【问题标题】:Python PyQt Send Data Between FormsPython PyQt 在表单之间发送数据
【发布时间】:2018-11-27 23:11:26
【问题描述】:

我有两个用 Qt Designer 构建的表单。这两种形式利用了here 中描述的 uic.loadUiType 过程。我已将 UI 表单上传到 this location 以导入表单。主窗口有三个按钮。当每个按钮被按下时——尝试将哪个按钮传递给数字键盘表单——尝试使用信号和插槽但不工作。

当 NumPad 表单打开时,我需要用 Field1、2 或 3 填充它,以便我可以将 txtDatToPass 的内容传递回主窗口表单。不知道为什么信号而不是通过。任何想法或指导都会有所帮助 谢谢

import sys
from PyQt5 import QtWidgets, QtCore 
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QApplication, QLabel
from PyQt5 import uic


qtCreatorFile = "MainWinForm.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

qtCreatorFileKeyPad = "NumPadForm.ui"
Ui_KeyPad, QtBaseClass = uic.loadUiType(qtCreatorFileKeyPad )


class PunchWindow(QtWidgets.QMainWindow):
    signalPassDataToMainForm = QtCore.pyqtSignal(str,str)
    def __init__(self):
        super(PunchWindow, self).__init__()
        self.ui = Ui_KeyPad()
        self.ui.setupUi(self)
        self.move(850, 200) #Center Screen

  #NumberPad
        self.ui.btnOne.clicked.connect(lambda: self.numberPad(1))
        self.ui.btnTwo.clicked.connect(lambda: self.numberPad(2))
        self.ui.btnThree.clicked.connect(lambda: self.numberPad(3))
        self.ui.btnFour.clicked.connect(lambda: self.numberPad(4))
        self.ui.btnFive.clicked.connect(lambda: self.numberPad(5))
        self.ui.btnSix.clicked.connect(lambda: self.numberPad(6))
        self.ui.btnSeven.clicked.connect(lambda: self.numberPad(7))
        self.ui.btnEight.clicked.connect(lambda: self.numberPad(8))
        self.ui.btnNine.clicked.connect(lambda: self.numberPad(9))
        self.ui.btnZero.clicked.connect(lambda: self.numberPad(0))
        self.ui.btnDot.clicked.connect(lambda: self.numberPad("."))
        self.ui.btnBackSpace.clicked.connect(lambda: self.numberPad("BS"))
        self.ui.btnClear.clicked.connect(lambda: self.numberPad("Clear"))
        self.ui.btnEnter.clicked.connect(self.Enter)
##
    def numberPad(self, n):
        print(n)
        strField = self.ui.txtDataField.toPlainText()
        if(strField == "Field1") or (strField == "Field2") or (strField == "Field3"):
            strValue = self.ui.txtDataToPass.toPlainText()
            strN = str(n)
            if(strN == "BS"):
                strTrim = strValue[:-1]
                self.ui.txtDataToPass.setText(strTrim)
            elif(strN == "Clear"):
                self.ui.txtDataToPass.setText("")
            else:        
                strValue = strValue + strN 
                self.ui.txtDataToPass.setText(strValue)

    def Enter(self):
        strFieldNo = self.ui.txtDataField.toPlainText()
        strSendData = self.ui.txtDataToPass.toPlainText()
        print("Trying to send contents of txtDataToPass back to MainWindow Form -- Data Field:  " + strFieldNo +  "      Data: "  + strSendData)
        self.signalPassDataToMainForm.emit(strFieldNo, strSendData)



