这是我为此创建的自定义小部件:
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)
我已经使用以下命令从另一个文件导入了UI:
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)
此外,删除文件绝对没有任何作用。
我仍然不明白为什么会发生此错误。任何帮助将非常感激。谢谢!
这是一个最小的可重现示例:
main.py
# Importing The Required Modules
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *
import sys
# Importing the GUI file
from Problematic import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Connects to the "DragDrop" Widget defined in the GUI file
self.connect(self.ui.DragDrop, SIGNAL("dropped"), self.add_file)
self.show()
def add_file(self, file):
# Just some debugging. Not working from this end.
print("Signal Recieved:", file)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
有问题的
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'Problematic.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PySide2 import QtCore, QtGui, QtWidgets
from DragDropWidget import DragDropWidget
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.Frame = QtWidgets.QFrame(self.centralwidget)
self.Frame.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(158, 7, 23, 255), stop:1 rgba(255, 130, 20, 255));")
self.Frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.Frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.Frame.setObjectName("Frame")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.Frame)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.DragDrop = DragDropWidget(self.Frame)
self.DragDrop.setAcceptDrops(True)
self.DragDrop.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0.248473, y1:0.483, x2:1, y2:0, stop:0.208955 rgba(131, 62, 40, 22), stop:1 rgba(163, 13, 23, 0));\n"
"border: 2px dashed rgba(85, 85, 85, 95);")
self.DragDrop.setObjectName("DragDrop")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.DragDrop)
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_3.setSpacing(0)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.Text = QtWidgets.QLabel(self.DragDrop)
font = QtGui.QFont()
font.setFamily("Microsoft Sans Serif")
font.setPointSize(80)
font.setItalic(True)
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
self.Text.setFont(font)
self.Text.setAlignment(QtCore.Qt.AlignCenter)
self.Text.setObjectName("Text")
self.horizontalLayout_3.addWidget(self.Text)
self.horizontalLayout_2.addWidget(self.DragDrop)
self.horizontalLayout.addWidget(self.Frame)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.Text.setText(_translate("MainWindow", "Drag & Drop\n"
"Files Here"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
DragDropWidget.py
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *
import os
class DragDropWidget(QWidget):
def __init__(self, type, 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)
# Just Some Debugging, Working from this end
print("Signal Emitted:", url)
else:
event.ignore()
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)
但是,正如所说的,这是一个过时的,过时的功能(也太冗长,不是很Python语言)。
解决方案是为该类创建信号并直接发出它们:
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)
或者,有两种可能性:您可以使用允许发出任何类型的参数()的通用 object
签名,或使用信号重载。在这种情况下,您可以使用单个信号,该信号能够发出具有各种参数长度和类型的信号。在这种情况下,将默认使用第一个重载,而其他重载必须使用方括号选择:dropped = 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)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句