Как получить доступ к MainWindow.Widget из подкласса? - PullRequest
0 голосов
/ 03 мая 2020

У меня есть 3 Qlabels: label1, label2 и label3.

Моя идея такова: при наведении мыши на label1 или label2, label3.text будет показывать «мышь на label1» или «мышь на label2» в соответствии с на какую метку наведена мышь.

Я создал подкласс 'CustomLabel' для label1 и label2, где я определяю функцию 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_())

1 Ответ

1 голос
/ 03 мая 2020

«MainWindow.ui.label3 невозможно достичь», потому что label3 не существует и ui.

MainWindow является классом , «шаблон» для экземпляра .

Итак, у объекта MainWindow class нет атрибута с именем ui (следовательно, нет ui.label3 также), но mainWindow экземпляр , который вы создаете в конце кода, делает.

Для достижения того, что вы хотите, есть как минимум два метода .

Используйте сигналы / слоты для обеспечения связи между экземплярами

Создайте сигнал для класса 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)

Используйте фильтр событий для захвата событий

В этом случае мы устанавливаем фильтр событий на виджеты, которые мы Если вы хотите следить за событиями, и если это событие мыши, введите его, мы соответственно обновим третий ярлык:

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 из кода).
Read подробнее о использовании Designer , чтобы понять правильные способы использования файлов, созданных Designer.
Если вам нужно расширить виджеты Qt по умолчанию путем создания подклассов, и вам нужно использовать эти классы в Designer, проведите некоторое исследование о используя "продвигаемые виджеты".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...