I am new to QT. As far as I can see, there are two ways to connect signals and slots with each other. One way would be using the connect method. When e.g. wanting to put a method ButtonReleased() to the slot that is triggered after the released() signal of a pushButton with name pushButton, one could write:
connect(ui->pushButton, SIGNAL(released()), this, SLOT(ButtonPressed()));
However, as far as I see, one could also define a method with name on_pushButton_released() to achieve the same connection. Is there any difference between both methods and if so, which one is preferred?
Thanks in advance!
There are indeed two main ways to connect signals to slots.
The first one, using the connect method allows to connect any signal to any slot (or signal) as long as the function signatures match. This is the main way to connect signals in Qt.
The second way are member methods that are called on_ObjectName_SignalName(). These are automatically connected by Qt, if a UI element called ObjectName exists and has a signal called SignalName. This is specifically meant for the use case of having some Widget with a separate .ui file, which contains these elements that you want to connect to. As such, this mechanism does not work if you create UI elements "by hand" in your C++ code.
As you can see, the second mechanism has very specific requirements that need to be satisfied to work, although these are not uncommon. So if you have satisfied these conditions I see no Problem in doing it this way, but others may disagree and this is largely personal preference.
Also note: The syntax in your question is the old syntax from Qt4. If you are using Qt5 and newer, it is highly advised to use the new syntax.
You can read more about signals and slots on the Qt Documentation.
Related
I have a small Qt plotting application and I am enabling/disabling widgets (combo/spin boxes) based on a "master" combo box. For example, say the master is combo1, which changes the entries in combo2, based on currentIndex(), enables/disables spin1, and sets a value for spin1 if a certain entry in combo1 is selected. There are more widgets than only these, though.
After the small discussion in the chat (and onwards), I used Qt::QueuedConnection with every connect(), but this didn't stop the re-enabled widgets to emit signals when re-enabled. This caused my many connect() to all be executed for all the re-enabled widgets, resulting in multiple plottings, which I want to avoid. As they are right now, (almost) all the widgets use plot() inside a connect(), so it's multiple signals to one slot.
My question: is there a way to prevent emitting the signals when the widgets are re-enabled? I could make plot() use some bool to check whether the plot has been executed and prevent further actions of the same type, but that would still cause the widgets to emit the signal and run plot(), even if the check will prevent the actual plotting, but that doesn't seem like the way to go. I would also prefer to avoid running installEventFilter(), or similar, as that would, most probably, slow down even more than the previous fix.
Another option, already mentioned in a comment, is to use QObject::blockSignals:
combo1->blockSignals(true);
// do what ever you need
combo1->blockSignals(false);
I find it easier to use and read. Also, there are many situations where you simply don't know / handle the connections.
Update
Since Qt 5.3 you also have QSignalBlocker, an exception-safe wrapper for blockSignals (internally it uses RAII to block signals in the constructor and restore them to their previous state on destruction):
{
QSignalBlocker blocker{combo1}
// do what ever you need
}
Use disconnect before every connect to prevent multiple connections. Disconnecting a not connected slot is always allowed.
disconnect(spinbox1,...);
connect(spinbox1,...);
Blocking signals is also possible but I think you want the first solution.
From QtDocumentation:
bool QObject::blockSignals(bool block)
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke anything connected to it). If block is false, no such blocking will occur.
I'm trying to create a signal and slot in Qt4 and I am fairly new to Qt. From what I understand in Qt5 it is just created automatically and this is not the case in Qt4 it seems. I'm trying to create a an action when the user clicks on an option in the menu bar at the to of the UI.= I see that there is a Signal/Slot editor at the bottom of the screen with options "Sender", "Signal", "Receiver", and "Slot". I'm not entirely sure how to use this function. Any help is appreciated.
Basically you need to connect your signal and slot
connect(ui->button1, SIGNAL(clicked()), this, SLOT(yourSlot()));
and in this link there is good example about signals and slot: signals and slots in qt.
You seem to have misunderstood.
The difference in Qt 5 is that it offers new syntax to make the connections.
The connection is "automatic" when you don't specify the connection type, i.e. direct, queued, etc, the default is automatic, which makes Qt check the object's thread ownership and select the appropriate connection type.
Connections must either be explicitly made in code, or be made using the UI editor, and while the latter may save you some typing in some cases, in general most of the connections you end up making are explicit in code, so you better learn how to do it, because the UI editor can help you only in a few corner cases. I haven't really used the UI editor for connections, and have tried it once or twice years ago, but the limitation I think is that you can only make connections between UI elements and signals and slots of the widget.
Consider that signal and slot connections are not merely a UI thing, it is a core principle in Qt and UI is just one of its many uses.
I have a scenario in which different classes dynamically attach to a thread by connecting its signal to their slots. My question is whether it is possible to unsubscribe again? Is there a way to remove signal-slot connection?
Look at the QT documentation, down near the bottom. It says that
Disconnect can be used to remove the connection.
disconnect(sender0, SIGNAL(overflow()),receiver1, SLOT(handleMathError()))
Another good resource that also mentions disconnect is here.
I am trying to reimplement or modify a tab code in a gui application. They are currently using Qt signal and slots system to handle addition and removal of tabs from the tab bar (For example if a tab was being drag from one tab widget to another, the old tab widget will signal the new tab widget that a new tab is coming). I was thinking rather than using that, I could simplify things using a thread safe singleton class. Then when ever a tab is moved, the widget just call on the singleton rather than emitting a signal.
Thanks
Signals and Slots.
Without even starting why the singleton would be bad, the way the data is updated inside Qt would be messed up by the singleton approach.
Don't do that. You are working within an environment and should use the mechanism the framework provides. What about if the UI in the future will have multiple windows and maybe multiple instances?
If possible you should always try to use the way from the framework you are using. This will also help in the future for the maintenance (upgrades, new hires, etc.)
You want to use a singleton, which will accept messages and dispatch them back ? (note: if you use a garden variety object instead of a singleton, you're essentially implementing an Observer pattern).
Then you are reinventing signals and slots, which use a global state internally. Instead of putting work in reinventing some difficult piece of code, why don't you use the already existing signals and slots ?
I know that i can use QSignalMapper to call a slot with different parameters based on connection. What i want to achieve is a little different.
We are using plugins in our application and different plugins are responsible for different types of objects. We are connecting multiple slots, each implemented in a different plugin, to one signal emitted by the main application. One of the parameters of the signal is a QString indicating the type of object associated with the signal. Currently, we are checking this parameter in the slots and proceed if the type is handled by the plugin. This has a downside, every plugin does this checking and i want to avoid this if possible.
I want to connect all slots to the same signal, and when the signal is emitted, only the appropriate slot is called depending on the value of the QString argument, kind of like a QSignalMapper but in a different way.
Is there any built-in mechanism to do this? If not, any ideas on how i can achieve this?
Thank you in advance.
I don't think there's a component for that, but you could create your own signal mapper like this:
create a MySignalMapper component
code an addSourceSignal method to set the signal of the main app
code an addDestinationSlot method that takes a QString/slot pair and maps the string to the slot.
in your component connect the source signal to a custom slot that dispatches based on the qstring value. You can invoke a slot with QMetaObject::invokeMethod.
Qxt has a class exactly for this functionality. You can use QxtSlotMapper class which is in QxtCore module.
http://libqxt.bitbucket.org/doc/tip/qxtslotmapper.html
You could restrict the allowed values of the "type" string to be valid C++ function names only. Force the plugins to name their slots according to the types they handle, then for each plugin simply attempt to connect the appropriately named slots.
In other words, you could do what QMetaObject::connectSlotsByName, except implement your own naming convention.