I'm currently working on a Qt project and am somewhat confused with the signals and slots mechanism. I feel however that I have a somewhat good understanding between the differences between a QObject and user interface form.
A user interface form (described by a .ui file) is fed into the user interface compiler(uic) and produces an associated header file. This header file doesn't just contain interface information, but instead contains the implementation details on a QObject should be formatted. A QObject on the other hand is the base class in which a lot of the Qt framework is built upon. The signals and slot systems is based completely on the QObject.
When extending the QObject class (or from a derived class), you are actually defining an object in which can produce signals and slots. To format this object to look like the user interface you just designed in Qt Designer, you create an instance of the ui class (via the ui header generated by the uic). You call the setup method on this class and feed it the new QObject you're creating.
This all seems to make sense.
However, what doesn't make sense is when you start actually defining signals. From with Qt Designer, I have the option to right click and select a 'signal'. When I select a signal (whether that be a mouse click on a button or a change in a progress bar), it ends up adding that to my QObjects signals section. My question is: why and how? How exactly are my actions in Qt Designer (a program that generates an XML for the uic) getting coupled to my QObject in Qt Creator? More specifically, how does it know which QObject to add this slot to?
This question may be somewhat unclear, so I'll throw an example here.
Say for example I want to create a new interactive display of some kind. Let's call it 'MyScreen'. In order to create this interface, I would likely have 3 files: 'myscreen.h', 'myscreen.cpp', and 'myscreen.ui'. 'myscreen.h' is responsible for declaring the QObjects properties and methods as well as signals and slots. 'myscreen.cpp' is responsible for defining the methods, signals, and slots. 'myscreen.ui' is repsonible for creating the user interface layout that will be used to format an instance of MyScreen.
But due to what I had stated previously saying that the ui is just used for generating a header, why exactly is it coupled to 'myscreen.cpp'? That is, I can right click on the .ui layout, create a new signal type, and that signal type will be added to the myscreen.h and myscreen.cpp. How does this happen? How is it coupled? Does Qt operate such that there should always be 3 files (xxx.h, xxx.cpp, xxx.ui) that should exist?
So hopefully that gives you some context in what I'm confused about. There doesn't seem to be a well written document (that I've found at least), that thoroughly describes the underlying relationship between all these items.
TLDR - How does the signal/slot from the .h and .cpp actually link to the elements defined in the .ui file?
My question is: why and how? How exactly are my actions in Qt Designer (a program that generates an XML for the uic) getting coupled to my QObject in Qt Creator? More specifically, how does it know which QObject to add this slot to?
The short answer is: magic.
The real answer is, it actually has nothing to do with your actions in Designer, at least not directly. It's not actually even a UI-specific thing, it's just that designer makes good use of it. What happens is this:
First of all, any time you compile a file that makes use of the Q_OBJECT macro, this triggers Qt's moc tool to run during compilation ("triggers" isn't really the most accurate description: More precisely, when qmake is run to generate makefiles, it adds build rules to run moc when Q_OBJECT is detected in a header, but that's beside the point). Details are a bit outside the scope of this answer but long story short is it ultimately generates those moc_*.cpp files you'll see after compilation, which contain a whole bunch of compiled meta info. The important part of this is where it generates run-time accessible information about the various signals and slots you have declared. You'll see how that's important here below.
The other important thing is all QObjects have a name. This name is accessible at runtime. The name you give your widgets in designer is set as the widget's object name. The reason this is important will also become clear below.
And the final important thing is QObjects have a hierarchical structure; when you create a QObject you can set its parent. All of the widgets on your form ultimately have the form itself (e.g. your QMainWindow-derived class) as their parent.
Ok, so...
You'll notice in source code Qt generates for your windows you always have that ui->setupUi(this) call in the constructor. The implementation of that function is generated by Qt's uic tool during compilation, in e.g. ui_mainwindow.h. That function is where all the properties you set up in designer, stored in the .ui file, are actually set, including the widgets' object names. Now, the last line of the generated setupUI() implementation is the key:
void setupUi(QMainWindow *MainWindow) {
...
// Object properties, including names, are set here. This is
// generated from the .ui file. For example:
pushButton = new QPushButton(centralWidget);
pushButton->setObjectName(QString::fromUtf8("pushButton"));
pushButton->setGeometry(QRect(110, 70, 75, 23));
...
// This is the important part for the signal/slot binding:
QMetaObject::connectSlotsByName(MainWindow);
}
That function, connectSlotsByName, is where the magic happens for all those widget signals.
Basically that function does the following:
Iterate through all your declared slot names, which it can do because this was all packed into runtime-accessible strings by moc in the meta object info.
When it finds a slot whose name matches the pattern on_<objectname>_<signalname>, it recursively searches the object hierarchy for an object whose name is <objectname>, e.g. one of your named widgets, or whatever other named objects you may have created. It then connects that objects signal, <signalname> to the slot it found (it basically automates calls to QObject::connect(...)).
And that's it.
So what this means is, nothing special actually happens in designer when you go to a slot there. All that happens is designer inserts a slot named on_widgetName_signalName, with the appropriate parameters, into your header and generates an empty function body for it. (thuga has added a great explanation of this). This is enough for QMetaObject::connectSlotsByName to find it at run time and set up the connection.
The implications here are very convenient:
You can remove a widget's signal handler without doing anything special in designer. You just remove the slot and its definition from your source file, it's all completely self contained.
You can add widget signal handlers by hand without having to go through the designer interface, which can save you some tedium sometimes. All you have to do is create a slot in your window named e.g. on_lineEdit1_returnPressed() and voila, it works. You just have to be careful, as hyde reminds us in a comment: If you make a mistake here you won't get a compile-time error, you will only get a run-time warning printed to stderr and the connection won't be created; so it's important to pay attention to console output if you make any changes here.
The other implication here is that this functionality isn't actually limited to UI components. moc runs for all your QObjects, and connectSlotsByName is always available. So any object hierarchy you create, if you name the objects, then declare slots with appropriate names, you can call connectSlotsByName to automatically set up connections; it just so happens that uic sticks that call at the end of setupUi, because that's a convenient place to put it. But the magic isn't UI-specific, and doesn't rely on uic, only on the meta info. It's a generally available mechanism. It's pretty neat.
As an aside: I stuck a quick example of QMetaObject::connectSlotsByName on GitHub.
What happens when you add a slot from the Go to slot... context menu item, is it goes through your project, and it looks for any files that include ui_myclass.h. When it finds this file, it then makes sure that Ui::MyClass object is declared either in that file, or in directly included files. These would be your myclass.cpp and myclass.h files. If it finds these files, it will then add the slot declaration and the definition in those files.
You can test this by removing the Ui::MyClass object (usually named ui) declaration from your myclass.h file, and then adding a slot by using the Go to slot... function in the designer. You should get some error message stating it couldn't find Ui::MyClass object declaration.
You can also try removing the ui_myclass.h inclusion from your myclass.cpp file. If you try adding a slot from the designer now, you will get an error message stating that it couldn't find ui_myclass.h included anywhere, or something like that.
If you define everything just inside your myclass.h file and remove myclass.cpp, it should give you an error message stating that it is unable to add the slot definition.
You can inspect how it works in more detail by looking at this part of the source code.
But in the end what really matters is, that you declare and define your class methods in separate .h and .cpp files, and that ui_xxx.h is included and that Ui::xxx object has been declared in those files. Of course this is what Qt Creator does for you automatically when you add a new form class, so you don't have to worry about it.
I have a current C++ program built using GNU make. It is reasonably large - about a dozen .cpp files and a similar number of headers.
It all runs off the command line and currently just outputs to cout and cerr.
I want to add Qt interface elements to it - what is the best way to do this?
(I have built some Qt stuff in the past (not for a few years) though I am rusty - the C++ code I have now works and I don't want to change that, just fix the way it outputs information to the end user.)
You didn't specify whether you're interested in Qt Widgets or Qt Quick, so I'll assume widgets.
Fire up Qt Creator, and create a new Qt Widgets project. Open designer mode by double clicking on the .ui file that was created and start creating the interface that you want. If you just want somewhere to start integrating your logic, dump your existing code into mainwindow.cpp (or whatever you called it) and refactor it as you learn more about Qt.
For example, one of your buttons might cause a slot to be invoked, and you could then do all of your stuff in that slot.
There are also a lot of non-gui-related utility classes like QCommandLineParser that may help you out.
I want to dynamically instantiate a QWidget and bind its "Pressed" event, either with a Qt signal or by overriding a function.
However I'm only allowed to create one new .cpp file.
I don't know how to override a C++ function dynamically, or how to change a virtual function into a Qt signal.
Is what is represented in the picture above achievable ?
The Widgets Tutorial of the Qt docs is a nice starting point.
Under Qt Widgets Examples you can find the Calculator Example, which should contain all of what you want to do.
Take the code, strip it down to what you need, use and try to understand it.
Or maybe have a look at the Getting Started section.
When you place the mouse pointer over any Qt function/class it shows a pop-up with short description of what it does, taken from the docs in the comment above the function/class.
For my functions/classes I have documentation in the doxygen format:
/**
Returns foo
*/
QString getFoo() {
return "foo";
}
When this function is used, I want to view the same type of pop-up with my docs when the mouse pointer is over the function name.
Is it possible to do that with Qt Creator?
Unfortunately it's not possible for Qt Creator (as of the recently release 2.4) to pick up the tags on-the-fly. However, what might work is to let doxygen run, and tell it to create qch files. If you register the created qch file, you should get mouse-over and even a proper help file. See http://www.ogre3d.org/tikiwiki/Integrating+API+documentation+into+Qt+Creator+Help for how Ogre3D does it. YMMV if that's worth it for a fast-changing project. It's certainly a good idea for a (semi-)stable library.
Relevant bug report: https://bugreports.qt.io/browse/QTCREATORBUG-4557
Qt Creator requires the generated docs to have some special markers in order to retrieve the tooltip text. I couldn't find a way to insert these markers with Doxygen so I've created a simple script to do it:
https://github.com/mmmarcos/doxygen2qtcreator
It's not bulletproof but it allows us to integrate our classes and methods briefs into Qt Creator tooltips.
I'm fairly new to Qt, and am trying to wrap my head around signals and slots. Though I've figured out how to create custom slots, I've yet to figure out how do update the GUI from my C++ code. I realized that the entire UI, which I created in the designer, is only written in what appears to be XML based UI code. Do I have to handwrite my own Qt C++ UI in order to update the interface, or can I somehow use C++ to update the XML based UI? I'm just looking to add a widget to the main form on a button click. Any help is appreciated. Thanks!
To add a widget to a form you can simply do
ui->layout()->addWidget(new Widget);
XML is used by QtDesigner as a mean to create, update, and persist your GUI, enabling a visual approach to development, but in the end you can build your application entirely without it.
you dont havfe to update the xml of UI . you can inherit the ui into your own class using setupUi
http://crpppc19.epfl.ch/doc/qt4-doc-html/html/qwidget.html#setupUi
now in your C++ class you can update the widgets like changing label text, lineEdit text, setting up spinbox value using Signals & slot.
That xml is used by Qt designer and outside of designer it's only used by uic as a source to generate C++ code, so everything that you do in the designer end-up as C++ code, so it can be updated (or done completely) in C++ code (you can look into the code and see that you most likely have a member called ui that is most likely a pointer, but it can also be an instance of a C++ class that is generated for you by uic, and trough that ui member you can access the widgets and layouts that you created in the designer).
A generic resource that i recommend you to read can be found here and then (if you still can't figure it out) ask a specific question about what exactly are you trying to achieve.
LE: that link contains 3 methods to use the generated code into C++ code, don't try all of them into your working project, you may choose one method or use the default one (ui member pointer)