PyQt/PySide(包装的 C/C++ 对象已被删除)
PyQt/PySide (wrapped C/C++ object has been deleted)
如果我运行这个代码:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(200,200,800,400)
self.mainWindowWidget = QWidget()
self.setCentralWidget(self.mainWindowWidget)
self.mainWindowLayout = QGridLayout()
self.mainWindowWidget.setLayout(self.mainWindowLayout)
self.DnD = DragnDrop()
self.DnD.setAcceptDrops(True)
self.DnD.setAlignment(Qt.AlignCenter)
self.DnD.setStyleSheet('''
QLabel {
border: 2px solid rgb(0, 0, 0);
color: rgb(0, 0, 0);
background-color: rgb(192, 192, 192);
}
''')
self.DnDList = QListWidget()
self.mainWindowLayout.addWidget(self.DnD, 1, 0)
self.mainWindowLayout.addWidget(self.DnDList, 2, 0)
class DragnDrop(QLabel):
def __init__(self):
QLabel.__init__(self)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
self.test = event.mimeData().urls()
MainWindow().DnDList.addItem(str(self.test))
if __name__ == "__main__":
myApp = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Plastique'))
mainWindow = MainWindow()
mainWindow.show()
myApp.exec_()
sys.exit(0)
如果我在 QLabel 上拖放文件:
,我会得到这个 运行-time 错误
RuntimeError: wrapped C/C++ object of type QListWidget has been deleted
对不起,如果我的代码示例很弱,但我不是很精通编程。目标是在 qlabel
上放置一个文件并获取它的文件路径,然后显示在 qlistwidget
.
中
我查看了 this and this 问题,但未能完全理解问题的真正含义或解决方法。
编辑
我喜欢thomasedv的建议,但没有实现。
我尝试发出自定义信号,但未能成功将其传递给 MainWindow 的函数-Class。
在我编辑的代码中:
def dropEvent(self, event):
self.test = event.mimeData().urls()
MainWindow().DnDList.addItem(str(self.test))
至:
def dropEvent(self, event):
self.emit(SIGNAL("sig"), str(event.mimeData().urls()))
但我现在不知道如何继续将该字符串添加到我的列表中。
我可以很容易地把它变成 运行(使用 PyQt5,必须导入一些额外的东西,但我想这是 PySide 和 PyQt5 之间的区别),但是拖放不起作用,并且我认为那是你的问题。我认为用字符串发出一个自定义信号(如果你可以像在 PyQt5 中那样在 PySide 中做到这一点),然后在你的主窗口 class 中将它连接到一个函数,将它添加到你制作的列表中要好得多那里。现在您正在尝试将列表元素添加到 MainWindow().DnDList,我认为这与在您的 Mainwindow class.
中创建的元素不同
编辑:这里是 signal/slot 方法的 PyQt5 实现。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(200,200,800,400)
self.mainWindowWidget = QWidget()
self.setCentralWidget(self.mainWindowWidget)
self.mainWindowLayout = QGridLayout()
self.mainWindowWidget.setLayout(self.mainWindowLayout)
self.DnD = DragnDrop()
self.DnD.linkDropped.connect(self.urlToList)
self.DnD.setAcceptDrops(True)
self.DnD.setAlignment(Qt.AlignCenter)
self.DnD.setStyleSheet('''
QLabel {
border: 2px solid rgb(0, 0, 0);
color: rgb(0, 0, 0);
background-color: rgb(192, 192, 192);
}
''')
self.DnDList = QListWidget()
self.mainWindowLayout.addWidget(self.DnD, 1, 0)
self.mainWindowLayout.addWidget(self.DnDList, 2, 0)
@pyqtSlot(str)
def urlToList(self, url):
self.DnDList.addItem(url)
class DragnDrop(QLabel):
linkDropped = pyqtSignal(str)
def __init__(self):
QLabel.__init__(self)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
self.test = event.mimeData().urls()
self.linkDropped.emit(self.test[0].toString())
if __name__ == "__main__":
myApp = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Plastique'))
mainWindow = MainWindow()
mainWindow.show()
myApp.exec_()
sys.exit(0)
有几点需要注意,self.test 实际上是一个带有 QUrls 的列表。所以你需要使用 0 索引。如果要支持拖放多个文件,遍历列表中的项目,将每个项目转换为字符串并为每个元素发出,如下所示:
for i in self.test:
self.linkDropped.emit(i.toString())
每个 url 都以文件开头:\\\ 前缀,因为我确定它在浏览器中,如果您不想使用它,可能需要稍微更改它:
i.toString()[8:]
如果我运行这个代码:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(200,200,800,400)
self.mainWindowWidget = QWidget()
self.setCentralWidget(self.mainWindowWidget)
self.mainWindowLayout = QGridLayout()
self.mainWindowWidget.setLayout(self.mainWindowLayout)
self.DnD = DragnDrop()
self.DnD.setAcceptDrops(True)
self.DnD.setAlignment(Qt.AlignCenter)
self.DnD.setStyleSheet('''
QLabel {
border: 2px solid rgb(0, 0, 0);
color: rgb(0, 0, 0);
background-color: rgb(192, 192, 192);
}
''')
self.DnDList = QListWidget()
self.mainWindowLayout.addWidget(self.DnD, 1, 0)
self.mainWindowLayout.addWidget(self.DnDList, 2, 0)
class DragnDrop(QLabel):
def __init__(self):
QLabel.__init__(self)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
self.test = event.mimeData().urls()
MainWindow().DnDList.addItem(str(self.test))
if __name__ == "__main__":
myApp = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Plastique'))
mainWindow = MainWindow()
mainWindow.show()
myApp.exec_()
sys.exit(0)
如果我在 QLabel 上拖放文件:
,我会得到这个 运行-time 错误RuntimeError: wrapped C/C++ object of type QListWidget has been deleted
对不起,如果我的代码示例很弱,但我不是很精通编程。目标是在 qlabel
上放置一个文件并获取它的文件路径,然后显示在 qlistwidget
.
我查看了 this and this 问题,但未能完全理解问题的真正含义或解决方法。
编辑
我喜欢thomasedv的建议,但没有实现。
我尝试发出自定义信号,但未能成功将其传递给 MainWindow 的函数-Class。
在我编辑的代码中:
def dropEvent(self, event):
self.test = event.mimeData().urls()
MainWindow().DnDList.addItem(str(self.test))
至:
def dropEvent(self, event):
self.emit(SIGNAL("sig"), str(event.mimeData().urls()))
但我现在不知道如何继续将该字符串添加到我的列表中。
我可以很容易地把它变成 运行(使用 PyQt5,必须导入一些额外的东西,但我想这是 PySide 和 PyQt5 之间的区别),但是拖放不起作用,并且我认为那是你的问题。我认为用字符串发出一个自定义信号(如果你可以像在 PyQt5 中那样在 PySide 中做到这一点),然后在你的主窗口 class 中将它连接到一个函数,将它添加到你制作的列表中要好得多那里。现在您正在尝试将列表元素添加到 MainWindow().DnDList,我认为这与在您的 Mainwindow class.
中创建的元素不同编辑:这里是 signal/slot 方法的 PyQt5 实现。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(200,200,800,400)
self.mainWindowWidget = QWidget()
self.setCentralWidget(self.mainWindowWidget)
self.mainWindowLayout = QGridLayout()
self.mainWindowWidget.setLayout(self.mainWindowLayout)
self.DnD = DragnDrop()
self.DnD.linkDropped.connect(self.urlToList)
self.DnD.setAcceptDrops(True)
self.DnD.setAlignment(Qt.AlignCenter)
self.DnD.setStyleSheet('''
QLabel {
border: 2px solid rgb(0, 0, 0);
color: rgb(0, 0, 0);
background-color: rgb(192, 192, 192);
}
''')
self.DnDList = QListWidget()
self.mainWindowLayout.addWidget(self.DnD, 1, 0)
self.mainWindowLayout.addWidget(self.DnDList, 2, 0)
@pyqtSlot(str)
def urlToList(self, url):
self.DnDList.addItem(url)
class DragnDrop(QLabel):
linkDropped = pyqtSignal(str)
def __init__(self):
QLabel.__init__(self)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
self.test = event.mimeData().urls()
self.linkDropped.emit(self.test[0].toString())
if __name__ == "__main__":
myApp = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Plastique'))
mainWindow = MainWindow()
mainWindow.show()
myApp.exec_()
sys.exit(0)
有几点需要注意,self.test 实际上是一个带有 QUrls 的列表。所以你需要使用 0 索引。如果要支持拖放多个文件,遍历列表中的项目,将每个项目转换为字符串并为每个元素发出,如下所示:
for i in self.test:
self.linkDropped.emit(i.toString())
每个 url 都以文件开头:\\\ 前缀,因为我确定它在浏览器中,如果您不想使用它,可能需要稍微更改它:
i.toString()[8:]