Search code examples
pythonpython-3.xpyqtpyqt5qcombobox

set strings to comboBox from other Dialog


I have made two GUIs in Pyqt5 & Qt Designer. The first GUI is to show the person name in a comboBox. The second GUI will be opend by clicking + button and then the user can write the name,age and job which i need later in other thing.

My Question is, how can i get the new name from the 2. GUI and set it in comboBox of the 1. GUI. I tried that in the below code but it doesn't work.

whole code:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(363, 165)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(30, 30, 68, 19))
        self.label.setObjectName("label")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(120, 30, 131, 25))
        self.comboBox.setObjectName("comboBox")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(280, 30, 41, 34))
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 363, 31))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "person"))
        self.pushButton.setText(_translate("MainWindow", "+"))

    def InputDialog1(self):
        self.Dialog = QtWidgets.QDialog()
        self.ui=Ui_Dialog()
        self.ui.setupUi(self.Dialog)
        self.Dialog.setWindowTitle('Add Infos')
        self.Dialog.show()

class Person_data(object):
    def __init__(self,parent=None):
         self.Person_1 = {'-':[0,0]}

class MainWindow(QMainWindow, Ui_MainWindow,Person_data):

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent=parent)
        Person_data.__init__(self, parent=parent)
        self.setupUi(self)
        self.initMe()

    def initMe(self):
        self.pushButton.clicked.connect(self.InputDialog1)

        Person_list={}
        for i in self.Person_1.keys():
                Person_list[i] = ''
                Person_list_2 = list(Person_list)
        print(Person_list_2)
        self.comboBox.addItems(Person_list_2)



class Ui_Dialog(Person_data):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(344, 231)
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(170, 160, 112, 34))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(Dialog)
        self.pushButton_2.setGeometry(QtCore.QRect(30, 160, 112, 34))
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(30, 20, 271, 121))
        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.gridLayoutWidget)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.gridLayoutWidget)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.lineEdit_3 = QtWidgets.QLineEdit(self.gridLayoutWidget)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.gridLayout.addWidget(self.lineEdit_3, 2, 1, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
        self.label = QtWidgets.QLabel(self.gridLayoutWidget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        self.pushButton.clicked.connect(self.okpress)
        self.pushButton_2.clicked.connect(Dialog.close)

    def okpress(self):
        aa1=float(self.lineEdit_2.text());aa2=float(self.lineEdit_3.text())
        self.Person_1[str(self.lineEdit.text())] = [aa1,aa2]
        i = True
        while i == True:
            bb = MainWindow()
            Person_list={}
            for i in self.Person_1.keys():
                Person_list[i] = ''
                Person_list_2 = list(Person_list)
            print(Person_list_2)
            bb.comboBox.addItems(Person_list_2)
            i=False  #just to exit while


    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton.setText(_translate("Dialog", "add"))
        self.pushButton_2.setText(_translate("Dialog", "Cancel"))
        self.label_2.setText(_translate("Dialog", "Age"))
        self.label_3.setText(_translate("Dialog", "Job"))
        self.label.setText(_translate("Dialog", "Name"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.setWindowTitle('Main Person Windows')
    w.show()
    sys.exit(app.exec_())

Solution

  • It is not recommended that you modify the code generated by Qt Designer, since you can have unexpected behaviors, in addition to messing up the code. The appropriate thing from my perspective is to create classes that inherit from the appropriate widgets and that use the design of QtDesigner, so my answer includes the restructuring of the code to make it more readable.

    Analyzing in your code I see that you confuse the inheritance with the idea of sharing data, when it is inherited from a class it creates similar but not equal elements in each class, even though each object of those classes create similar objects among them but they are not the same , are not the same variables so they point to different memory space, in your case you think that as Ui_Dialog and MainWindow inherit from Person_data, then the variables Person_1 in both classes are the same, and in reality it is not.

    Another problem that your code has is the validation, one must try that the user places appropriate values and must interact with certain elements when necessary, for example the conversion to float can cause problems if the text is empty or is not a number, also the add button should only be enabled if all fields are filled in properly, for this Qt provides classes such as QIntValidator.

    QDialog is a class specialized in forms and we should try as much as possible to use exec_() since it returns if the form is accepted or not, but for this you must use the accept and reject methods when the buttons are appropriate.

    Code:

    class PersonDialog(QtWidgets.QDialog, Ui_Dialog):
        def __init__(self, *args, **kwargs):
            QtWidgets.QDialog.__init__(self, *args, **kwargs)
            self.setupUi(self)
            self.pushButton.clicked.connect(self.accept)
            self.pushButton_2.clicked.connect(self.reject)
            self.lineEdit_3.setValidator(QtGui.QIntValidator(0, 100))
            self.lineEdit.textChanged.connect(self.enableButtonAccept)
            self.lineEdit_2.textChanged.connect(self.enableButtonAccept)
            self.lineEdit_3.textChanged.connect(self.enableButtonAccept)
            self.enableButtonAccept()
    
        def enableButtonAccept(self):
            if self.lineEdit.text() != "" and self.lineEdit_2.text() != "" and self.lineEdit_3.text() != "":
                self.pushButton.setEnabled(True)
            else:
                self.pushButton.setEnabled(False)
    
        def getPerson(self):
            values = self.lineEdit.text(), self.lineEdit_2.text(), int(self.lineEdit_3.text())
            self.lineEdit.clear()
            self.lineEdit_2.clear()
            self.lineEdit_3.clear()
            return values
    
    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
        def __init__(self, *args, **kwargs):
            QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
            self.setupUi(self)
            self.Person_1 = {}
            self.initMe()
    
        def initMe(self):
            self.personDialog = PersonDialog(self)
            self.pushButton.clicked.connect(self.InputDialog1)
    
        def InputDialog1(self):
            if self.personDialog.exec_() == PersonDialog.Accepted:
                name, job, edad = self.personDialog.getPerson()
                self.Person_1[name] = [job, edad]
                self.comboBox.addItem(name)