class MainWindow(QtWidgets.QMainWindow):
    signalPassData = QtCore.pyqtSignal(str) # used to send Field1, 2 , or 3 to Punch Window

    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()        
        self.ui.setupUi(self)
        self.move(450, 200) #Center Screen

        self.ui.btnField1.clicked.connect(self.Field1)
        self.ui.btnField2.clicked.connect(self.Field2)
        self.ui.btnField3.clicked.connect(self.Field3)

        #Should recieve signals back from PunchWindow
        self.Punch = PunchWindow()
        self.Punch.signalPassDataToMainForm.connect(self.Update)

    def Update(self, strField, strData):
        self.ui.txtData1.setText(strData)

    def Field1(self):
        strField = "Field1"
        print(strField)
        self.ui.SW = PunchWindow()
        self.ui.SW.show()
        self.signalPassData.emit(strField)

    def Field2(self):
        strField = "Field2"
        print(strField)
        self.ui.SW = PunchWindow()
        self.ui.SW.show()
        self.signalPassData.emit(strField)

    def Field3(self):
        strField = "Field3"
        print(strField)
        self.ui.SW = PunchWindow()
        self.ui.SW.show()
        self.signalPassData.emit(strField)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    MW = MainWindow()
    MW.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案1】:

    首先是设计类,在 PunchWindow 的情况下,您必须有一个更新 txtDataField 的方法,并有一个将数据发送到 MainWindow 的信号。另一方面,在 MainWindow 中,每次按下按钮时,都必须使用最初提到的方法更新 txtDataField,然后在连接到 signalPassDataToMainForm 的插槽中,您必须区分相应的字段。

    import sys
    from functools import partial
    from PyQt5 import QtCore, QtWidgets, uic
    
    qtCreatorFile = "MainWinForm.ui"
    Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
    
    qtCreatorFileKeyPad = "NumPadForm.ui"
    Ui_KeyPad, QtBaseClass = uic.loadUiType(qtCreatorFileKeyPad )
    
    class PunchWindow(QtWidgets.QMainWindow, Ui_KeyPad):
        signalPassDataToMainForm = QtCore.pyqtSignal(str, str)
    
        def __init__(self, parent=None):
            super(PunchWindow, self).__init__(parent)
            self.setupUi(self)
            self.move(850, 200) #Center Screen
            buttons = (self.btnOne, self.btnTwo, self.btnThree, self.btnFour,
                self.btnFive, self.btnSix, self.btnSeven, self.btnEight,
                self.btnNine, self.btnZero, self.btnDot, self.btnBackSpace,
                self.btnClear)
            vals = (1, 2, 3, 4, 5, 6, 7, 8, 9, 0, ".", "BS", "Clear")
            for button, val in zip(buttons, vals):
                button.clicked.connect(partial(self.numberPad, val))
            self.btnEnter.clicked.connect(self.enter)
    
        @QtCore.pyqtSlot(str)
        def setCurrentField(self, text):
            self.txtDataField.setPlainText(text)
    
        def numberPad(self, n):
            strField = self.txtDataField.toPlainText()
            if strField in ("Field1", "Field2", "Field3"):
                strValue = self.txtDataToPass.toPlainText()
                strN = str(n)
                if strN == "BS":
                    self.txtDataToPass.setPlainText(strValue[:-1])
                elif strN == "Clear":
                    self.txtDataToPass.clear()
                else:        
                    strValue += strN 
                    self.txtDataToPass.setPlainText(strValue)
    
        @QtCore.pyqtSlot()
        def enter(self):
            strFieldNo = self.txtDataField.toPlainText()
            strSendData = self.txtDataToPass.toPlainText()
            self.signalPassDataToMainForm.emit(strFieldNo, strSendData)
    
    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
            self.move(450, 200) #Center Screen
            buttons = (self.btnField1, self.btnField2, self.btnField3)
            fields = ("Field1", "Field2", "Field3")
            for button, field in zip(buttons, fields):
                button.clicked.connect(partial(self.updatePunch, field))
            self.punch = PunchWindow()
            self.punch.signalPassDataToMainForm.connect(self.updateField)
    
        @QtCore.pyqtSlot(str, str)
        def updateField(self, strField, strData):
            if strField == "Field1":
                self.txtData1.setText(strData)
            elif strField == "Field2":
                self.txtData2.setText(strData)
            elif strField == "Field3":
                self.txtData3.setText(strData)
    
        @QtCore.pyqtSlot()
        def updatePunch(self, field):
            self.punch.setCurrentField(field)
            self.punch.show()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        MW = MainWindow()
        MW.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • @QtCore.pyqtSlot()
    • 感谢 eyllanesc -- 提供的解决方案有效!您回答了这个问题,还为我的代码风格提供了急需的指导。如果我可能还有另一个问题 - 您能否就何时或何时不使用 @QtCore.pyqtSlot() 提供一个简短的答复。谢谢
    • @dkuzdas 您实际上可以将它用于小部件的任何方法(通常是从 QObject 继承的任何类),但它用于连接到信号的方法。另一方面,如果我的回答对您有所帮助,请不要忘记将其标记为正确,如果您不知道该怎么做,请查看tour,这是最好的感谢方式。阅读pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多