Do the Qt signals/slots follow the scope of native C++?
Let's say I have the following classes: House, Kitchen, Cellar, Stove and Shelf.
class House {Kitchen kitchen, Cellar cellar;};
class Kitchen {Stove stove;};
class Cellar {Shelf shelf;};
Now I want to send a signal from the shelf in the cellar to the stove in the kitchen. Is the only way to do this by connecting a signal from the shelf to the cellar and a slot from kitchen to the stove and then in house connecting cellar and kitchen? Or is there a way to do this directly?
I have a class that needs to communicate with a user interface and I wonder if I need to "proxy" all the various signals/slots through intermediate classes. Or is this an indicator of bad design?
You can do the connection in any method of House, as there you can access both objects. The "connector" must be able to access both sender and receiver, at compile time, that's all there is to it.
You should be able to just link a signal from the Shelf instance to the Stove instance
in House,
connect(cellar->shelf,SIGNAL(signalHere()),kitchen->stove,SLOT(slotHere()));
just make sure that shelf and stove are public variables in Kitchen and Cellar and you'll be set
You cant use signals/slots on classes which are no QObjects, so no, your example wont work whatsoever.
You can circumvent the encapsulation if you initilaize the child objects with their parent object, so you can do dirty tricks like: connect(this->shelf, SIGNAL(signalHere()), kitchen->children()[0], SLOT(aStoveSlot())). however this will only work if the first child of Kitchen is really a Stove... so since this is a obvious dependency, you should make this visible by making stove public, or by adding a stove accessor method.
Related
I have application which has MainWindow that is divided in three main parts:
Thing is, all three parts need to communicate between themselves. For example, there is a QListView in left section where you select items, and depending on the selected item options change in the right section.
I have come up with three solutions:
draw everything within the MainWindow which would make MainWindow one big superclass:
This solution solves all problems with communication between widgets because all of them are part of MainWindow::ui but then I get one big (potentially messy) class.
put each section in it's own class and make MainWindow a singleton:
This solution is... well a singleton. And I don't really like singletons. I will have access to MainWindow from everywhere (essentially I am creating a global variable) and I would still have to expose MainWindow::ui (and ::uis of other sections) via getter which would mean that everything will have access to ::uis.
put each section in it's own class and connect everything via signals and slots:
This would probably be the best solution but with this solution I need to create getter for each widget from EachSection::ui (to be able to connect it in MainWindow with it's counterparts), I would need a lot of calls to connect() and I also have a problem if two slots react to same signal but they need to react in specific order.
So what would be the best approach?
The best approach would be to define messaging (protocol) between views, so that views is not tightly coupled (all views isolated and dont know about each other) one instance class (main window) know all three and connects them. Imagine a button line edit and label, when you press button label gets value of line edit, button implementation does not depend on lineedit implementation, lineedit does not depend on label and so on, all three classes can be extended or changed and it doesnot affect two other, so you can focus on one of them at the time.
I recently switched from unity and I wanted to know if there was a “getComponent” equivalent in UE4? I have an enemy script and I created a blueprint from that script and have added a widget with a progress bar to show the enemies health during combat. I have seen a lot of examples of how to do this in blueprint but if possible, I would like to just do it in code and let the percentage be calculated when it is needed to be, like after damage or something, rather than binding via blueprints.
I have tried using the getcomponentbyclass method but that throws an error because the component I want is not a child of the actor class.
Any help appreciated
You need to call GetComponentByClass() on an Actor.
If your Enemy is a Component, you can call getOwner() to retrieve the actor owning this component.
You can then call GetComponentByClass() on this actor instance.
I have a Qt application with a main class GUIApplication which inherits from QMainWindow as shown below. The GUI has a start button, stop button and a QGraphicsScene.
My application will read data from the serial port and other stuff and draw on the QGraphicsScene according to what is received.
My main GUI class knows about my serial port class as it must initialse it on press of the start button etc. That is fine. My serial port class however must also must be able to communicate with my GUI class as it must update the QGraphicsScene on reception of data and other stuff.
My question is , is it a bad design for my serial port class to know about the GUI class also. Isn't this a form of circular dependency between the two classes? I plan to have a member of my serial port class a pointer to the GUI class. Is this the only way to do it , or should I register a callback in the serial port class instead, to decouple the classes? Any help is appreciated thanks.
// GUI class
#include "MySerial.h "
class GUIApplication : public QMainWindow
{
Q_OBJECT
public:
//.........
o_o
// Serial port class
#include "GUIApp.h "
class MySerial
{
public:
//..............
//write something on GUI`
It is a bad design. Your serial port class has nothing to do with GUI by nature and as such should be separated from it - apart from circular dependencies, you make it much less flexible that way and limit its usability. One day you might want to use it in a console application and if you wrote the class in such a way that it must be aware of the GUI class, you would have to modify it just to make it work with console and either have two versions that would differ only regarding UI, which doesn't make much sense, or add Qt as dependency even though you would not need it in console app if you wouldn't want to break the compatibility, which doesn't make much sense either.
Much better solution is sending some signal from your serial port class or some meaningful return code after the data is received, and then make the GUI class catch this value and update QGraphicsScene itself. That way you also get rid off the circular dependency.
Using MVC, I have several view classes, all of which need to write to an event log. The event log contains a slot called addEntry which writes the data to the log. I'm struggling with how to implement the signals. I don't want to have to pass the event log object into every class. So do I...
1) create local signals in each class, and let my main window connect them all?
2) can I make the slot static so all views can access it without needing the event log object?
3) create one signal and pass it as a function pointer into each class so they can all use the same signal?
4) something else?
Thanks.
At most this, see below.
No. Slots have to be associated with
class instances.
I doubt the moc would understand this, and it seems
unnecessarily complicated.
In principle you could let the events
propagate up the parent/child hierarchy and let the main window edit
the log but this is also too complicated.
Assuming your view classes inherit from QAbstractItemView then they already have signals you can use, particularly if you use the Q*Widget convenience classes. In your situation, if this doesn't work for me, I do 1). You may also consider signaling from the model classes--that is where the updating actually happens after all.
Couldn't you setup static member functions in your event logging classes to retrieve a ptr to
an event logging instance? Return the one global instance if that's all you have,
static EventLogger* EventLogger::getLoggerInstance();
or a more nuanced if you have multiple event loggers.
static EventLogger* EventLogger::getLoggerInstance(args, ...);
If a view needs to hook in the the event logging, it retrieves an event logging instance and connects to it.
At the beginning I want to tell that I just started learning QT so my knowledge about this is really not deep. I wrote simple tasks management it's a console application of course. I used logic which resembles MVC pattern (controllers, views, actions, models).
For example let's take user login. I create instance of LoginController class, then LoginController creates instance of LoginView who is waiting for user to enter data - login, password. Login and password is saved as LoginView members. Then in LoginController I read this data and passes them as parameters to UserVerificationAction constructor. Constructor of this class saved this data as members of their class. Next in LoginController I calls method of class UserVerification - action() which validates login and password. Then depending on the result of validation I create instance of MenuController or instance of LoginFailiedView. This mechanism is user throughout the program (CreateUserController, AddTaskController) etc. I used virtual methods so MenuController consists of about 20 lines of code and is very easy to read.
I want to use Qt to implement a GUI to be more precise I want to use signals and slots mechanism but I have a dilemma. Maybe it would by better to create a slot in the LoginView class and then creates action instance instead passes entered data to LoginView members and then in LoginController creates instance od action class. maybe there is a better way to do this. I want you to give me some tips on how I should do it properly
p.s.
Sorry for my English
In Qt, the concept of a "controller" is slightly blurred. It tends to be part of both the model and view. This does not mean that you can't write a controller to link a model and view logic.
Normally what you will see is a view that emits signals for its actions. And then you wire these either directly into compatible slots on a model or a subclass where you have written your own slots.
If for instance you have a main window. This window might create a model and a view as children. And it may then define slots on the window subclass that wire between the model and view. This means your window is a view and a controller.
Qt provides Model/View architecture.
It introduces 3 classes: Model, View and Delegate to store, present and edit data.
I believe that is what you are looking for.