如何从子类访问MainWindow.Widget?

问题描述 投票:-1回答:1

我有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_())
python pyqt pyqt5
1个回答
1
投票

“无法访问MainWindow.ui.label3”,因为label3不存在,ui也不存在。

[MainWindowclass,是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上使用这些类,请对使用“升级的小部件”进行一些研究。

© www.soinside.com 2019 - 2024. All rights reserved.