Qt pass data between multiple forms - qt

I am new to Qt and understands the concept of signal and slots. However I am not able to implement it.
My objective is:
Form1 has a button Config. So when I click Config it should open another form Form2( without closing Form1) and send a string strData to Form2.
In Form2 I set some value in the string strData. Then I click Ok button in Form2, Form2 should close and return back the string to Form1.
When the call returns back to Form1, it should continue from where it emitted the signal to invoke Form2.
Any help is highly appreciated.

You can't do this using signals/slots; the signal is emitted, and all of the connected slots are executed, and then the code continues from where the signal is emitted and eventually returns to the event loop. That's when your second form is actually shown and the user can respond to it, but by then, your code is long past where the signal was emitted.
What I believe you're looking for is the QDialog::exec method; use it in place of the signal. The basic pattern of the code is:
// This is the response to click on Config...
Form2Dialog form2;
form2.setSomeStringValue (some_value);
if (form2.exec() == QDialog::Accepted)
{
QString some_new_value = form2.newValue();
}
The Form2Dialog is a subclass of QDialog where you've added your own setSomeStringValue and newValue methods. (What you actually name these is up to you.)
The important thing is that the exec method blocks and doesn't return until the user selects OK or Cancel on the dialog, or closes it using the "close" button in the title bar (if there is one).

Related

Send signal data from QMainwindow to QDialog

I am going to send data collected in the QMainWindow to an object of QDialog via signal-slot connections. Here is the relevant code fragment to do this in mainwindow.cpp:
void MainWindow::on_dialogA_clicked()
{
if(dialogA==NULL) dialogA =new MyDialog();
//'this' refers to MainWindow
connect(this,SIGNAL(sendData(QVector<bool>)), dialogA, SLOT(getData(QVector<bool>)), Qt::QueuedConnection);
dialogA->show();
}
However when working with dialogA, it seems that the data are not updated properly and the dialog interface becomes Not responding after while. I wonder if the signal-slot connection above is right or not, or that is the way to have data communication with a QDiaglog.
Two things...first, switch to the modern method of creating signal/slot connections:
connect (this, &MainWindow::sendData, dialogA, &MyDialog::getData, Qt::QueuedConnection);
If there's something wrong with the definition, using this format allows the compiler to catch it rather than a run-time warning. Assuming the parameters are defined correctly, there's nothing wrong with the "connect" statement except that it's in the wrong place, which is the second issue.
Every time the user clicks, an additional connection is being made between your main window and the dialog. Qt doesn't automatically ensure that only one connection is made between a given signal and slot. It'll create as many as you ask it for. The "connect" call should be part of the "if" block:
if (! dialogA)
{
dialogA =new MyDialog();
connect...
}
Depending on how much data is in that vector and what the dialog does with it, if you click enough times, it may be that you're just processing the data so many times that everything slows down tremendously.

QTabWidget: close tab button not working

I have set ui->tabWidget->setTabsClosable(true); but QTabwidget only showing a cross on each tab that is not closing tab on click on this button. What else I have to do to make tabs closable? I tried to connect any slot (which would be proper for this work) of close to signal tabCloseRequested(int) but couldn't find any such slot in tabwidget. Please suggest the right way.
Create a slot e.g. closeMyTab(int) and connect the tab widget's tabCloseRequested(int) signal to this slot. In this slot call tab widget's removeTab method with the index received from the signal.
See this answer for more details.
For future stumblers upon this question looking for a PyQt5 solution, this can be condensed into a 1-liner:
tabs = QTabWidget()
tabs.tabCloseRequested.connect(lambda index: tabs.removeTab(index))
The tabCloseRequested signal emits an integer equal to the index of the tab that emitted it, so you can just connect it to a lambda function that takes the index as its argument.
The only problem I could see with this is that connecting a lambda function to the slot prevents the object from getting garbage collected when the tab is deleted (see here).
EDIT (9/7/21): The lambda function isn't actually necessary since QTabWidget.removeTab takes an integer index as its sole argument by default, so the following will suffice (and avoids the garbage-collection issue):
tabs.tabCloseRequested.connect(tabs.removeTab)
The best way to do it since we got new connection syntax (Qt 5) is:
QTabWidget* tabWidet = new QTabWidget();
connect(tabWidget->tabBar(), &QTabBar::tabCloseRequested, tabWidget->tabBar(), &QTabBar::removeTab);
You just need to tell the tabWidget itself to close the requested tab index (the param passed to the slot) as this:
ui->tabWidget->removeTab(index);

