Qt: Best mechanism to capture and pass signals - qt

I have a class extending QWidget class and this class uses a Ui class generated by QtDesigner. Something like following:
class MyWidget : public QWidget
{
signals:
void pushButtonClicked();
// ....
private:
Ui::MyUi ui;
}
MyWidget::MyWidget()
{
ui = new Ui::MyUi();
ui->setupUi(this);
}
Now lets suppose there is a QPushButton * pushButton field inside Ui::MyUi. The UI for this widget has no complex business logic.
Now it is required that whenever pushButton is clicked this widget should emit a signal (lets call it pushButtonClicked(). Now the only way I can imagine this to be achieved is to:
connect clicked() signal of pushButton object to a local slot and emit signal pushButtonClicked()from there.
Install MyWidget as mouseEventFilter for pushButton and handle it inside MyWidget::mouseClickedEvent
Are there other options? Like somehow letting Qt framework to use 'MyWidget::pushButtonClicked()' instead of pushButton->clicked()
In the project I have many scenarios like this where such signal passing is needed from the wrapper classes like MyWidget, which wrap/abstract the UI by aggregation or inheritance. In general which is considered the best approach for better design, code reuse esp. when the project is at nascent stage and it is not known which of these UIs might need complex business logic in the future.
Please note that extending QPushButton is not an option.

You can connect signals directly =)
connect(pushButton , SIGNAL(clicked()), this, SIGNAL(pushButtonClicked()));

Related

Passing variable to promoted QWidget

I have two classes:
-MainWindow
-MyWidget which is promoted in MainWindow.ui using QT Creator's design tab.
Both of the class .ui's are designed in design tab.
I try to pass variables to MyWidget from MainWindow without any success. Compiler doesn't give any errors, but variables are not passing. Is there any way to do this? MyWidget works well as long as I don't import MainWindow to it or import MyWidget to MainWindow. After import I can't control MyWidget's content by code. Any suggestions?
EDIT: Made a small example and added code to pastebin, so this post won't get bloated.
MainWindow.h
MainWindow.cpp
another links are in comments
Your class MainWindow does not need to a MyWidget attribute. MyWidget object is actually created by Ui::MainWindow object.
So, to access your MyWidget object (the one displayed on screen as part of MainWindow widget), use ui->widget (as widget is the name you gave the object in Qt Designer <widget class="MyWidget" name="widget" native="true"/>), instead of mw.
Modifying mw makes no sense because this instance of MyWidget is not used for GUI display.
You then have to change:
connect(this, SIGNAL(text(QString, QString)),&mw, SLOT(addText(QString,QString)));
into:
connect(this, SIGNAL(text(QString, QString)),ui->widget, SLOT(addText(QString,QString)));
Note: If MyWidget class needs parameters to be passed upon construction, you can remove the widgetinstanciation from your .ui file and create it locally using mw attribute of the MainWindow class as you did. But, then, to have this instance be shown on screen, you must add it to the layout of your MainWindow, like this (for example): ui->horizontalLayout->addWidget( &mw );

QT creating push buttons that add text to a text edit box

