How to emit signal from Dialog to a slot in MainWindow in PyQt
-
I'm getting started on PyQt5, I've been trying to learn about signals and slots as it seems to be the proper way to communicating between classes in PyQT.
Below you'll find my code, let me walk trough the code with you as you'll better understand my problem.
I have a mainwindow with a pushbutton
- When the button is clicked, a dialog window is executed.
- The User inputs some data in textLineEdits, then clicks on a "Add" button
- The Data is dumped to a Json File
And here's where I come to a halt:
- When my data gets written in my Json file, I want to emit a signal with 2 strings as argument.
- Connect the signal with a function in MainWindow class in order to add Items to my Combobox (the ComboBox is in the MainWindow)
Here's my demonstration code:
from PyQt5 import QtCore, QtGui, QtWidgets import sys import ui.mainwindow as MnWindow import ui.AddUserDialog as AddUserDialog class MainWindow(QMainWindow,MnWindow.Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.pushButtonAddUser.clicked.connect(self.showDialog) def showDialog(self): d = AddUserDialog(self) d.exec_() #Catch the emited signal from AddUserDialog and connect it to AddToCombo function def AddToCombo(self,first,last): self.UserComboBox.addItem(first + ' ' + last) class AddUserDialog(QDialog,AddUserDialog.Ui_Dialog): def __init__(self,parent=None): super(AddUserDialog,self).__init__(parent) self.setupUi(self) self.pushButtonAddUser.clicked.connect(self.AddUser) def AddUser(self): new_user = { 'firstname' : self.lineEditPrenom.text(), 'lastname' : self.lineEditNom.text(), 'Adresse' : self.lineEditAdresse.text(), 'Town' : self.lineEditVille.text(), 'ZipCode' : self.lineEditCodePostal.text(), } with open('MyJsonFile.json','r') as f: data = json.load(f) data['users'].append(new_user) with open('MyJsonFile.json','w') as f: json.dump(data,f,indent=3) #Emit signal with new_user['firstname'] & new_user['lastname'] as arguments self.close() if __name__ == "__main__": app = QApplication(sys.argv) form = MainWindow() form.show() app.exec_()
-
Hi,
This is a case where you do not need to do that.
Since you have a dialog, you can simply make a getter that will return the values you are interested in. After exec is done, just grab the values and set them where appropriate.
Signals and slots are great but you do not need them for everything.
-
A getter is juste a Python method in your class that returns something.
As for signals and slots, you can add the two signals you want to your dialog class and then connect them before calling exec.
-
@SGaist Thanks for your comment. I think I get it for the first solution.
As for the signal method, I'm just starting to learn about signals in Pyqt, Can you show me, if I'm not asking too much, a code demonstration of how to implement this ?
Thanks,
-
-
Hi @SGaist,
I've been following the link you passed me, here's what I did:
created a signal
class AddUserDialog(QDialog): # define a signal that emits two strings user_added = QtCore.pyqtSignal(str, str) ... def AddUser(self): ... # emit signal self.user_added.emit(new_user['firstname'], new_user['lastname']) self.close()
Connected the signal:
class MainWindow(QMainWindow,MnWindow.Ui_MainWindow): .... def showDialog(self): d = AddUserDialog(self) # connect signal to appropriate slot d.user_added.connect(self.AddToCombo) d.exec_()
Still It doesn't work, I get the following error:
AttributeError: 'AddUserDialog' object has no attribute 'user_added'
Any Idea Why this doesn't work?
Thanks again,
-
Can you provide a minimal runnable example that shows your issue ?