【问题标题】:PyQT4: Drag and drop files into QListWidgetPyQT4:将文件拖放到 QListWidget
【发布时间】:2011-05-08 06:55:57
【问题描述】:

我一直在编写一个 OCR 书籍扫描程序(它通过读取页码来重命名页面),并且已经从我的基本 CLI Python 脚本切换到 GUI。

我正在使用 PyQT4,并在拖放中查看了大量文档,但没有运气。它只是拒绝接受这些文件!我将这些用于我的 UI 设计文章:

  1. http://tech.xster.net/tips/pyqt-drag-images-into-list-widget-for-thumbnail-list/

  2. http://zetcode.com/tutorials/pyqt4/dragdrop/

我注意到有很多方法可以设置 PyQT4 GUI。哪一种效果最好?

糟糕,这是项目的源代码。

主脚本:

import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtGui import QListWidget
from layout import Ui_window

class StartQT4(QtGui.QMainWindow):
  def __init__(self, parent = None):
    QtGui.QWidget.__init__(self, parent)

    self.ui = Ui_window()
    self.ui.setupUi(self)

    QtCore.QObject.connect(self.ui.listWidget, QtCore.SIGNAL("dropped"), self.picture_dropped)

  def picture_dropped(self, l):
    for url in l:
     if os.path.exists(url):
      picture = Image.open(url)
      picture.thumbnail((72, 72), Image.ANTIALIAS)
      icon = QIcon(QPixmap.fromImage(ImageQt.ImageQt(picture)))
      item = QListWidgetItem(os.path.basename(url)[:20] + "...", self.pictureListWidget)
      item.setStatusTip(url)
      item.setIcon(icon)

class DragDropListWidget(QListWidget):
 def __init__(self, type, parent = None):
  super(DragDropListWidget, self).__init__(parent)
  self.setAcceptDrops(True)
  self.setIconSize(QSize(72, 72))

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

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

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

if __name__ == "__main__":
  app = QtGui.QApplication(sys.argv)
  myapp = StartQT4()
  myapp.show()
  sys.exit(app.exec_())

还有 UI 文件...

# Form implementation generated from reading ui file 'layout.ui'
#
# Created: Thu Nov 11 00:22:52 2010
#      by: PyQt4 UI code generator 4.8.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

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

class Ui_window(object):
    def setupUi(self, window):
        window.setObjectName(_fromUtf8("window"))
        window.resize(543, 402)
        window.setAcceptDrops(True)
        self.centralwidget = QtGui.QWidget(window)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        self.listWidget = QtGui.QListWidget(self.centralwidget)
        self.listWidget.setProperty(_fromUtf8("cursor"), QtCore.Qt.SizeHorCursor)
        self.listWidget.setAcceptDrops(True)
        self.listWidget.setObjectName(_fromUtf8("listWidget"))
        self.verticalLayout.addWidget(self.listWidget)
        window.setCentralWidget(self.centralwidget)

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

    def retranslateUi(self, window):
        window.setWindowTitle(QtGui.QApplication.translate("window", "PyNamer OCR", None, QtGui.QApplication.UnicodeUTF8))

感谢任何可以提供帮助的人!

【问题讨论】:

  • 可以肯定的是,当您将文件拖入其中时,dropEvent 中的“if event.mimeData().hasUrls”是否计算为 True?
  • 我在每个函数中添加了一个 print() 语句,它甚至似乎都没有初始化控件! 啜泣

标签: python drag-and-drop pyqt


【解决方案1】:

您作为示例使用的代码似乎运行良好并且看起来很干净。根据您的评论,您的列表小部件未初始化;这应该是您问题的根本原因。我已经简化了你的代码,并在我的 Ubuntu 10.04LTS 上进行了尝试,它运行良好。我的代码在下面列出,看看它是否也适合你。您应该能够将文件拖放到列表小部件中;一旦它被删除,就会添加一个新项目,显示图像和图像的文件名。

import sys
import os
from PyQt4 import QtGui, QtCore

class TestListView(QtGui.QListWidget):
    def __init__(self, type, parent=None):
        super(TestListView, self).__init__(parent)
        self.setAcceptDrops(True)
        self.setIconSize(QtCore.QSize(72, 72))

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

class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

        self.view = TestListView(self)
        self.connect(self.view, QtCore.SIGNAL("dropped"), self.pictureDropped)
        self.setCentralWidget(self.view)

    def pictureDropped(self, l):
        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, self.view)
                item.setIcon(icon)        
                item.setStatusTip(url)        

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

希望这会有所帮助,问候

【讨论】:

  • 哇,这肯定会有所帮助。我已经运行了我的程序,这将使它变得更好!是否可以完全覆盖 QListWidget 类?我想给它添加一些新功能。
  • 对您的问题的回答取决于您想要达到的目标。我可能会从使用 QListView 和 QAbstractModel 后代之一开始(或自己编写一个)。周围有很多示例供您开始使用。
  • 您应该将所有event.mimeData().hasUrls 编辑为event.mimeData().hasUrls()(至少对于PyQt 4.8)
猜你喜欢
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 2012-01-14
相关资源
最近更新 更多