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

这是我为此创建的自定义小部件:


from PySide2.QtCore import *

from PySide2.QtWidgets import *

from PySide2.QtGui import *

import os


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

此外,删除文件绝对没有任何作用。


我仍然不明白为什么会出现这个错误。任何帮助将非常感激。谢谢你!


开心每一天1111
浏览 95回答 1
1回答

慕容森

使用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)emitclass 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python