QDialog 中 QLineEdit 小部件的奇怪行为,绑定按钮功能 [英] Strange behavior of QLineEdit widgets in QDialog, binding button function

查看:46
本文介绍了QDialog 中 QLineEdit 小部件的奇怪行为,绑定按钮功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 pyqt 编程的新手,所以也许我错了,但我发现 self.lineEdit 在 Enter 按下时调用按钮的功能,即使 self.handleKeyRelease 被注释.这是最少的代码,也是我发现这种奇怪行为的第一个地方.

self.lineEdit = QtGui.QLineEdit(self.frame)# self.lineEdit.keyReleaseEvent = self.handleKeyReleaseself.pushButton = QtGui.QPushButton(self.frame)self.pushButton.clicked.connect(lambda 事件:self._insertIntoCategories(db, self.lineEdit))

同样行为的第二位是动态制作的类似表单的小部件(一行中有一个 LineEdit 和 3 个按钮)

 self.lineEdit_2 = QtGui.QLineEdit(self.frame_3)self.lineEdit_2.setText(item[1])#  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -   堵塞  -  -  -  -  -  -------------------------------------- #self.pushButton_4 = QtGui.QPushButton(self.frame_3)self.pushButton_4.clicked.connect(lambda event, id=item[0], le=self.lineEdit_2: self.modal('edit', '你确定要重命名这个类别吗?', id, le))#  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -   堵塞  -  -  -  -  -  -------------------------------------- #self.pushButton_3 = QtGui.QPushButton(self.frame_3)self.pushButton_3.clicked.connect(lambda 事件,id=item[0]: self.__chIcon(id))#  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -   堵塞  -  -  -  -  -  -------------------------------------- #self.pushButton_2 = QtGui.QPushButton(self.frame_3)self.pushButton_2.clicked.connect(lambda event, id=item[0], le=self.lineEdit_2: self.modal('delete', '你确定要删除这个类别吗?', id, le))

这些按钮中的每一个都可以正常工作,但是 Enter 按下(或释放)上的每个条目都会再次调用前面部分代码的函数(self.pushButton 的函数) self._insertIntoCategories 如果这段代码不够用,还有完整的代码如果需要,在 github 上.

完全可执行的代码:

