Добавление функций событий вне сгенерированного кода PyQt/PySide

Я использую PySide не так, как MVC, то есть я стараюсь, насколько это возможно, не редактировать сгенерированный файл .ui в .py, я помещаю логику своего приложения в пакеты (модели) и у меня есть один модуль (. pyw) больше похож на контроллер для их всех для инициализации и управления. Не слишком лучшая практика, но у меня все хорошо, все, что я хочу, это не добавлять код в сгенерированный файл ui .py (больше похоже на мой взгляд)

Теперь вот проблема

Я заметил, что сгенерированный файл PySide не наследуется от QDialog или QMainWindow, так как вы должны создать его при создании экземпляра класса, в результате чего такие события, как closeEvent(self, event), не работают внутри класса, даже когда вы его туда помещаете. Я знаю, как писать функции для QActions и соединений с виджетами, но я НЕ ЗНАЮ, КАК ДОБАВИТЬ ФУНКЦИЮ НА ОСНОВЕ КЛАССА В СОЗДАННЫЙ КЛАСС PYSIDE ВНЕ КЛАССА.

Если мне нужно отредактировать сгенерированный класс представления, я могу идеально настроить его так, как я хочу, НО я не хочу, потому что я могу внести изменения в QtDesigner и скомпилировать в любое время.

Это мой вопрос, так как я не хочу, как мне прикрепить, скажем, closeEvent к объекту, созданному из класса в моем классе контроллера, не касаясь сгенерированного класса представления.

Спасибо


person Temitayo    schedule 27.02.2014    source источник


Ответы (2)


никогда нет необходимости редактировать модуль пользовательского интерфейса, сгенерированный pyside-uic.

Существует три основных метода добавления функциональности уровня класса к виджетам из Qt Designer. Во-первых, для виджета верхнего уровня вы можете просто создать подкласс, например:

from PyQt4 import QtCore, QtGui
from mainwindow_ui import Ui_MainWindow

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow().setupUi(self)

    def closeEvent(self, event):
        print('Goodbye world!')
        QtGui.QMainWindow.closeEvent(self, event)

Во-вторых, для виджетов не верхнего уровня можно использовать событие- фильтр, например:

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        ...
        self.lineEdit.installEventFilter(self)

    def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.MouseMove and
            source is self.lineEdit):
            print('mouse-move:', event.globalPos())
        return QtGui.QMainWindow.eventFilter(self, source, event)

Таким образом, вместо повторной реализации mouseMoveEvent в подклассе QLineEdit вы можете прослушивать те же события через фильтр событий. Все защищенные функции имеют соответствующий тип события, доступ к которому можно получить таким образом.

Последний метод — продвижение виджетов, который сложнее настроить, но, пожалуй, дает наибольшую гибкость. Это позволяет вам полностью заменить виджеты из Qt Designer вашими собственными подклассами.

Для этого в Qt Designer вы должны щелкнуть правой кнопкой мыши виджет, который хотите заменить, и выбрать «Повысить до…». В диалоговом окне установите «Promoted class name» для вашего пользовательского подкласса (например, «MyLineEdit») и установите «Header file» для пути импорта python для модуля, содержащего подкласс (например, «myapp» или «myapp.gui» ). Затем вы должны нажать «Добавить», а затем «Повысить», и вы увидите, что класс изменится с «QLineEdit» на «MyLineEdit» на панели инспектора объектов.

После этого все, что вам нужно сделать, это убедиться, что модуль myapp содержит класс MyLineEdit, который может быть импортирован модулем .ui, сгенерированным pyside-uic.

person ekhumoro    schedule 27.02.2014

Monkey Patching сделал свое дело, я не знаю, почему я не учил об этом

person Temitayo    schedule 28.02.2014