QlineEdit 和信号&槽

Posted

技术标签:

【中文标题】QlineEdit 和信号&槽【英文标题】:QlineEdit and signal & slot 【发布时间】:2018-09-08 18:26:55 【问题描述】:

我用QLineEditQLabel 创建了一个小部件,我想从QlineEdit 获取输入并用QLabel 显示它。我使用了信号和插槽连接,我不知道我做错了什么,但它不能正常工作。我想从QLineEdit 获取这两个值,然后再显示。

当前窗口

我想要什么?

代码:

import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class WinDialog(QtWidgets.QDialog):

    currenttextedited = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super(WinDialog, self).__init__(parent)

        self.setGeometry(300,300,350,300)

        self.setWindowTitle("Signal & Slot")

        self.propertyWidget = PropertyWidget()

        section_lay = QtWidgets.QHBoxLayout()
        section_label = QtWidgets.QLabel("Name: ")
        section_edit = QtWidgets.QLineEdit('')

        length_lay = QtWidgets.QHBoxLayout()
        length_label = QtWidgets.QLabel("Input a number:     L = ")
        self.length_edit = QtWidgets.QLineEdit('1000')
        self.length_edit.setInputMask("999999")
        self.length_edit.setFocus(True)

        thick_lay = QtWidgets.QHBoxLayout()
        thick_label = QtWidgets.QLabel("Input a text: T = ")
        thick_edit = QtWidgets.QLineEdit('')

        section_lay.addWidget(section_label)
        section_lay.addWidget(section_edit)

        length_lay.addWidget(length_label)
        length_lay.addWidget(self.length_edit)
        length_lay.addStretch()

        thick_lay.addWidget(thick_label)
        thick_lay.addWidget(thick_edit)
        thick_lay.addStretch()

        VB_lay = QtWidgets.QVBoxLayout()
        VB_lay.addStretch()
        VB_lay.addLayout(length_lay)
        VB_lay.addLayout(thick_lay)
        VB_lay.addStretch()

        buttonBox = QtWidgets.QDialogButtonBox()

        buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel
        |QtWidgets.QDialogButtonBox.Ok)
        buttonBox.accepted.connect(self.accept) 
        buttonBox.rejected.connect(self.reject)

        grid = QtWidgets.QGridLayout(self)
        grid.addLayout(section_lay, 0, 0, 1, 2)
        grid.addLayout(VB_lay, 1, 0)
        grid.addWidget(self.propertyWidget, 2, 0)
        grid.addWidget(buttonBox, 3, 0, 1, 2)



        self.length_edit.textEdited.connect(self.textchanged)

    def textchanged(self, text):
        print(text)
        self.currenttextedited.emit(text)

class PropertyWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
       super(PropertyWidget, self).__init__(parent)        
       HB_lay = QtWidgets.QHBoxLayout(self)
       self.Displaylabel = QtWidgets.QLabel('')
       HB_lay.addWidget(self.Displaylabel)
       HB_lay.addStretch()



@QtCore.pyqtSlot(int)
def Display(self, text):
    try:
        L_Display = int(text)
        T_Display = int(text) 
        fmt = "L = mm\nT = mm"
        self.Displaylabel.setText(fmt.format(L_Display, T_Display))
    except ValueError:
        print("Error")        


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

【问题讨论】:

【参考方案1】:

根据图像中的示例,您希望显示不同的文本,但您将相同的数字转换为整数:L_Display = int(text)T_Display = int(text) 那么您希望如何显示 2 个不同的文本?,显然功能显示需要 2条目(self 的两个不同条目加上我已更改为小写,因为建议函数具有小写名称)。

现在的逻辑如下:如果length_edit 或thick_edit 的任何文本发生变化,那么您必须调用display() 传递新文本。所以解决方案是使用一个槽,连接QLineEdits的textEdited信号,并在其中获取文本并传递文本。

