我刚开始使用PyQt;我正在尝试设置一个非常简单的MainWindow,其中包含3个行编辑和1个按钮。
以下是我想要得到的行为:
当两个第一个按钮的内容变得有效时,按钮就启用了。
当单击按钮时,将第二行编辑的内容重置为空刺,并禁用按钮。
下面是代码-视图代码是使用Qt和pyuic5生成的。
一切似乎都很好,除了用鼠标单击按钮时--行编辑的内容显示为未擦除(实际上是),而按钮看起来是启用的(实际上是禁用的)。如果触发窗口刷新(即最小化和恢复),则将正确显示窗口小部件。当使用键盘单击按钮时,将正确刷新所有内容。
我不知道是什么原因造成了这个奇怪的艺术品..。任何帮助都将不胜感激。
编辑我刚刚发现,只有当用enter键“单击”按钮时,它才能正常工作,如果使用空格,注意到同样有缺陷的行为.这让我想知道"enter“和任何其他点击的意思有什么区别?
提前谢谢你
主要python代码:
from PyQt5 import QtWidgets, QtCore
import sys
import view1
class Model(QtCore.QObject):
text1_changed = QtCore.pyqtSignal(str)
text2_changed = QtCore.pyqtSignal(str)
text3_changed = QtCore.pyqtSignal(str)
canprocess_changed = QtCore.pyqtSignal(bool)
def __init__(self):
super().__init__()
self._text1 = ''
self._text2 = ''
self._text3 = ''
self._canprocess = False
@property
def text1(self):
return self._text1
@text1.setter
def text1(self, value):
self._text1 = value
self.text1_changed.emit(value)
@property
def text2(self):
return self._text2
@text2.setter
def text2(self, value):
self._text2 = value
self.text2_changed.emit(value)
@property
def text3(self):
return self._text3
@text3.setter
def text3(self, value):
self._text3 = value
self.text3_changed.emit(value)
@property
def canprocess(self):
return self._canprocess
@canprocess.setter
def canprocess(self, value):
self._canprocess = value
self.canprocess_changed.emit(value)
class Controller(QtCore.QObject):
def __init__(self, model: Model):
super().__init__()
self._model = model
self._text1valid = False
self._text2valid = False
def istext1valid(self, text) -> bool:
return text[:3] == 'abc'
def istext2valid(self, text) -> bool:
return text[:3] == 'def'
def _validity_update(self):
self._model.canprocess = self._text1valid and self._text2valid
@QtCore.pyqtSlot(str)
def change_text1(self, text):
self._text1valid = self.istext1valid(text)
self._validity_update()
if self._text1valid:
self._model.text1 = text
@QtCore.pyqtSlot(str)
def change_text2(self, text):
self._text2valid = self.istext2valid(text)
self._validity_update()
if self._text2valid:
self._model.text2 = text
@QtCore.pyqtSlot(str)
def change_text3(self, text):
self._model.text3 = text
@QtCore.pyqtSlot()
def process(self):
# do real stuff
self._text2valid = False
self._validity_update()
self._model.text2 = ''
def init_view(self):
self._text1valid = False
self._text2valid = False
self._validity_update()
self._model.text1=''
self._model.text2=''
self._model.text3='an init value'
class MainAppWindow(QtWidgets.QMainWindow, view1.Ui_MainWindow):
def __init__(self, model: Model, controller: Controller):
super().__init__()
self._model = model
self._controller = controller
self.setupUi(self)
def setupUi(self, window):
super().setupUi(self)
self.bProceed.clicked.connect(self._controller.process)
self.ledit1.editingFinished.connect(lambda: self._controller.change_text1(self.ledit1.text()))
self.ledit2.editingFinished.connect(lambda: self._controller.change_text2(self.ledit2.text()))
self.ledit3.editingFinished.connect(lambda: self._controller.change_text3(self.ledit3.text()))
self._model.text1_changed.connect(self.ledit1.setText)
self._model.text2_changed.connect(self.ledit2.setText)
self._model.text3_changed.connect(self.ledit3.setText)
self._model.canprocess_changed.connect(self.bProceed.setEnabled)
self._controller.init_view()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainmodel = Model()
maincontroller = Controller(mainmodel)
MainWindow = MainAppWindow(mainmodel, maincontroller)
MainWindow.show()
sys.exit(app.exec_())生成的UI:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(435, 204)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.formLayout = QtWidgets.QFormLayout(self.centralwidget)
self.formLayout.setObjectName("formLayout")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setObjectName("label_2")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
self.ledit1 = QtWidgets.QLineEdit(self.centralwidget)
self.ledit1.setObjectName("ledit1")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.ledit1)
self.ledit2 = QtWidgets.QLineEdit(self.centralwidget)
self.ledit2.setObjectName("ledit2")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.ledit2)
self.bProceed = QtWidgets.QPushButton(self.centralwidget)
self.bProceed.setFocusPolicy(QtCore.Qt.StrongFocus)
self.bProceed.setDefault(True)
self.bProceed.setObjectName("bProceed")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.bProceed)
self.ledit3 = QtWidgets.QLineEdit(self.centralwidget)
self.ledit3.setObjectName("ledit3")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.ledit3)
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setObjectName("label_3")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 435, 22))
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)
MainWindow.setTabOrder(self.ledit1, self.ledit2)
MainWindow.setTabOrder(self.ledit2, self.bProceed)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label_2.setText(_translate("MainWindow", "Text2"))
self.label.setText(_translate("MainWindow", "Text1"))
self.bProceed.setText(_translate("MainWindow", "Proceed"))
self.label_3.setText(_translate("MainWindow", "Text3"))发布于 2020-06-28 07:39:41
从Mac的版本5.10开始,它就已经成为了PyQt5的一个已知缺陷,它影响到几乎所有内容以编程方式更改的小部件。
解决方案是对任何内容被更改的小部件进行子类,并显式调用repaint()。
举个例子,下面是我为按钮使用的代码:
class OSxPushButton(QtWidgets.QPushButton):
"""
A class to correct an OSX bug affecting widgets update when attributes are
programmatically modified.
"""
def __init__(self, parent=None):
super().__init__(parent)
def setEnabled(self, a0: bool) -> None:
super().setEnabled(a0)
self.repaint()https://stackoverflow.com/questions/62530793
复制相似问题