我有3个Qlabel:label1,label2和label3。
我的想法是:当鼠标悬停在label1或label2上时,label3.text将根据鼠标悬停在哪个标签上显示'label1上的鼠标'或'label2上的鼠标'。
我为label1和label2创建了一个子类'CustomLabel',在其中定义了EnterEvent函数。
问题是我无法从该类访问label3。
MainWindow.ui.label3无法访问!
这里是代码,除了一行我无法设法访问label3的代码外,其他所有东西都在工作。
我是一个初学者,所以我可能缺少一些非常简单的东西。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(688, 446)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label1 = CustomLabel(self.centralwidget)
self.label1.setGeometry(QtCore.QRect(110, 110, 121, 31))
self.label1.setObjectName("label1")
self.label2 = CustomLabel(self.centralwidget)
self.label2.setGeometry(QtCore.QRect(320, 110, 121, 31))
self.label2.setObjectName("label2")
self.label3 = QtWidgets.QLabel(self.centralwidget)
self.label3.setGeometry(QtCore.QRect(190, 280, 121, 31))
self.label3.setObjectName("label3")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label1.setText(_translate("MainWindow", "Label1"))
self.label2.setText(_translate("MainWindow", "Label2"))
self.label3.setText(_translate("MainWindow", "Label3"))
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
class CustomLabel(QtWidgets.QLabel):
def __init__(self,texte):
Custom_font = QtGui.QFont()
Custom_font.setPointSize(14)
super(CustomLabel,self).__init__(texte)
self.setFont(Custom_font)
def enterEvent(self,e):
print('here is ',self.text())
MainWindow.ui.label3.setText('mouse on ', self.text) # Error on this line, 'MainWindow' has no attribute ui
#MainWindow.label3.setText('mouse on ', self.text) # Error here too, 'MainWindow' has no attribute label3
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
“无法访问MainWindow.ui.label3”,因为label3
不存在,ui
也不存在。
[MainWindow
是class,是instance的“模板”。]]
因此,MainWindow
class
ui
的属性(因此也没有ui.label3
),but在结尾处创建的mainWindow
instance您的代码。要实现您想要的,至少有两种方法。
为CustomLabel类创建一个信号,并在鼠标进入该信号时发出它;然后从主窗口连接该信号:
class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.label1.entered.connect(self.labelEntered) self.ui.label2.entered.connect(self.labelEntered) def labelEntered(self, label): self.ui.label3.setText('mouse on {}'.format(label.text())) class CustomLabel(QtWidgets.QLabel): entered = QtCore.pyqtSignal(object) def __init__(self,texte): Custom_font = QtGui.QFont() Custom_font.setPointSize(14) super(CustomLabel,self).__init__(texte) self.setFont(Custom_font) def enterEvent(self,e): self.entered.emit(self)
使用事件过滤器捕获事件
在这种情况下,我们在要监视事件的小部件上单击install an event filter,如果该事件是鼠标,请输入一个,我们将相应地更新第三个标签:
class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.label1.installEventFilter(self) self.ui.label2.installEventFilter(self) def eventFilter(self, source, event): if isinstance(source, CustomLabel) and event.type() == QtCore.QEvent.Enter: # the "source" of the event is one of our custom labels, and the event # type is an "Enter" one, so let's update the other label self.ui.label3.setText('mouse on {}'.format(source.text())) return super(MainWindow, self).eventFilter(source, event)
作为旁注,似乎您正在尝试编辑从
pyuic
生成的文件的内容(或者至少您正在尝试模仿它们的行为)。这是绝对不应该做的事情,因为这些文件仅打算在实际程序中用作导入的模块(并且模仿它们的行为不是从代码创建GUI的最佳方法)。阅读有关using Designer的更多信息,以了解使用Designer创建的文件的正确方法。如果您需要通过子类扩展默认的Qt小部件,并且需要在Designer上使用这些类,请对使用“升级的小部件”进行一些研究。