-1

If I run this code:

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)

I will get this Run-time error if i drag and drop files on the QLabel:

RuntimeError: wrapped C/C++ object of type QListWidget has been deleted

Sorry if my code example is weak but I am not very proficient in programming. The goal is to drop a file on that qlabel and get the file-path of it which is then displayed in a qlistwidget.

I looked at this and this question but failed to fully understand what the problem really is or how I can solve this.

Edit

I like thomasedv's suggestion but fail to realize it.

I tried to emit a custom signal but i dont succeed in passing it to a function of the MainWindow-Class.

In the Code I edited:

    def dropEvent(self, event):

        self.test = event.mimeData().urls()
        MainWindow().DnDList.addItem(str(self.test))

to:

    def dropEvent(self, event):

        self.emit(SIGNAL("sig"), str(event.mimeData().urls()))

But I am now helpless how to proceed to add that string to my list.

  • Your program works fine in PySide if you replace MainWindow() with mainWindow, a rather simple mistake. Also the reported error is a bit different from what I get with your code. – NoDataDumpNoContribution Aug 08 '17 at 13:34

1 Answers1

0

I can get it to run easily(with PyQt5, had to import some extra stuff, but i guess that's a difference between PySide and PyQt5), but the drag and drop doesn't work, and i think that's your issue. I think it's far better to emit a custom signal(if you can do that in PySide like in PyQt5) with the string, and then connect that in your mainwindow class to a function, which adds it to the list you made there. Right now you are trying to add the list element to a MainWindow().DnDList which i don't think is the same as the one created in your Mainwindow class.

Edit: Here is the PyQt5 implementation of the signal/slot method.

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)

Few things to note, self.test is actually a list with QUrls. So you need to use the 0 index. If you want to support drag and drop of multiple files, iterate through the items in the list, convert each item to string and emit for each element, like so:

for i in self.test:
    self.linkDropped.emit(i.toString()) 

Each url starts with a file:\\\ prefix since i'm sure that's in the browser, might need to change that a bit if you don't want it with:

i.toString()[8:] 
Thomasedv
  • 382
  • 4
  • 22
  • It would be great if you could look at my edited question – Sahelantro Jul 27 '17 at 11:55
  • @Sahelantro I did manage to make a working example out of your post, but that's not in pyside but using the PyQt5 method, which I think is different. I'm won't be able to do anything for a while, but if no one comes along with a answer in the meantime, I'll try when I can. – Thomasedv Jul 27 '17 at 12:18
  • @Sahelantro, updated answer with code, not sure if it'll work with PySide, but i hope so. – Thomasedv Jul 27 '17 at 17:05