为了账号安全,请及时绑定邮箱和手机立即绑定

拖放小部件实现错误 - RuntimeWarning:

拖放小部件实现错误 - RuntimeWarning:

开心每一天1111 2023-10-05 17:36:15
这是我为此创建的自定义小部件:from PySide2.QtCore import *from PySide2.QtWidgets import *from PySide2.QtGui import *import osclass DragDropWidget(QWidget):    def __init__(self, parent=None):        super(DragDropWidget, self).__init__(parent)        self.setAcceptDrops(True)    def dragEnterEvent(self, event):        if event.mimeData().hasUrls:            event.accept()        else:            event.ignore()    def dragMoveEvent(self, event):        if event.mimeData().hasUrls:            if len(event.mimeData().urls()) != 1:                event.ignore()            else:                event.setDropAction(Qt.CopyAction)                event.accept()        else:            event.ignore()    def dropEvent(self, event):        if event.mimeData().hasUrls:            event.setDropAction(Qt.CopyAction)            event.accept()            if len(event.mimeData().urls()) != 1:                event.ignore()            else:                url = event.mimeData().urls()[                    0].toLocalFile()                if os.path.exists(url):                    self.emit(SIGNAL("dropped"), url)        else:            event.ignore()我可以从 dropEvent 函数打印出文件的位置,但无法使用 connect 从主函数访问它。我的主要功能有以下几行:self.connect(self.ui.DragDropEncode, SIGNAL("dropped"), self.add_file)def add_file(self, file):    print(file)我已经使用以下命令从另一个文件导入了我的用户界面:from Main_UI import Ui_MainWindow我有这个小部件的以下代码:   self.DragDropEncode = DragDropWidget(self.AddFileEncode)   self.DragDropEncode.setAcceptDrops(True)当我运行主文件时,出现以下错误:main.py:55: RuntimeWarning: MetaObjectBuilder::addMethod: Invalid method signature provided for "dropped"  self.connect(self.ui.DragDropEncode, SIGNAL("dropped"), self.add_file)此外,删除文件绝对没有任何作用。我仍然不明白为什么会出现这个错误。任何帮助将非常感激。谢谢你!
查看完整描述

1 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

使用SIGNAL()宏多年来一直被认为是过时的,并且“新样式”信号和槽语法必须始终用于新代码。

此外,SIGNAL 语法应该始终有一个(可能为空)参数类型列表作为其签名。PyQt 过去支持所谓的“短路信号”,它允许将没有正确签名的自定义信号连接到 python 可调用对象,并且可以发出具有任意数量和类型参数的信号。通过使用不带括号的信号可以实现这一点。

如前所述,此语法已过时,并且 pyside 还删除了对这些短路信号的支持,如PySide 和 PyQt 之间的差异页面中所述:

由于这是一个旧的且已弃用的功能,并且修复此问题的努力不值得,因此我们决定不实现它。在 PySide 代码中,您需要使用类似以下内容:

self.emit(SIGNAL ('text_changed_cb(QString)'), text)

在你的情况下,由于你没有使用参数,所以它应该是这样的:

self.connect(self.ui.DragDropEncode, SIGNAL("dropped()"), self.add_file)

但是,如前所述,这是一个古老且已弃用的功能(而且也太冗长且不太Pythonic)。

解决方案是为类创建信号并直接发出它们:

class DragDropWidget(QWidget):

    dropped = Signal(str)

    # ...


    def dropEvent(self, event):

        # ...

        self.dropped.emit(url)

然后将实例的信号连接到插槽:


self.ui.DragDropEncode.dropped.connect(self.add_file)

请注意,发出信号时必须遵守参数签名。在上面的情况下,根据您的代码,我假设您将 mimeData 的 QUrl 转换为字符串。如果您需要发出 QUrl,信号必须反映:


class DragDropWidget(QWidget):

    dropped = Signal(QUrl)

或者,有两种可能性:您可以使用允许发出任何类型的参数 ( ) 的通用 签名,或使用信号重载。在这种情况下,您可以使用能够发出各种参数长度和类型的单个信号。在这种情况下,将使用第一个重载作为默认值,而其他重载必须用方括号选择:objectdropped = Signal(object)emit


class DragDropWidget(QWidget):

    dropped = Signal([str], [QUrl])


    # ...


    def dropEvent(self, event):

        # ...

        url = event.mimeData().urls()[0]

        self.dropped.emit(url.toLocalFile())

        self.dropped[QUrl].emit(url)

如果您需要根据信号签名连接到不同的插槽,这会很有用:


    self.ui.DragDropEncode.dropped.connect(self.function_that_uses_strings)

    self.ui.DragDropEncode.dropped[QUrl].connect(self.function_that_uses_urls)


查看完整回答
反对 回复 2023-10-05
  • 1 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信