Add button click handler in Qt project, Visual Studio - c++

I have Qt SDK and Visual Studio Qt Add-In working in VS2008. I created Qt UI project with main window class MainWindow. Double-click on mainwindow.ui opens Qt Designer. Then I added push button to the window, and called it pushButton. In Signals-Slots mode I managed to connect button's clicked signal with MainWindow ButtonClicked slot. Signal/Slot editor looks like this:
Sender pushButton
Signal clicked()
Receiver MainWindowClass
Slot ButtonClicked()
mainwindow.ui file was changed, reflecting this new information. However, mainwindow.cpp and mainwindow.h remain unchanged. I expect to see the place where I can add my own code. So, I added this code manually:
// mainwindow.h
...
protected slots:
void ButtonClicked();
// mainwindow.cpp
void MainWindow::ButtonClicked()
{
QMessageBox msgBox;
msgBox.setText("Clicked");
msgBox.exec();
}
It works, but I wonder whether this is correct way to do this. Is slot declaration and implementation supposed to be added manually, or I am missing something?

If you use signal/slot editor, you have to add these codes manually. Old Qt Add-In was automatically add these if you double click on a button from designer. Now Qt Designer is a seperate application. Double clicking is not possible.
Also you can use automatic connections. With automatic connections you dont need to connect signals with slots. Functions which has special naming convention, automatically called. Like on_okButton_clicked.

Related

Access Qt UI of another Class from the MainWindow Class

I want to understand if the following sequence is possible? If yes, how can we achieve the same?
MainWindow Qt GUI has a QPushButton
While we click on the QPushButton, it must open another Qt GUI Window (a different class, say 'DialogClass')
In the newly opened Qt GUI Window we have a QLineEdit and QPushButton
While we enter data in the QLineEdit and click on the QPushButton (of the DialogClass) the MainWindow class should receive the data entered in QLineEdit
Any help on this item will be appreciated. Thanks in advance!
Qt foresees its signals and slots approach for such purposes.
The QPushButton of your class offers a signal clicked which you connect to a custom (self-written) slot of your dialog. The dialog's slot then should read the contents of the QLineEdit and publish these on the dialogs own (custom) signal, which is connected to a (custom) slot of your main window, which then can process the value originally contained in the line edit.
Details will resemble pretty much the example of Qt's signals and slots documentation, so I won't be more explicit about.

How to connect Qt signals and slots using QT Designer and Visual Studio