New to QT just playing around with it to see if its something I will enjoy using and if so would like to go on and learn the program in depth.
Struggling a bit with the button concept. I have created a button and a textedit area. I want to add a string of text into the textedit window when the button is pressed.
I can't seem to find anything on google or the QT wiki to achieve this. Can someone point me in the direction so I can at least get started and have a play with this great tool.
In Qt signals and slots are being used to communicate between the objects. This should provide you with the necessary information to get you started.
A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal. Qt's widgets have many pre-defined slots, but it is common practice to subclass widgets and add your own slots so that you can handle the signals that you are interested in.
So, in your particular case you need to connect the QPushButton clicked() signal with your custom slot that does what is needed (add the text to the textarea):
QPushButton * btn = new QPushButton("Button", this);
connect(btn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
And we need to declare our slot in the header:
private slots:
void onBtnClicked();
And define it:
void MySpecialWidget::onClick()
{
// Do what is to be done
}
If you have done everything correctly it should work... Otherwise have a look at the console to see if there are any messages looking like:
Object::connect: No such slot MySpecialWidget::onClick() in ...
or
Object::connect: No such signal ....
They should give you a hint about what is going on.
Finally I recommend to have a look at the broad set of Qt examples.

Does it matter if i start a qt base as QMainWindow or as a QDialog?

if i need multiple dialogs for my application. QmainWindow is just for layout of multiple dialogs?
QMainWindow is still a single window but it provides facilities for advanced GUI programming.
If you need to pop up multiple dialogs first read Modeless Dialogs section of qt docs.
If basically says that create your dialogs on the heap and use show() method.
Something like below (untested code). This should show two dialogs at the same time.
int main( int argc, char ** argv )
{
QApplication app;
Mydialog1 dlg1 = new Mydialog1();
dlg1->show ();
Mydialog1 dlg2 = new Mydialog2();
dlg2->show ();
a.exec();
}
Yes, a QMainWindow provides a the base window for a regular GUI application. A regular GUI application is thought of as having "Menus", "Toolbars", "Status bar"
AFAIK, a QDialog does not provide any of the above. if your application doesn't require any menus, toolbars etc... then you can simply use QDialogs as you said. But I'd strongly recommend using a QMainWindow if your application has multiple widgets. If you can explain what you are trying to achieve then maybe we can help you with better alternatives.

How to generate a window (widget) on button press in qt

I have designed a GUI through Qt creator on Linux. This design consists of some fields, text edit and some push buttons.
When I press on the push button I want to display another window. Is there any GUI option for this or any hard code?
You need signals and slots.
You have to connect the clicked signal to a custom slot, created by you, of your main widget.
Corrected Code, based in the comments of Patrice Bernassola and Job.
In the class definition (.h file) add the lines:
Q_OBJECT
private slots:
void exampleButtonClicked();
private:
QDialog *exampleDialog;
The macro Q_OBJECT is needed when you define signals or slots in your classes.
The variable exampleDialog should be declared in the definition file to have access to it in the slot.
And you have to initialize it, this is commonly done in the constructor
ExampleClass::ExampleClass()
{
//Setup you UI
dialog = new QDialog;
}
In the class implementation (.cpp file) add the code that does what you want, in this case create a new window.
void ExampleClass::exampleButtonClicked()
{
exampleDialog->show();
}
And also you have to connect the signal to the slot with the line:
connect(exampleButton, SIGNAL(clicked()), this, SLOT(exampleButtonClicked()));
Your question is somehwat basic, so I suggest to read a basic tutorial, in this way you can make progress faster, avoiding waiting for answers.
Some links to tutorials that were useful to me:
http://zetcode.com/tutorials/qt4tutorial/
http://doc.qt.io/archives/qt-4.7/tutorials-addressbook.html
on click event of button you create another widget and show.
another option is Stacked widget, http://doc.trolltech.com/4.6/qstackedwidget.html

how to create & call slot in other class than MainWindow?

Currently Im using QT Creator which created UI file for view and I'm a QT starter.
There is a part I am curious is that how can i create another Class for, let say a GraphicView, so that I can send signal and slot to that class instead of the main form?
Side Question: why I can't edit Singal and Slot in other place than MainWindow in Edit Signal/Slot Mode? (the edit button is not activated if it's not MainWindow, so i have to use those default Signal) Let say i need to create a ToggleFullScreen() but the edit is gray out, how do I do it?
Adam is right.
But there are several ways to use a UI file in your application.
Have a look at http://qt.nokia.com/doc/4.5/designer-using-a-ui-file.html
For signal-slot specific question : see the link in Adam answer.
But, in summary, if you declare the Q_OBJECT macro in yours classes, you can communicate between those by signal-slot mechanism !
Signals and Slots
You have to create a derived class that inherits from QMainWindow if you want to add new signals or slots.

Resources