from PyQt4 import QtCore, QtGui尝试:_fromUtf8 = QtCore.QString.fromUtf8除了属性错误:def _fromUtf8(s):返回尝试:_encoding = QtGui.QApplication.UnicodeUTF8def _translate(context, text, disambig):返回 QtGui.QApplication.translate(context, text, disambig, _encoding)除了属性错误:def _translate(context, text, disambig):返回 QtGui.QApplication.translate(context, text, disambig)类 Ui_Form(对象):def setupUi(self):self.Form = QtGui.QDialog()形式 = self.FormForm.setObjectName(_fromUtf8("Form"))Form.resize(504, 550)self.verticalLayout = QtGui.QVBoxLayout(Form)self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))self.frame = QtGui.QFrame(Form)sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)sizePolicy.setHorizo​​ntalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())self.frame.setSizePolicy(sizePolicy)self.frame.setMinimumSize(QtCore.QSize(0, 50))self.frame.setStyleSheet(_fromUtf8("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 green, stop:1 white);"))self.frame.setFrameShape(QtGui.QFrame.StyledPanel)self.frame.setFrameShadow(QtGui.QFrame.Raised)self.frame.setObjectName(_fromUtf8("frame"))self.horizo​​ntalLayout_2 = QtGui.QHBoxLayout(self.frame)self.horizo​​ntalLayout_2.setObjectName(_fromUtf8("horizo​​ntalLayout_2"))self.horizo​​ntalLayout = QtGui.QHBoxLayout()self.horizo​​ntalLayout.setObjectName(_fromUtf8("horizo​​ntalLayout"))# -------------- 小部件定义的开始 -------------------------- ##这是第一个输入#self.lineEdit = QtGui.QLineEdit(self.frame)self.lineEdit.setObjectName(_fromUtf8("lineEdit"))self.horizo​​ntalLayout.addWidget(self.lineEdit)# 这是第一个按钮self.pushButton = QtGui.QPushButton(self.frame)self.pushButton.setMinimumSize(QtCore.QSize(50, 0))self.pushButton.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/add.png);background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, 停止:0 白色, 停止:1 白色);"))self.pushButton.setText(_fromUtf8(""))self.pushButton.setObjectName(_fromUtf8("pushButton"))self.pushButton.clicked.connect(lambda 事件:self.btnBehavior())self.horizo​​ntalLayout.addWidget(self.pushButton)# -------------- 小部件定义结束 -------------------------- #self.horizo​​ntalLayout_2.addLayout(self.horizo​​ntalLayout)self.verticalLayout.addWidget(self.frame)self.frame_2 = QtGui.QFrame(Form)sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)sizePolicy.setHorizo​​ntalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())self.frame_2.setSizePolicy(sizePolicy)self.frame_2.setStyleSheet(_fromUtf8("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 green, stop:1 white);"))self.frame_2.setFrameShape(QtGui.QFrame.StyledPanel)self.frame_2.setFrameShadow(QtGui.QFrame.Raised)self.frame_2.setObjectName(_fromUtf8("frame_2"))self.verticalLayout_2 = QtGui.QVBoxLayout(self.frame_2)self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))self.verticalLayout_3 = QtGui.QVBoxLayout()self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))self.frame_3 = QtGui.QFrame(self.frame_2)sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)sizePolicy.setHorizo​​ntalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())self.frame_3.setSizePolicy(sizePolicy)self.frame_3.setStyleSheet(_fromUtf8("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 white, stop:1 green);"))self.frame_3.setFrameShape(QtGui.QFrame.StyledPanel)self.frame_3.setFrameShadow(QtGui.QFrame.Raised)self.frame_3.setObjectName(_fromUtf8("frame_3"))self.horizo​​ntalLayout_3 = QtGui.QHBoxLayout(self.frame_3)self.horizo​​ntalLayout_3.setObjectName(_fromUtf8("horizo​​ntalLayout_3"))# -------------- 小部件定义的开始,第二行 -------------------------- ## 这是第二个输入self.lineEdit_2 = QtGui.QLineEdit(self.frame_3)sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)sizePolicy.setHorizo​​ntalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.lineEdit_2.sizePolicy().hasHeightForWidth())self.lineEdit_2.setSizePolicy(sizePolicy)self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2"))self.horizo​​ntalLayout_3.addWidget(self.lineEdit_2)#这是第二个、第三个和第四个按钮self.pushButton_4 = QtGui.QPushButton(self.frame_3)sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)sizePolicy.setHorizo​​ntalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.pushButton_4.sizePolicy().hasHeightForWidth())self.pushButton_4.setSizePolicy(sizePolicy)self.pushButton_4.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/edit.jpg);background-color: transparent;"))self.pushButton_4.setText(_fromUtf8(""))self.pushButton_4.clicked.connect(lambda 事件:self.btnBehavior())self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))self.horizo​​ntalLayout_3.addWidget(self.pushButton_4)self.pushButton_3 = QtGui.QPushButton(self.frame_3)self.pushButton_3.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/ch_pic.png); background-color: transparent;"))self.pushButton_3.setText(_fromUtf8(""))self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))self.pushButton_3.clicked.connect(lambda 事件:self.btnBehavior())self.horizo​​ntalLayout_3.addWidget(self.pushButton_3)self.pushButton_2 = QtGui.QPushButton(self.frame_3)self.pushButton_2.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/trash.png);background-color: transparent;"))self.pushButton_2.setText(_fromUtf8(""))self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))self.pushButton_2.clicked.connect(lambda 事件:self.btnBehavior())self.horizo​​ntalLayout_3.addWidget(self.pushButton_2)# -------------- 小部件定义结束 -------------------------- #self.verticalLayout_3.addWidget(self.frame_3)self.verticalLayout_2.addLayout(self.verticalLayout_3)SpacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)self.verticalLayout_2.addItem(spacerItem)self.verticalLayout.addWidget(self.frame_2)self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):Form.setWindowTitle(_translate("Form", "Form", None))self.pushButton_4.setToolTip(_translate("Form", "<html><head/><body><p>rename</p></body></html>", None))self.pushButton_3.setToolTip(_translate("Form", "<html><head/><body><p>picture</p></body></html>", None))self.pushButton_2.setToolTip(_translate("Form", "<html><head/><body><p>delete</p></body></html>", None))self.pushButton_2.setWhatsThis(_translate("Form", "<html><head/><body><p>delete</p></body></html>", None))def btnBehavior(self):打印('btn点击');如果 __name__ == "__main__":导入系统app = QtGui.QApplication(sys.argv)# Form = QtGui.QDialog()ui = Ui_Form()ui.setupUi()ui.Form.show()sys.exit(app.exec_())

