QListView 不接受使用 Python PyQt4 在 QMainWindow 中的丢弃

Posted

技术标签:

【中文标题】QListView 不接受使用 Python PyQt4 在 QMainWindow 中的丢弃【英文标题】:QListView not accepting drops in QMainWindow with Python PyQt4 【发布时间】:2013-08-23 19:34:51 【问题描述】:

我无法让QListWidget 接受丢弃的文件。

我使用Qt Designer 制作了QMainWindowQListWidget

我该如何解决这个问题?

这是我的main.py

import sys
import os   
from PyQt4 import QtCore, QtGui
from PythonApp import Ui_MainWindow

class MainWindow(Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        listView = Ui_MainWindow.listView
        listView.setAcceptDrops(True)
        listView.setIconSize(QtCore.QSize(72, 72))
        self.connect(listView, QtCore.SIGNAL("dropped"), self.pictureDropped)
        self.setCentralWidget(listView)

    def pictureDropped(self, l):
    listView = Ui_MainWindow.listView
        for url in l:
            if os.path.exists(url):
                print(url)                
                icon = QtGui.QIcon(url)
                pixmap = icon.pixmap(72, 72)                
                icon = QtGui.QIcon(pixmap)
                item = QtGui.QListWidgetItem(url, listView)
                item.setIcon(icon)        
                item.setStatusTip(url)             

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)
        else:
            event.ignore()

    def main():
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)

        MainWindow.show()
        sys.exit(app.exec_())

    if __name__ == '__main__':
        main()

这是我的PythonApp.py文件:

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setAcceptDrops(True)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.listView = QtGui.QListView(self.centralwidget)
        self.listView.setGeometry(QtCore.QRect(100, 60, 501, 331))
        self.listView.setAcceptDrops(True)
        self.listView.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
        self.listView.setDefaultDropAction(QtCore.Qt.CopyAction)
        self.listView.setObjectName(_fromUtf8("listView"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

【问题讨论】:

errorexception等吗??????信息越多越好。 另外,您可能希望清理有关此问题的代码。只需发布相关部分,否则它会变得非常混乱。 没有错误也没有异常,只是不接受任何丢弃。谢谢。 尝试在dropevent中添加print "here"之类的东西,以测试是否触发了事件。 我会添加打印件... 【参考方案1】:

查看此示例的工作原理,以便您修改代码:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

#---------
# IMPORT
#---------
import sys, os

from PyQt4 import QtGui, QtCore

#---------
# DEFINE
#---------
class MyListWidget(QtGui.QListWidget):
    dropped = QtCore.pyqtSignal(list)

    def __init__(self, type, parent=None):
        super(MyListWidget, 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:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()

        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()

            filePaths = [
                str(url.toLocalFile())
                for url in event.mimeData().urls()
            ]

            self.dropped.emit(filePaths)

        else:
            event.ignore()

class MyWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.listWidgetFiles = MyListWidget(self)
        self.listWidgetFiles.dropped.connect(self.on_listWidgetFiles_dropped)

        self.layoutVertical = QtGui.QVBoxLayout(self)
        self.layoutVertical.addWidget(self.listWidgetFiles)

    @QtCore.pyqtSlot(list)
    def on_listWidgetFiles_dropped(self, filePaths):
        for filePath in filePaths:
            if os.path.exists(filePath):
                QtGui.QListWidgetItem(filePath, self.listWidgetFiles)

#---------
# MAIN
#---------
if __name__ == "__main__":        
    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('MyWindow')

    main = MyWindow()
    main.resize(333, 111)
    main.show()

    sys.exit(app.exec_())

【讨论】:

以上是关于QListView 不接受使用 Python PyQt4 在 QMainWindow 中的丢弃的主要内容,如果未能解决你的问题,请参考以下文章

QListView 更新 - 不触发更新

从 python 中的 PYQT5 QListview 获取选定文件的文件名

QListView 与 CustomWIdget 使用 QStyledItemDelegate

Qt:更改 QListView 中的图标

PyQt QListView在用户界面编辑项目后检索项目

调整大小时 QListView 图标模式不重新布局