Переопределить (переопределить) методы в PyQt5 с помощью uic.loadUI () - PullRequest
1 голос
/ 18 марта 2019

Я на самом деле разрабатываю небольшой софт, используя PyQt5 и QtDesigner, уже несколько недель.Я просмотрел много tutos и искал много ответов на SO, но не могу найти тот, который касается способа переопределения метода QWidget с помощью uic.loadUI ().

Обратите внимание, что я упростилстолько, сколько я мог в своем тестовом коде указать точно, где моя проблема:

1 / Этот не работает, он корректно загружает мой file.ui, но нажатие ничего не дает:

import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget

class Window(QWidget):
    def __init__(self):
        super().__init__() # Or QWidget.__init__(self)
        self.dlg = uic.loadUi("file.ui")
        self.dlg.show()

    def mousePressEvent(self, event):
        print("click !")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    app.exec_()

2 / Но я выяснил, что это на самом деле работает:

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle("My window")
        self.show()

    def mousePressEvent(self, event):
        print("click !")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    app.exec_()

Так что, как я вижу, это потому, что я не могу переопределить метод события.Из-за того, что mousePressEvent не является методом, присоединенным к моему подклассу QWidget self.dlg.

Теперь, когда я знаю почему, я хотел бы знать, как я могу переопределить метод mousePressEvent и использовать его.Я задавался вопросом о «загрузке» метода после его переопределения, или вызове метода QWidget для его переопределения, или просто создании собственного метода для перехвата любого события, но все, что я пытался полностью потерпеть неудачу.

Во всяком случае, спасибо взаранее за ваши ответы / советы / молитвы.

1 Ответ

2 голосов
/ 18 марта 2019

Предполагая, что при создании file.ui вы используете шаблон виджета:

enter image description here

Тогда решение будет следующим:

import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget

class Window(QWidget):
    def __init__(self):
        super().__init__()
        uic.loadUi("file.ui", self)
        self.show()

    def mousePressEvent(self, event):
        print("click !")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    app.exec_()

Почему это не сработало при использовании self.dlg = uic.loadUi("file.ui")? Поскольку, как вы указали, был создан виджет is self.dlg, который все еще является атрибутом окна выигрыша, которое никогда не былопоказано, что в случае uic.loadUi("file.ui", self) вы указываете, что оно не создает окно, а заполняет существующее окно

Обновление:

В зависимости от полученной ошибки:

TypeError: ('Wrong base class of toplevel widget', (<class '__main__.Window'>, 'QMainWindow'))

Это позволяет мне сделать вывод, что вы использовали не QWidget в качестве основы, а QMainWindow, поэтому Window должен наследоваться от QMainWindow:

import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("file.ui", self)
        self.show()

    def mousePressEvent(self, event):
        print("click !")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    app.exec_()
...