Please explain variations on connect
-
I am working on the tutorials provided for QT3 chapter 7. The app creates a grid of 16 widgets with slider driving an LCD and daisy chains them such that widget 16 drivers the other fifteen. The key is these two connects:
connect( slider, SIGNAL(value_Change(int)), lcd, SLOT(display(int));
connect( slider, SIGNAL(value_Change(int)), SLOT(display(int));The second occurrence does not have the name of the object receiving the signal. It looks like it is sending the signal to the signal. The code does work. I don't understand the concept.
-
Hi,
The second version is equivalent to
connect( slider, SIGNAL(value_Change(int)), this, SLOT(display(int));
-
Ok, then that's called signal chaining, you can to that to forward the signal of an inner widget. But ultimately, it can be rewritten the same way as my previous example.
-
@SGaist
I continue read that incorrectly. The first line I see as this:- Go to object slider and get signal value_Change(int))
- Go to object lcd, and send that signal to display(int). Or more correctly, call the function with the argument provided.
Or more technically, go to object slider and capture the integer argument. Go to object lcd and call function display() with that integer as the argument.
For the second line:
Go to object slider and capture the integer value from function value_Change( int). Go to NULL (because there is no destination provided) and, well, I don't know. Get the integer value again but what should or can be done with it. -
As I wrote before it's not null, it's just
this
that is omitted.connect( slider, SIGNAL(value_Change(int)), SIGNAL(value_Change(int)) );
is the same as
connect( slider, SIGNAL(value_Change(int)), this, SIGNAL(value_Change(int)) );
-
There is something I continue to get wrong. Here is what I presume to be a level deeper.
For the first connect I see this:
The SIGNAL
The MOC (If I have that right, the QT Creator preprocessor that captures all the QT specific keywords and emits code for the cpp processor), detects that class/object slider has declared a SIGNAL named value_Change(int). So the MOC replaces (or maybe supplements) the function within slider such that when anything within class/object slider calls function value_Change(int), it is really calling some code/class/object/method that the MOC creates.
The SLOT
That done, then the MOC detects that class/object lcd has a function display(int) that is labeled with the MOC keyword SLOT. Now the MOC emits code such that when something in “slider” calls function value_Change(int), the code emitted by the MOC really calls (or winds up calling) function display(int) within lcd. Thusly the integer argument gets routed from slider to lcd.
For the second connect I see this.
The SIGNAL is unchanged.
The SLOT
You mention that the “this” pointer is implied. So my interpretation becomes:
The MOC, looking for a place to put an integer argument, goes to class/object slider and sees that there is a SIGNAL named value_Changed(int)
I see two avenues, each presents problems.
A. value_Change(int) is an output and MOC is looking from some place to put an output. Output to Output does not work.
B. As noted in the SLOT above, a call to value_Change() is really directed to something within the MOC where it makes a call to something else passing the integer argument. The only thing that can be is value_Change(int), and the MOC calls the same function as noted above. BUT, now we are calling the function that just gave us the integer argument. That looks like a circular call to me and that will not work.So, I do see that I am not understanding this, but I don’t know where to find the missing piece.
Geez, I hope I did not make any more typos in those paragraphs. -
It seems you are again mixing something. You first example connects a signal to a slot. The second, connects a signal to a signal, which is allowed to route an inner widget signal upper.
class MyNiceWidget : public QWidget { Q_OBJECT public: MyNiceWidget(QWidget *parent=nullptre) : QWidget(parent) { QSlider *slider = new QSlider; QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(slider); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(myValueChanged(int)); // Forwarding the signal } signals: void myValueChanged(int value); };
Qt Creator has nothing to do here.
moc
is a tool that's been there from the beginning.See here on the why of moc
Here about the use of mocYou can inspect the generated code if you want to see what magic happens.
-
I struggle with how much to burden you with reading and how much to put in here so you can detect flaws in my understanding, complicated by the fact that I cannot copy/paste from my work computer to here.
Now that you have held my hand and led me down the path a bit, it occurred to me that that bit of code might not be needed, the one that is:Connect( slider, SIGNAL( valueChanged( int ), SIGNAL( valueChange(int)));
So I commented it out, and the app works exactly as it does with that code there. That lends credence to my puzzlement at how it might be working in this particular app. In short, it isn’t. (It is not doing anything in this app.)
I took your link about why the MOC and the intro was especially good. I think I have a moderately good understanding at the 100,000 foot level. The link on the use of the MOC is good also, but rather over my head for the moment. I will stick with the simple build process for now.When I first met QT I thought this was cool, but no big deal. Then I began to learn about it and was impressed. Now I recognize QT is far larger and more involved that I could have imagined on first sight.
That said, I do end with a question. Start with a very simple standard Makefile generated by qmake. Then show me the edit needed to save the preprocessor output. I presume the MOC generates code that is then digested by the preprocessor, and that output shows what the MOC created. That will be over my head for anything complicated, but maybe I can understand it for simple stuff. I will also be able to use that for other projects as we have many that use macros by the boatload.
Thank you for your time and patience. -
Then show me the edit needed to save the preprocessor output. I presume the MOC generates code that is then digested by the preprocessor, and that output shows what the MOC created
I don't use
qmake
so I can't give you the exactitudes. But if you're usinggcc
I know the-E
command-line argument will just produce the pre-processor output of your.cpp
file (rather than actually compiling it). If you use MSVC I would hope it has something similar. So make yourCPPFLAGS
/CFLAGS
/CXXFLAGS
or whatever include-E
and you can probably capture what you say you want to see. -
@JonB is right for saving the preprocessed code from the C++ compiler.
But I guess what you want to see is the code
moc
generates and that is compiled by the C++ compiler.Therefore you don't need to edit anything, just look in your build directory, you should have quite some
moc_xxx.cpp
files there (at least that's how it looks with recent Qt version - I have no Qt3 to compare.I you can actually read and understand this cpp file is a different story ;)
-
In the documentation I already linked to, there's how to write Makefile rules to use moc with your project.