解决方案

根据

I am new with programming in pyqt, so maybe i am wrong with this, but i have found that self.lineEdit on Enter pressed calls for button's function, even when self.handleKeyRelease is commented. This is minimum of code and first place where i have found that strange behavior.

self.lineEdit = QtGui.QLineEdit(self.frame)

# self.lineEdit.keyReleaseEvent = self.handleKeyRelease

self.pushButton = QtGui.QPushButton(self.frame)
self.pushButton.clicked.connect(lambda event: self._insertIntoCategories(db, self.lineEdit))

second place of this same behaviour are ,dynamically made, form-like widgets (there is one LineEdit and 3 buttons in a row)

        self.lineEdit_2 = QtGui.QLineEdit(self.frame_3)
        self.lineEdit_2.setText(item[1])    


        # ------------------------------------  block ------------------------------------------------- #

        self.pushButton_4 = QtGui.QPushButton(self.frame_3)       

        self.pushButton_4.clicked.connect(lambda event, id=item[0], le=self.lineEdit_2: self.modal('edit', 'Are you sure you want to rename this category ?', id, le))

        # ------------------------------------  block ------------------------------------------------- #

        self.pushButton_3 = QtGui.QPushButton(self.frame_3)

        self.pushButton_3.clicked.connect(lambda event, id=item[0]: self.__chIcon(id))


        # ------------------------------------  block ------------------------------------------------- #

        self.pushButton_2 = QtGui.QPushButton(self.frame_3)

        self.pushButton_2.clicked.connect(lambda event, id=item[0], le=self.lineEdit_2: self.modal('delete', 'Are you sure you want to delete this category ?', id, le))