最后我看到你希望QLineEdits 只接收数字,所以一个选择是使用QIntValidator,以便只接受数字(另一个更好的选择是使用QSpinBox 而不是QLineEdit

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class WinDialog(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(WinDialog, self).__init__(parent)

        self.setGeometry(300,300,350,300)
        self.setWindowTitle("Signal & Slot")

        self.propertyWidget = PropertyWidget()

        section_lay = QtWidgets.QHBoxLayout()
        section_label = QtWidgets.QLabel("Name: ")
        section_edit = QtWidgets.QLineEdit('')

        length_lay = QtWidgets.QHBoxLayout()

        length_label = QtWidgets.QLabel("Input a number:     L = ")
        self.length_edit = QtWidgets.QLineEdit()
        self.length_edit.setFocus(True)
        val_lenght = QtGui.QIntValidator(0, 100000, self.length_edit)
        self.length_edit.setValidator(val_lenght)

        thick_lay = QtWidgets.QHBoxLayout()
        thick_label = QtWidgets.QLabel("Input a text: T = ")
        self.thick_edit = QtWidgets.QLineEdit()
        val_thick = QtGui.QIntValidator(0, 100000, self.thick_edit)
        self.thick_edit.setValidator(val_thick)

        section_lay.addWidget(section_label)
        section_lay.addWidget(section_edit)

        length_lay.addWidget(length_label)
        length_lay.addWidget(self.length_edit)
        length_lay.addStretch()

        thick_lay.addWidget(thick_label)
        thick_lay.addWidget(self.thick_edit)
        thick_lay.addStretch()

        VB_lay = QtWidgets.QVBoxLayout()
        VB_lay.addStretch()
        VB_lay.addLayout(length_lay)
        VB_lay.addLayout(thick_lay)
        VB_lay.addStretch()

        buttonBox = QtWidgets.QDialogButtonBox()

        buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel
            | QtWidgets.QDialogButtonBox.Ok)
        buttonBox.accepted.connect(self.accept) 
        buttonBox.rejected.connect(self.reject)

        grid = QtWidgets.QGridLayout(self)
        grid.addLayout(section_lay, 0, 0, 1, 2)
        grid.addLayout(VB_lay, 1, 0)
        grid.addWidget(self.propertyWidget, 2, 0)
        grid.addWidget(buttonBox, 3, 0, 1, 2)

        self.length_edit.textEdited.connect(self.onTextEdited)
        self.thick_edit.textEdited.connect(self.onTextEdited)

    def onTextEdited(self):        
        l = self.length_edit.text()
        t = self.thick_edit.text()
        self.propertyWidget.display(l, t)

class PropertyWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
       super(PropertyWidget, self).__init__(parent)        
       HB_lay = QtWidgets.QHBoxLayout(self)
       self.Displaylabel = QtWidgets.QLabel('')
       HB_lay.addWidget(self.Displaylabel)
       HB_lay.addStretch()

    def display(self, l, t):
        try:
            L_Display = int(l)
            T_Display = int(t) 
            fmt = "L = mm\nT = mm"
            self.Displaylabel.setText(fmt.format(L_Display, T_Display))
        except ValueError:
            self.Displaylabel.clear()       


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

【讨论】:

@ZarKha 如果我的回答对您有帮助,请不要忘记将其标记为正确,如果您不知道该怎么做,请查看tour,这是最好的感谢方式。另一方面,不要编辑我的答案,如果您有任何与我的解决方案相关的问题,请编辑您的问题并添加必要的内容以表明您对哪一部分有一些不便。 感谢您的快速回复。现在可以了。关于上面的 cmets,我很清楚,我有不同的文本,应该有 2 个不同的条目,函数会收到。在函数构造中获取length_edit 和thick_edit 文本背后的想法是一个绝妙的解决方案。我在其他一些脚本中坦率地创建了类似的调用函数,但我面临和挑战困难,让我忽略了它。

以上是关于QlineEdit 和信号&槽的主要内容,如果未能解决你的问题,请参考以下文章

Qt - QLineEdit编辑框

QLineEdit 单击时清除文本并从按钮读取文本[关闭]

qt自定义信号和槽函数 emit

Python PyQt5:如果 QLineEdit 为空,如何更改 QLabel 的颜色?

QT4 设计器在信号/槽编辑器中不接受“&”引用和“”空格字符

自定义信号槽发生重载的解决办法