Example of calling a function to parent?
-
I 'm searching for a simple example of calling (from a form) a function to another form.
Let me explain: I have FormA with a button on it. Clicking this button I open FormB which also has a button.
When I click on FormB's button I want to call a function in FormA.From what I read it will be done with Signal, Slots and emit() (but to tell the truth I don't understand much).
Is there some example? -
Ok, I found a python example that works.
#!/usr/bin/python3 # Threading example with QThread and moveToThread (PyQt5) import sys import time from PyQt5 import QtWidgets, QtCore class WorkerThread(QtCore.QObject): signalExample = QtCore.pyqtSignal(str, int) def __init__(self): super().__init__() @QtCore.pyqtSlot() def run(self): while True: # Long running task ... self.signalExample.emit("leet", 1337) time.sleep(5) class Main(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.worker = WorkerThread() self.workerThread = QtCore.QThread() self.workerThread.started.connect(self.worker.run) # Init worker run() at startup (optional) self.worker.signalExample.connect(self.signalExample) # Connect your signals/slots self.worker.moveToThread(self.workerThread) # Move the Worker object to the Thread object self.workerThread.start() def signalExample(self, text, number): print(text) print(number) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) gui = Main() sys.exit(app.exec_())
I want to modify it (in python code for now) so that the WorkerThread class' code will 'move' to mainWindow (and WorkerThread class to be completely removed).
How can I do this? -
Ok, I found a python example that works.
#!/usr/bin/python3 # Threading example with QThread and moveToThread (PyQt5) import sys import time from PyQt5 import QtWidgets, QtCore class WorkerThread(QtCore.QObject): signalExample = QtCore.pyqtSignal(str, int) def __init__(self): super().__init__() @QtCore.pyqtSlot() def run(self): while True: # Long running task ... self.signalExample.emit("leet", 1337) time.sleep(5) class Main(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.worker = WorkerThread() self.workerThread = QtCore.QThread() self.workerThread.started.connect(self.worker.run) # Init worker run() at startup (optional) self.worker.signalExample.connect(self.signalExample) # Connect your signals/slots self.worker.moveToThread(self.workerThread) # Move the Worker object to the Thread object self.workerThread.start() def signalExample(self, text, number): print(text) print(number) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) gui = Main() sys.exit(app.exec_())
I want to modify it (in python code for now) so that the WorkerThread class' code will 'move' to mainWindow (and WorkerThread class to be completely removed).
How can I do this?@Panoss
You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer. In any case you cannot perform any UI actions in anything but the main thread in Qt, so what you describe will not work anyway.Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.
-
@Panoss
You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer. In any case you cannot perform any UI actions in anything but the main thread in Qt, so what you describe will not work anyway.Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.
-
@Panoss
You have picked an example with threads. Why? That is the last thing you should be doing as a newcomer. In any case you cannot perform any UI actions in anything but the main thread in Qt, so what you describe will not work anyway.Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.
@JonB said in Example of calling a function to parent?:
Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.
This was the first I read, but as I mentioned, didn't understand much. This is why I'm looking for a working, simple, example.
-
@JonB said in Example of calling a function to parent?:
Have you read https://doc.qt.io/qt-5/signalsandslots.html ? That shows the sort of thing you were asking about, and does not mention threads.
This was the first I read, but as I mentioned, didn't understand much. This is why I'm looking for a working, simple, example.
Ok, I have an example in python which is exactly as I want it:
from PySide6 import QtWidgets, QtCore class FormB(QtWidgets.QWidget): form_done = QtCore.Signal(str) def __init__(self, *args, steps=5, **kwargs): super().__init__(*args, **kwargs) self.entry = QtWidgets.QLineEdit("Enter value here") self.button = QtWidgets.QPushButton("Done") self.button.clicked.connect(self.button_pressed) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.entry) layout.addWidget(self.button) def button_pressed(self): #self.hide() self.form_done.emit(self.entry.text()) class FormA(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_b = None self.button = QtWidgets.QPushButton("Draw B") self.button.clicked.connect(self.draw_b) self.label = QtWidgets.QLabel("I display the result in this label") layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.button) layout.addWidget(self.label) def draw_b(self): if self.form_b is None: self.form_b = FormB() self.form_b.form_done.connect(self.b_done) self.form_b.show() def b_done(self, text): self.label.setText(text) def main(): app = QtWidgets.QApplication([]) form_a = FormA() form_a.show() app.exec() main()
So, how do I convert this python code:
form_done = QtCore.Signal(str)
to c++?
-
Hi,
The Qt documentation contains quite a lot of examples using signals and slots. You should go through the ones from the widgets module since it's the one you are implementing your application with.
-
Hi,
The Qt documentation contains quite a lot of examples using signals and slots. You should go through the ones from the widgets module since it's the one you are implementing your application with.
@SGaist said in Example of calling a function to parent?:
The Qt documentation contains quite a lot of examples using signals and slots
Didn't find a full working example, only fragments of code I 'm trying to put together.
If you have found a full working example please post it! -
These lines are to be found in the class declaration.
-
And now this:
QObject::connect(&a, &Counter::valueChanged, &b, &Counter::setValue);
I modified it to (this code is in the constructor of FormB):
connect(&parent, &parent::valueChanged, this, &FormB::setValue);
???
It's wrong...The 'parent' I mean.
The sender is FormB...so.. -
And now this:
QObject::connect(&a, &Counter::valueChanged, &b, &Counter::setValue);
I modified it to (this code is in the constructor of FormB):
connect(&parent, &parent::valueChanged, this, &FormB::setValue);
???
It's wrong...The 'parent' I mean.
The sender is FormB...so..@Panoss
Everything is upside down :)let's recap, you want the main window (formA) to be inform when a value has changed in second window (formB)
The main window register to receive a signal from the second window.
In formA:
connect(formB, &FormB::valueChanged, this , &FormA::valueChangedInFormB);
-
@mpergand it works!!!
Thank you all!The actual name of FormA is 'ArticlesWindow' and of FormB 'positionsForm'.
(FormB is the sender)
I post the code in case someone needs it:articleswindow.h private slots: void positionChanged(); articleswindow.cpp void ArticlesWindow::positionChanged(){ qDebug() << "ArticlesWindow::positionChanged"; } void ArticlesWindow::openPositionsForm(){ class positionsForm *form = new class positionsForm(model, this); connect(form, &positionsForm::valueChanged, this , &ArticlesWindow::positionChanged);
And:
positionsform.h public slots: void setValue(int value); signals: void valueChanged(int newValue); positionsform.cpp void positionsForm::setValue(int value) { emit valueChanged(value); }
-
@mpergand it works!!!
Thank you all!The actual name of FormA is 'ArticlesWindow' and of FormB 'positionsForm'.
(FormB is the sender)
I post the code in case someone needs it:articleswindow.h private slots: void positionChanged(); articleswindow.cpp void ArticlesWindow::positionChanged(){ qDebug() << "ArticlesWindow::positionChanged"; } void ArticlesWindow::openPositionsForm(){ class positionsForm *form = new class positionsForm(model, this); connect(form, &positionsForm::valueChanged, this , &ArticlesWindow::positionChanged);
And:
positionsform.h public slots: void setValue(int value); signals: void valueChanged(int newValue); positionsform.cpp void positionsForm::setValue(int value) { emit valueChanged(value); }
-
It works but the message is printed twice, like if function ArticlesWindow::positionChanged is called twice??