each of this buttons works fine, but each entry on Enter press(or release) again calls for function from previous part of the code (self.pushButton's function) self._insertIntoCategories If this code is not sufficient, there is full code on github if needed.

fully executable code :

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):

    def setupUi(self):
        self.Form = QtGui.QDialog()
        Form = self.Form
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(504, 550)
        self.verticalLayout = QtGui.QVBoxLayout(Form)
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))

        self.frame = QtGui.QFrame(Form)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
        self.frame.setSizePolicy(sizePolicy)
        self.frame.setMinimumSize(QtCore.QSize(0, 50))
        self.frame.setStyleSheet(_fromUtf8("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0  green, stop:1 white);"))
        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtGui.QFrame.Raised)
        self.frame.setObjectName(_fromUtf8("frame"))

        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.frame)
        self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))

        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))

        # -------------- start of widget definitions -------------------------- #

        # THIS IS FIRTS INPUT #

        self.lineEdit = QtGui.QLineEdit(self.frame)
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.horizontalLayout.addWidget(self.lineEdit)

        # AND THIS IS FIRST BUTTON

        self.pushButton = QtGui.QPushButton(self.frame)
        self.pushButton.setMinimumSize(QtCore.QSize(50, 0))
        self.pushButton.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/add.png);background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 white, stop:1 white);"))
        self.pushButton.setText(_fromUtf8(""))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(lambda event: self.btnBehavior())
        self.horizontalLayout.addWidget(self.pushButton)

        # -------------- end of widget definitions -------------------------- #


        self.horizontalLayout_2.addLayout(self.horizontalLayout)

        self.verticalLayout.addWidget(self.frame)

        self.frame_2 = QtGui.QFrame(Form)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
        self.frame_2.setSizePolicy(sizePolicy)
        self.frame_2.setStyleSheet(_fromUtf8("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 green, stop:1 white);"))
        self.frame_2.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtGui.QFrame.Raised)
        self.frame_2.setObjectName(_fromUtf8("frame_2"))

        self.verticalLayout_2 = QtGui.QVBoxLayout(self.frame_2)
        self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))

        self.verticalLayout_3 = QtGui.QVBoxLayout()
        self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))

        self.frame_3 = QtGui.QFrame(self.frame_2)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
        self.frame_3.setSizePolicy(sizePolicy)
        self.frame_3.setStyleSheet(_fromUtf8("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 white, stop:1 green);"))
        self.frame_3.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_3.setFrameShadow(QtGui.QFrame.Raised)
        self.frame_3.setObjectName(_fromUtf8("frame_3"))

        self.horizontalLayout_3 = QtGui.QHBoxLayout(self.frame_3)
        self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))


        # -------------- start of widget definitions, second row -------------------------- #

        # THIS IS SECOND INPUT

        self.lineEdit_2 = QtGui.QLineEdit(self.frame_3)

        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.lineEdit_2.sizePolicy().hasHeightForWidth())
        self.lineEdit_2.setSizePolicy(sizePolicy)
        self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2"))

        self.horizontalLayout_3.addWidget(self.lineEdit_2)


        #THIS IS SECOND, THIRD AND FOURTH BUTTONS

        self.pushButton_4 = QtGui.QPushButton(self.frame_3)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_4.sizePolicy().hasHeightForWidth())
        self.pushButton_4.setSizePolicy(sizePolicy)
        self.pushButton_4.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/edit.jpg);background-color: transparent;"))
        self.pushButton_4.setText(_fromUtf8(""))
        self.pushButton_4.clicked.connect(lambda event: self.btnBehavior())
        self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))

        self.horizontalLayout_3.addWidget(self.pushButton_4)
        self.pushButton_3 = QtGui.QPushButton(self.frame_3)
        self.pushButton_3.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/ch_pic.png); background-color: transparent;"))
        self.pushButton_3.setText(_fromUtf8(""))
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.pushButton_3.clicked.connect(lambda event: self.btnBehavior())
        self.horizontalLayout_3.addWidget(self.pushButton_3)

        self.pushButton_2 = QtGui.QPushButton(self.frame_3)
        self.pushButton_2.setStyleSheet(_fromUtf8("border-image: url(imgs/required/btns/trash.png);background-color: transparent;"))
        self.pushButton_2.setText(_fromUtf8(""))
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_2.clicked.connect(lambda event: self.btnBehavior())
        self.horizontalLayout_3.addWidget(self.pushButton_2)

        # -------------- end of widget definitions -------------------------- #

        self.verticalLayout_3.addWidget(self.frame_3)
        self.verticalLayout_2.addLayout(self.verticalLayout_3)

        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)

        self.verticalLayout_2.addItem(spacerItem)
        self.verticalLayout.addWidget(self.frame_2)

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


    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.pushButton_4.setToolTip(_translate("Form", "<html><head/><body><p>rename</p></body></html>", None))
        self.pushButton_3.setToolTip(_translate("Form", "<html><head/><body><p>picture</p></body></html>", None))
        self.pushButton_2.setToolTip(_translate("Form", "<html><head/><body><p>delete</p></body></html>", None))
        self.pushButton_2.setWhatsThis(_translate("Form", "<html><head/><body><p>delete</p></body></html>", None))

    def btnBehavior(self):
        print('btn clicked');


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    # Form = QtGui.QDialog()
    ui = Ui_Form()
    ui.setupUi()
    ui.Form.show()
    sys.exit(app.exec_())

解决方案

According to the documentation:

autoDefault : bool

This property holds whether the push button is an auto default button

If this property is set to true then the push button is an auto default button.

In some GUI styles a default button is drawn with an extra frame around it, up to 3 pixels or more. Qt automatically keeps this space free around auto-default buttons, i.e., auto-default buttons may have a slightly larger size hint.

This property's default is true for buttons that have a QDialog parent; otherwise it defaults to false.

See the default property for details of how default and auto-default interact.

That is, this is the responsible property of this problem. The workaround is to set the autoDefault property to False for all QPushButtons.

To do it in a simple way I have restructured your code, to do this put the state of Qt Designer has generated and then implemented the logic that implements that design, given this is my proposed solution:

class Dialog(QtGui.QDialog, Ui_Form):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setupUi(self)

        for pb in self.findChildren(QtGui.QPushButton):
            pb.setAutoDefault(False)

        self.pushButton.clicked.connect(self.btnBehavior)

    def btnBehavior(self):
        print('btn clicked')

As @ekhumoro says you can do the same with Qt Designer, .

这篇关于QDialog 中 QLineEdit 小部件的奇怪行为,绑定按钮功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