CloseEvent Qt from instance class

I created a Qt form that handles the close event. In my other class (Test class), I create an instance of this form and would like to handle the close event of the form from the "Test" class.
I tried using the following code in the "Test" class, but does not seem to work .
connect(instanceWidget, SIGNAL(closeEvent(QCloseEvent *)), this, SLOT(handleFormCloseEvent(QCloseEvent *)));
Note instanceWidget is the instance of the Qt form from test class.
The event handler methods, like closeEvent, are not signals, so you can't connect to them.
The event processing goes like this:
The event loop gets an event for given object from its queue.
It notifies the object by calling object->event(...).
This method is reimplemented in QWidget and calls relevant specific event handler. In this case, it calls closeEvent().
The signals/slots are not involved.
If you want to handle events of other objects (a QWidget is a QObject), you must install an event filter on them. Your event filter will react to the event you care about, while passing onwards other events.
My solution -
Handle OnClose event in the form/UI class and inject the following code -
emit OnClose();
event->accept;
Add Signal OnClose();
In the instantiated (test class) , create a signal and slot for OnClose and provide custom funcationality.
-- Closing form , calls UI's close event handler, which emits onclose signal and gets handled by test class. after which it returns to form class and closes the form.

preesing enter on QLineEdit terminates the screen

i have a QLineEdit on my main screen define by QDialog.along with it i have a table which contains dynamic data displayed by QThread with 50 data in every 2 seconds.when i input any value in QLinrEdit and then press enter then the screen terminates.
value = new QLineEdit(this);
m_label = new QLabel(tr("&Enter Preference Value:"));
m_label->setBuddy(value);
m_preLayout->addWidget(m_label);
m_preLayout->addWidget(value);
m_preferenceGroup->setLayout(m_preLayout);
connect(value, SIGNAL(returnPressed()), this, SLOT(preferentialData()));
void appWindow::preferentialData()
{
valuee = (value->text()).toInt();
}
here i am taking the input from user and then converting that input into an integer which will be further used for some other purpose.Now after taking that input as per signal i press enter and as soon as after that the screen closes.
the value is converted to int and no errors are coming on compiling but why is the window closing? because if it closes then the thing that i will further do with that converted int will be like of no use as with the help of that int i will change some display on my table as i mentioned that i have a table too in that window.
thanks for any help in advance
I'm almost certain (can't be sure without seeing more code) that the dialog is taking the "Enter" keypress and calling its accept() method, which closes the dialog. If you made the dialog in Qt Creator and chose one of the dialog types that places a button box on the form for you, then this connection is wired up by default.
Check your dialog's signal/slot connections and make sure that the accept() slot isn't connected to a QPushButton or QDialogButtonBox signal.

QT signals & slots

How to use signal and slots for handling events i.e when a pushButton is clicked some number should be displayed in QLineEdit.Just like in caluculator application when a number is clicked the corresponding is displayed .
connect a widget's signal to other's widget slot.
Signal = Emitted when the button (for instance) is pressed.
Slot = called when a certain singal is fired, and this signal is connected to this slot.
If You use QtCreator here is the procedure:
right click on the pushbutton. Select go to slot.
Select clicked()
QtCreator will open C++ editor with new empty member function defined that implements
your slot. This function will be called whenever someone clicks this button.
Now in this function you can call method of another widget ot modify its contants.
This book is quite good for starters:
http://www.amazon.com/Book-Qt-Art-Building-Applications/dp/1593271476/ref=sr_1_8?ie=UTF8&qid=1300905855&sr=8-8
Good luck.

Resources