【问题标题】:How to override PySide2 widget's method generated by Qt Designer?如何覆盖 Qt Designer 生成的 PySide2 小部件的方法?
【发布时间】:2021-07-02 19:08:47
【问题描述】:

我正在尝试通过在 powertoys 中创建类似 powerrename 工具的模拟可执行文件来学习 PySide2。

成功加载 Ui_PowerRenameDialog 后,该对话框由 Qt Designer 创建的 .ui 文件生成。

我遇到了一个错误试图完成一项功能,该功能可以让用户将文件从 Windows 资源管理器拖放到 .ui 文件中嵌入的 QTreeWidget

这是我的完整代码:

import sys
from PySide6 import QtWidgets
from PySide6 import QtCore
from ui_powerRename import Ui_PowerRenameDialog

class MyPowerRenameDialog(QtWidgets.QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)

        self.ui = Ui_PowerRenameDialog()
        self.ui.setupUi(self)

        self.modify_ui()
        self.create_connections()


    def modify_ui(self):
        self.ui.previewTreeWidget.setAcceptDrops(True)

        def dragEnterEvent(self,evt):
            if evt.mimeData().hasUrls():
                evt.accept()
            else:
                evt.ignore()

        def dropEvent(self,evt):
            for url in evt.mimeData().urls():
                newItem = QtWidgets.QTreeWidgetItem(url)
                self.addTopLevelItem(newItem)

        self.ui.previewTreeWidget.dragEnterEvent = dragEnterEvent
        self.ui.previewTreeWidget.dropEvent = dropEvent

        items = QtWidgets.QTreeWidgetItemIterator(self.ui.previewTreeWidget)
        for item in items:
            item.value().setFlags(item.value().flags()|QtCore.Qt.ItemIsUserCheckable)
            item.value().setCheckState(0,QtCore.Qt.Checked)

    def create_connections(self):
        self.ui.cancelButton.clicked.connect(self.close)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    window = MyPowerRenameDialog()
    window.show()

    sys.exit(app.exec_())

================================================ =================

这是我目前取得的成果(红色区域是 QTreeWidget): 可执行快照:

如您所见,我尝试重载 QTreeWidget 对象的 dragEnterEventdropEvent 方法。 覆盖代码中最重要的部分如下所示:

def dragEnterEvent(self,evt):
    if evt.mimeData().hasUrls():
        evt.accept()
    else:
        evt.ignore()
def dropEvent(self,evt):
    for url in evt.mimeData().urls():
        newItem = QtWidgets.QTreeWidgetItem(url)
        self.addTopLevelItem(newItem)

self.ui.previewTreeWidget.dragEnterEvent = dragEnterEvent
self.ui.previewTreeWidget.dropEvent = dropEvent

================================================ ================

问题是在尝试将任何内容从资源管理器拖放到 QTreeWidget 实例时,我遇到了 TypeError

TypeError: dragEnterEvent() missing 1 required positional argument: 'evt'.

我试图搜索类似的问题。一个可能的解决方案是使用 installEventFilter。但它只会导致更多错误。

我的意思是 PySide2 文档真的很乱,我无法从他们格式不正确的文档中获得任何有用的信息。

文档中的例子很少。而且大部分都是直接从C++版本复制过来的,甚至没有改成Python语法。

知道如何实现该功能吗?

有没有推荐的学习 PySide2 的方法?

【问题讨论】:

    标签: python pyside6


    【解决方案1】:

    错误来自dragEnterEventdropEvent没有绑定到一个类(因为它们嵌套在另一个函数中),这意味着self不是自动的,这就是为什么当它被调用时它需要两个参数,selfevt,但 Qt 框架只传递了evt

    要修改Ui_PowerRenameDialog 的行为,您应该创建Ui_PowerRenameDialog 的子类并在该子类中实现两个事件方法

    【讨论】:

    • 我已经尝试过了,不会有任何错误。但是当将某些东西拖到视图时,只会出现一个未经许可的图标,表明该功能未正确实现。
    • 我想知道,如果没有 self 指向 QTreeWidget 实例,如何访问 dropEventaddTopLevelItem(newItem) 方法/b> 方法。
    • 对不起,我没有正确阅读你的问题,我修改了我的答案
    • 谢谢,我意识到猴子修补方法不适合覆盖小部件的方法,我将创建自己的子类并使用 Qt Designer 中的提升功能。您的回答真的很有帮助,谢谢。
    • 很高兴我能帮上忙
    猜你喜欢
    • 2019-02-07
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    相关资源
    最近更新 更多