Signals and Slots and vtable, oh my!!
-
Using Qt5 with my C++ (open source) project, under both
VS Code/makefile
andQt Creator
dev environments, execution of theconnect()
method yields:QObject::connect: No such slot QComboBox::MyIndexChanged() in BashQtHelper.cpp:118
Or, when I include Q_OBJECT, the linker error:
undefined reference to `vtable for MyComboBox'
The class is:
class MyComboBox: public QComboBox { public: MyComboBox(QWidget *parent = nullptr): QComboBox(parent) { connect(this, SIGNAL(activated(int)), this, SLOT(MyIndexChanged())); } ~MyComboBox(){} public slots: void MyIndexChanged() { if (currentIndex()) {std::cout << currentText().toStdString() << "\n"; exit(0);}} };
When I try the alternative call, namely with pointers to functions:
connect(this, &activated, this, &MyComboBox::MyIndexChanged);
The compiler complains:
error: no matching function for call
The minimalist program by ChatGPT is:
#include <QtWidgets/QApplication> #include <QtWidgets/QComboBox> #include <QtWidgets/QVBoxLayout> #include <QtWidgets/QMessageBox> class ComboBoxApp : public QWidget { public: ComboBoxApp(QWidget *parent = nullptr) : QWidget(parent) { // Create a combo box comboBox = new QComboBox(this); // Add items to the combo box comboBox->addItem("Option 1"); comboBox->addItem("Option 2"); comboBox->addItem("Option 3"); // Connect the signal for item selection to the custom slot connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxSelectionChanged(int))); // Create a layout and set it for the main window QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(comboBox); setLayout(layout); } public slots: // Custom slot to handle combo box selection changes void onComboBoxSelectionChanged(int index) { QString selectedOption = comboBox->itemText(index); QMessageBox::information(this, "Selection Changed", "Selected: " + selectedOption); } private: QComboBox *comboBox; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); ComboBoxApp window; window.setWindowTitle("ComboBox Application"); window.resize(300, 150); window.show(); return app.exec(); }
How do I make this code work, or do I need to scrap the whole thing and start with a better SIGNAL/SLOT template?
-
@radar said in Signals and Slots and vtable, oh my!!:
The minimalist program by ChatGPT is:
Rule No. 1: Dont trust any AI/Bot, when you are not able to confirm the result's correctness ;-)
class MyComboBox: public QComboBox
{
public:You are missing the
Q_OBJECT
macro. Without this, no signals ands slots ;-)
Add the macro, includeQComboBox
and then clean your build, and build again.connect(this, &activated, this, &MyComboBox::MyIndexChanged);
You need the complete, fully qualified function pointer there
&activated
is not enough, unless it's a global function which doesn't belong to any class.Apart from all this, connecting
this
tothis
doesn't make too much sense. Then you just can call the function when you need it -
@Pl45m4 said in Signals and Slots and vtable, oh my!!:
Rule No. 1: Dont trust any AI/Bot, when you are not able to confirm the result's correctness ;-)
Okay then, where's the official template/example provided by Qt?
It's easy to say "don't do this, don't use that", the useful answers are, "here's an example of how to do it right".
-
@radar said in Signals and Slots and vtable, oh my!!:
Okay then, where's the official template/example provided by Qt?
Have you tried the official documentation instead of ChatGPT? :)
-
@radar said in Signals and Slots and vtable, oh my!!:
VS Code/makefile
I checked your GitHub... and there is no
moc
in your makefile... Maybe I've missed something but AFAICS you are not running the meta-object-compiler, which would explain why none of yourQObject
/ metaobject stuff, including signals, is working.Edit:
Also, why do you have everything (twoQObject
classes and even the main) in one cpp file?!
MOC can only run*.h
files and you need to include your moc'ed output in your*.cpp
file.
[ Edit: can also run cpp files, but it's unusual as stated by @Christian-Ehrlicher ]Start to learn how Qt and everything that comes with it works, otherwise you will run into more trouble sooner or later
-
@Pl45m4 said in Signals and Slots and vtable, oh my!!:
MOC can only run *.h files and you need to include your moc'ed output in your *.cppfile.
Thats not true
But why create a custom Makefile instead using CMake or qmake to let do all this work?
-
@Christian-Ehrlicher said in Signals and Slots and vtable, oh my!!:
Thats not true
What part? The
h
-only or that you have to include your moc in your cpp?
I know that you dont have to, but you have to run moc on the files where you declare yourQ_OBJECT
, right?! So usually you would declare your class in some header file and moc outputs something likemoc_myclass.cpp
Found this, because I wasnt 100% sure:
Now I'm also confused :D
-
@Pl45m4 You can also moc a .cpp file even though it's unusual.
e.g. when you've a small private, object-derived class in your cpp file (as some Qt source code is doing it) instead moving the class definition into an own foo_p.h.
I mostly use it for small testcases only containing a main.cpp - then you need to include <main.moc> and cmake is doing the rest (instead fiddling around with a Makefile).