I am using Qt Designer for the design of my application which contains a "Load File" QPushButton (which has been promoted to a custom loadfile.h) as well as an QOpenGLWidget (which has been promoted to a custom OGLWidget.h).
I wanted to have it so that when I click my "Load File" button it sends a signal to a slot in my OGLWidget class which brings up a dialogue and loads the file.
I started by going into signal/slot edit mode in Qt Designer and connected the button to the openglwidget with clicked() as the signal and a newly added (from within Qt Designer) populate_mesh_from_obj().
I then made a function:
void OGLWidget::populate_mesh_from_obj()
{
exit(0);
}
as a test and in the header put:
public slots:
void populate_mesh_from_obj();
Now in my head I thought:
The signal clicked() is already implemented by Qt magic
The slot has been implemented by me
Qt Designer has connected them somewhere
So to me this should have worked. Any ideas why it hasn't?
you have to connect them manually..
connect(ui->button, &QPushButton::clicked, yourGlPointer, &OGLWidget::populate_mesh_from_obj);
Fortunately, the accepted answer is incorrect (It's not that it doesn't work manually, but you don't have to do it that way).
In fact, QT will automatically connect the signal to all slots that follow a standard naming convention.
This naming convention for slots goes like this:
void on_<object name>_<signal name>(<signal parameters>);
In your case, this means if you created the QPushButton in QT Designer like this:
the object name is loadfile and the signal name is clicked.
Now, declare your function like this in the header:
public slots:
void on_loadfile_clicked();
and define it like this in the cpp:
void OGLWidget::on_loadfile_clicked()
{
exit(0);
}
and the connection will be automatically taken care of.
This auto-connection feature is actually implemented through the QT Meta-Object compiler. You can retrace what happens by opening the ui_<classname>.h file generated by QT Designer. It will contain a function void setupUi(<QClassName> *<YourClassName>) containing a line QMetaObject::connectSlotsByName(<YourClassName>);. This is what instructs QTs Meta-Object Compiler to implement the connections for you.

Qt unwanted double execution of a pushButton pressed signal

I created with Qt Creator 3.3.1 in design mode a pushButton and with the designer I connect the button with the signal pressed(). It work fine but sometimes and when I set in the pressed event a pushButton to hide or show or change the index of a stacketWidget the signal pressed() is repeated twice consecutively. I don't have connect manually in the code, but it's all done automatically by the designer. I'm using Qt 4.8.6 embedded. Thanks
void myclass::on_pushButton_1_pressed()
{
qDebug("Pressed event");
ui->pushButton_2->hide(); //if I comment this line the pressed signal is not repeated twice
}
Qt designer forms have a feature called autoconnect. It automatically connects signals of your form widgets, if there is a slot called on_{ObjectName}_{SignalName}.
So your slot is connected twice, once by your connection in the designer, and once by auto-connect.
Either remove your connection in designer, or rename your slot to resolve the additional call

HowTo correctly close QDialog when main windows is hidden?

I have some kind of dilemma.
I'm using:
MSVS 2008
Qt 4.7.3 (with Qt VS Add-in 1.1.9)
I wrote small Qt application, base on QMainWindow class, where also exists settings dialog (QDialog). Every works fine in GUI mode. After that I started to change my project to make it visible only in tray. Just comment in main.cpp show() method, like this:
MainWindow w;
//w.show();
return app.exec();
But from tray, I need to launch settings dialog, which is implemented in mainwindow.h/.cpp files. I added to tray menu action (QAction) which is starts that settings dialog. And here comes the unexpected problem: when I tried to close this settings dialog with [ X ] close button (in top right corner) my app closed!
Here is the action slot:
void MainWindow::onOpenSettingsDlgClicked()
{
SettingsDlg dlg( this );
dlg.exec();
}
I have tried to reimplement virtual reject() method for the settings dialog class, and set there only hide() function, but that solution not helped.
What I'm doing wrong?
Thanks you!
You should turn off the quitOnLastWindowClosed property which is turned on by default as defined in the doc (http://doc.qt.nokia.com/latest/qapplication.html#quitOnLastWindowClosed-prop)
This said, you'll have to handle the termination of your QApplication yourself, maybe with an [quit] entry in the tray menu.
Just found another option which seems better is to override closeEvent of the QDialog to only hide it.
void PrefDialog::closeEvent(QCloseEvent *event) {
this->hide();
event->ignore();
}
I found this seems better because it doesn't change the global application behaviour.

How do I create a custom slot in qt4 designer?

Whenever I use the signal/slot editor dialog box, I have to choose from the existing list of slots. So the question is how do I create a custom named slot?
right click on the main window and select "change signals and slots" and add a new slot.
It will appear in your signal slot editor.
This does seem to be possible in the version of Qt Designer 4.5.2, but it can't be done from the Signal/Slot Editor dock-widget in the main window.
This is what worked for me
Switch to Edit Signals/Slots mode (F4)
Drag and drop from the widget which is to emit the signal, to the widget which is to receive the signal.
A Configure Connection dialog appears, showing the signals for the emitting widget, and the slots for the receiving widget. Click Edit... below the slots column on the right.
A Signals/Slots of ReceivingWidget dialog appears. In here its is possible to click the plus icon beneath slots to add a new slot of any name.
You can then go back and connect to your new slot in the Configure Connection dialog, or indeed in the Signal/Slot Editor dockwidget back in the main window.
Caveat: I'm using PyQt, and I've only tried to use slots added in this way from Python, not from C++, so your mileage may vary...
Unfortunately this is not possible in Qt4.
In Qt3 you could create custom slots which where then implemented in the ui.h file. However, Qt4 does not use this file so custom slots are not supported.
There is some discussion of this issue over on QtForum
I am able to do it by:
In MainWindow.h, add the line:
public slots:
void example();
in the MainWindow class.
In MainWindow.cpp
void MainWindow::example() {
<code>
}
This doesn't seem to be possible in a simple way.
The designer only allows you to promote existing widgets to your own custom widgets. yet it doesn't allow you to connect the signals and slots of the class of promoted widgets.
The way this is possible is creating a plugin for the designer as is described here and in the pages that follow it.
The normal course of action is to promote a widget to your own class and then to connect it manually in your own code. this process is described here
It is not possible to do it, because it means you would add a slot to an existing Qt class like QPushButton which is not really the way to go.
You should create your own QWidget eventually by subclassing an existing one. Then integrating it into Qt Designer as a plugin as suggested. Having your own class allows you to add/modifiy the signals/slots available as you want.
Don't forget about the slot auto-connection features. There are a few drawbacks, like having to rename your function if you rename your widget, but we use those a lot at my company.
You can use the magic slot format of
void on_objectName_signal() {
// slot code here, where objectname is the Qt Designer object name
// and the signal is the emission
}
The connection to this method is established by the method connectSlotsByName and whenever the signal is emitted, this slot is invoked.
Maybe it'll help.
By default you have to choose from the existing list of slots. But you can add slot by right-clicking at you object in the list at right side of designer and choose "slot/signals" and add your custom slot/signal. After that, you can choose it in signal/slot editor.
click the widget by right button
promote the widget into a class you defined
click the widget by right button again
you will see that signal and slot is editable