在PyQt / PySide生成的代码之外添加事件函数

时间:2014-02-27 14:22:25

标签: python function class qt-designer

我正在以不那么MVC的方式使用PySide,这意味着,我尽量不要编辑生成的.ui到.py文件,我把我的应用程序逻辑放在包(模型)中,我有一个模块(.pyw文件)更像是一个控制器,用于初始化和执行管理。不太好的练习,但我做得很好,我想要的是我不想在生成的ui .py文件中添加代码(更像我的观点)

现在问题是

我注意到生成的PySide文件没有从QDialog或QMainWindow继承,因为在实例化类时必须创建它,因此closeEvent(self, event)之类的事件在类中不起作用即使你把它放在那里。我知道要为QActions和widget连接编写函数,但我不知道如何在类之外添加一个基于类的函数到一个生成的PYSIDE类。

如果我必须编辑生成的视图类,我可以完美地将其调整到我想要的但我不想要因为我可以在QtDesigner中进行修改并随时编译

这是我的问题,因为我不想如何附加对我在控制器类中创建的对象说closeEvent而不触及生成的视图类。

谢谢

2 个答案:

答案 0 :(得分:0)

从不需要编辑由pyside-uic生成的ui模块。

从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)

其次,对于不是顶级的小部件,您可以使用event-filter,如下所示:

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。所有protected functions都有相应的event type,可以通过这种方式访问​​。

最后一种方法是小部件推广,设置起来比较复杂,但可能提供最大的灵活性。这允许您使用自己的自定义子类从Qt Designer完全替换小部件。

要执行此操作,请在Qt Designer中右键单击要替换的小部件,然后选择“提升为...”。在对话框中,将“Promoted class name”设置为自定义子类(例如“MyLineEdit”),并将“Header file”设置为包含子类的模块的python导入路径(例如“myapp”或“myapp.gui”) )。接下来,您将单击“添加”,然后单击“提升”,您将在“对象检查器”窗格中看到类从“QLineEdit”更改为“MyLineEdit”。

有了这个,您需要做的就是确保myapp模块包含一个MyLineEdit类,该类可以由pyside-uic生成的.ui模块导入。

答案 1 :(得分:0)

Monkey Patching完成了这项工作,我不知道为什么我没有教这个