首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PyQt5中用uic.loadUI()重新定义(覆盖)方法

在PyQt5中用uic.loadUI()重新定义(覆盖)方法
EN

Stack Overflow用户
提问于 2019-03-18 11:44:01
回答 2查看 1.7K关注 0票数 1

实际上,从几个星期以来,我就在使用PyQt5和QtDesigner开发一个小型软件。我已经看了很多tutos,并在上面寻找了很多答案,但是我找不到关于使用uic.loadUI()重写QWidget方法的方法的答案。

请注意,我已经尽可能地简化了测试代码,以精确地指出我的问题所在:

1/这个不工作,它正确地加载了我的file.ui,但是单击没有做任何事情:

代码语言:javascript
复制
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]但我发现这一条实际上是起作用的:

代码语言:javascript
复制
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方法来重新定义它,或者简单地创建我自己的方法来捕捉任何事件,但是我尝试的一切都失败了。

无论如何,提前感谢你的回答/提示/祈祷。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-18 15:01:14

假设在创建file.ui时使用Widget模板:

然后,解决方案如下:

代码语言:javascript
复制
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仍然是win窗口的一个属性,从未显示过,在uic.loadUi("file.ui", self)的情况下,您要指出的是,它不是创建窗口,而是填充现有的窗口。

更新:

根据您得到的错误:

代码语言:javascript
复制
TypeError: ('Wrong base class of toplevel widget', (<class '__main__.Window'>, 'QMainWindow'))

它允许我推断出您没有使用QWidget作为基础,而是使用QMainWindow,因此窗口必须从QMainWindow继承:

代码语言:javascript
复制
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_()
票数 2
EN

Stack Overflow用户

发布于 2020-04-29 13:07:56

我的方法是在Qt对象检查器中使用Promote to...上下文菜单项。

这允许您在设计器中指定特定的小部件应该使用在图形构建器中所推送的子类。uic.loadUi会遵守这一点。

假设您在my_graphics_view.py中有一个my_graphics_view.py。您可以放置一个QGraphicsView,然后选择Promote to...并输入以下内容:

  • 基类名称:(预填充到QGraphicsView)
  • 提升类名:MyGraphicsView
  • 头文件:my_graphics_view.h (loadUi将为您调整扩展名)

...then点击“添加”,然后“推广”,你就完成了。

我只注意到两个注意事项:

  1. 据我所知,在构建子部件树之前,在使用setupUi__init__返回时没有uic.loadUi方法,因此,如果您想在__init__之后运行任何自定义代码,您必须将它放在一个名为widget.configure_children()的方法中,并在调用widget = uic.loadUi(...)之后自己调用它。
  2. 由于我不知道的原因,我从KubuntuLinux16.04LTS中使用的Qt Designer 5.5.1的副本不提供QMainWindow,因为它是在“推广”对话框的已知小部件下拉列表中提供的。 但是,如果编辑.ui文件,Qt设计器和loadUi都不会出现问题。就像看上去的那样..。下拉小部件中的一个神秘的遗漏,仅此而已。

下面是原始.ui文件中的样子:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
  <class>MainWindow</class>
  <widget class="MyMainWindow" name="MainWindow">
    <!-- ... --->
  </widget>
  <customwidgets>
    <customwidget>
      <class>MyMainWindow</class>
      <extends>QMainWindow</extends>
      <header>my_main_window.h</header>
    </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
</ui>

同样重要的是,根据此页,与uic.loadUi等价的PySide2将父类作为第二个参数,而不是自定义子类,因此您基本上不得不在PySide2下使用这种方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55220600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档