How to transfer data between two widgets if they can't get each other's instance directly
-
Hi guys,
Looking at the code below, the
widgetA
andwidgetB
can communicate with each other because their instances can be accessed frommainwindow
Class.But in my case, I am going to create extensions(
widgetA
andwidgetB
) frommainwindow
, and the two sub widgets are in different project folders. I can't control howmainwindow
initiates the two instances.In addition,
widgetA
andwidgetB
are not child widgets of mainwindow. So I cannot use findChild() to get instances frommainwindow
.In such case, is there a way to make widgetA and widgetB transfer data by using signal/slot or other mechanism, if they can't get each other's instance?
Cheers.
from PyQt5 import QtCore, QtGui, QtWidgets class widgetB(QtWidgets.QWidget): procDone = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(widgetB, self).__init__(parent) self.lineEdit = QtWidgets.QLineEdit(self) self.button = QtWidgets.QPushButton("Send Message to A", self) self.layout = QtWidgets.QHBoxLayout(self) self.layout.addWidget(self.lineEdit) self.layout.addWidget(self.button) self.button.clicked.connect(self.on_button_clicked) @QtCore.pyqtSlot() def on_button_clicked(self): self.procDone.emit(self.lineEdit.text()) @QtCore.pyqtSlot(str) def on_procStart(self, message): self.lineEdit.setText("From A: " + message) self.raise_() class widgetA(QtWidgets.QWidget): procStart = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(widgetA, self).__init__(parent) self.lineEdit = QtWidgets.QLineEdit(self) self.lineEdit.setText("Hello!") self.button = QtWidgets.QPushButton("Send Message to B", self) self.button.clicked.connect(self.on_button_clicked) self.layout = QtWidgets.QHBoxLayout(self) self.layout.addWidget(self.lineEdit) self.layout.addWidget(self.button) @QtCore.pyqtSlot() def on_button_clicked(self): self.procStart.emit(self.lineEdit.text()) @QtCore.pyqtSlot(str) def on_widgetB_procDone(self, message): self.lineEdit.setText("From B: " + message) self.raise_() class mainwindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(mainwindow, self).__init__(parent) self.button = QtWidgets.QPushButton("Click Me", self) self.button.clicked.connect(self.on_button_clicked) self.setCentralWidget(self.button) self.widgetA = widgetA() self.widgetB = widgetB() self.widgetA.procStart.connect(self.widgetB.on_procStart) self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone) @QtCore.pyqtSlot() def on_button_clicked(self): self.widgetA.show() self.widgetB.show() self.widgetA.raise_() if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main = mainwindow() main.show() sys.exit(app.exec_())
-
Hi guys,
Looking at the code below, the
widgetA
andwidgetB
can communicate with each other because their instances can be accessed frommainwindow
Class.But in my case, I am going to create extensions(
widgetA
andwidgetB
) frommainwindow
, and the two sub widgets are in different project folders. I can't control howmainwindow
initiates the two instances.In addition,
widgetA
andwidgetB
are not child widgets of mainwindow. So I cannot use findChild() to get instances frommainwindow
.In such case, is there a way to make widgetA and widgetB transfer data by using signal/slot or other mechanism, if they can't get each other's instance?
Cheers.
from PyQt5 import QtCore, QtGui, QtWidgets class widgetB(QtWidgets.QWidget): procDone = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(widgetB, self).__init__(parent) self.lineEdit = QtWidgets.QLineEdit(self) self.button = QtWidgets.QPushButton("Send Message to A", self) self.layout = QtWidgets.QHBoxLayout(self) self.layout.addWidget(self.lineEdit) self.layout.addWidget(self.button) self.button.clicked.connect(self.on_button_clicked) @QtCore.pyqtSlot() def on_button_clicked(self): self.procDone.emit(self.lineEdit.text()) @QtCore.pyqtSlot(str) def on_procStart(self, message): self.lineEdit.setText("From A: " + message) self.raise_() class widgetA(QtWidgets.QWidget): procStart = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(widgetA, self).__init__(parent) self.lineEdit = QtWidgets.QLineEdit(self) self.lineEdit.setText("Hello!") self.button = QtWidgets.QPushButton("Send Message to B", self) self.button.clicked.connect(self.on_button_clicked) self.layout = QtWidgets.QHBoxLayout(self) self.layout.addWidget(self.lineEdit) self.layout.addWidget(self.button) @QtCore.pyqtSlot() def on_button_clicked(self): self.procStart.emit(self.lineEdit.text()) @QtCore.pyqtSlot(str) def on_widgetB_procDone(self, message): self.lineEdit.setText("From B: " + message) self.raise_() class mainwindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(mainwindow, self).__init__(parent) self.button = QtWidgets.QPushButton("Click Me", self) self.button.clicked.connect(self.on_button_clicked) self.setCentralWidget(self.button) self.widgetA = widgetA() self.widgetB = widgetB() self.widgetA.procStart.connect(self.widgetB.on_procStart) self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone) @QtCore.pyqtSlot() def on_button_clicked(self): self.widgetA.show() self.widgetB.show() self.widgetA.raise_() if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main = mainwindow() main.show() sys.exit(app.exec_())
@Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:
In such case, is there a way to make widgetA and widgetB transfer data by using signal/slot or other mechanism, if they can't get each other's instance?
Yes. It is main window which knows about both of them
, the widgetA and widgetB can communicate with each other because their instances can be accessed from mainwindow Class.
So let main window do the
connect()
of some signal emitted by one widget to some slot defined in the other widget. Your own signals and slots. Pass whatever minimal parameter(s) might be required to do whatever job. There should be no reason why one widget needs to actually access the other widget.You seem to already know this when I see you have
self.procStart.emit(self.lineEdit.text())
? And you haveself.widgetA.procStart.connect(self.widgetB.on_procStart) self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
Oh, I see, you seem to know this! Then
But in my case, I am going to create extensions(widgetA and widgetB) from mainwindow , and the two sub widgets are in different project folders. I can't control how mainwindow initiates the two instances.
I don't get this. If mainwindow has the two instances it should be able to do the
connect()
. So what is your exact situation? -
Hi @JonB ,
thank you for your reply.
In my case, I don't have any control of the main window, so I can't get widgetA and widgetB objects in the main window.
My question is if there is a way to send signal from widgetA, then widgetB can connect the signal without knowing(getting) widgetA object? Connecting a signal by the name of it.
Because main window, widgetA, widgetB are in the same thread, is it possible to send signal to message(main) loop and catching it by the name?
Cheers
-
Hi @JonB ,
thank you for your reply.
In my case, I don't have any control of the main window, so I can't get widgetA and widgetB objects in the main window.
My question is if there is a way to send signal from widgetA, then widgetB can connect the signal without knowing(getting) widgetA object? Connecting a signal by the name of it.
Because main window, widgetA, widgetB are in the same thread, is it possible to send signal to message(main) loop and catching it by the name?
Cheers
@Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:
Connecting a signal by the name of it.
Not possible, because objects emit signals. So, you need the emitting object and you need receiving object to connect. Somewhere in your application you should be able to have both instances to connect.
"I don't have any control of the main window" - but in the code you posted you clearly create both objects in main window.
-
@Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:
Connecting a signal by the name of it.
Not possible, because objects emit signals. So, you need the emitting object and you need receiving object to connect. Somewhere in your application you should be able to have both instances to connect.
"I don't have any control of the main window" - but in the code you posted you clearly create both objects in main window.
-
Hi guys,
Looking at the code below, the
widgetA
andwidgetB
can communicate with each other because their instances can be accessed frommainwindow
Class.But in my case, I am going to create extensions(
widgetA
andwidgetB
) frommainwindow
, and the two sub widgets are in different project folders. I can't control howmainwindow
initiates the two instances.In addition,
widgetA
andwidgetB
are not child widgets of mainwindow. So I cannot use findChild() to get instances frommainwindow
.In such case, is there a way to make widgetA and widgetB transfer data by using signal/slot or other mechanism, if they can't get each other's instance?
Cheers.
from PyQt5 import QtCore, QtGui, QtWidgets class widgetB(QtWidgets.QWidget): procDone = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(widgetB, self).__init__(parent) self.lineEdit = QtWidgets.QLineEdit(self) self.button = QtWidgets.QPushButton("Send Message to A", self) self.layout = QtWidgets.QHBoxLayout(self) self.layout.addWidget(self.lineEdit) self.layout.addWidget(self.button) self.button.clicked.connect(self.on_button_clicked) @QtCore.pyqtSlot() def on_button_clicked(self): self.procDone.emit(self.lineEdit.text()) @QtCore.pyqtSlot(str) def on_procStart(self, message): self.lineEdit.setText("From A: " + message) self.raise_() class widgetA(QtWidgets.QWidget): procStart = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(widgetA, self).__init__(parent) self.lineEdit = QtWidgets.QLineEdit(self) self.lineEdit.setText("Hello!") self.button = QtWidgets.QPushButton("Send Message to B", self) self.button.clicked.connect(self.on_button_clicked) self.layout = QtWidgets.QHBoxLayout(self) self.layout.addWidget(self.lineEdit) self.layout.addWidget(self.button) @QtCore.pyqtSlot() def on_button_clicked(self): self.procStart.emit(self.lineEdit.text()) @QtCore.pyqtSlot(str) def on_widgetB_procDone(self, message): self.lineEdit.setText("From B: " + message) self.raise_() class mainwindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(mainwindow, self).__init__(parent) self.button = QtWidgets.QPushButton("Click Me", self) self.button.clicked.connect(self.on_button_clicked) self.setCentralWidget(self.button) self.widgetA = widgetA() self.widgetB = widgetB() self.widgetA.procStart.connect(self.widgetB.on_procStart) self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone) @QtCore.pyqtSlot() def on_button_clicked(self): self.widgetA.show() self.widgetB.show() self.widgetA.raise_() if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main = mainwindow() main.show() sys.exit(app.exec_())
@Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:
I can't control how
mainwindow
initiates the two instances.- Can you work together with the person(s) who have control over
mainwindow
? - The
mainwindow
obviously has a reason to instantiate your widgets. Does it provide any mechanism for your widgets to send/receive data?
- Can you work together with the person(s) who have control over
-
@Zac15 said in How to transfer data between two widgets if they can't get each other's instance directly:
I can't control how
mainwindow
initiates the two instances.- Can you work together with the person(s) who have control over
mainwindow
? - The
mainwindow
obviously has a reason to instantiate your widgets. Does it provide any mechanism for your widgets to send/receive data?
Hi @JKSH,
I don't have any control to the
mainwindow
.But I contacted the
mainwindow
developers, and they told me a way to get the objects of the child widgets frommainwindow
.They didn't document that, but there is an internal function to fetch children objects, which resolved my problem.
Thanks for your help.
- Can you work together with the person(s) who have control over