2010-11-11 124 views
11

我一直在编写一个OCR书籍扫描事物(它通过读取页面编号重命名页面),并已从我的基本CLI Python脚本切换到GUI。PyQT4:将文件拖放到QListWidget中

我正在使用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)) 

感谢任何人谁可以帮助!

+0

只是可以肯定,没有“如果event.mimeData()。hasUrls”在dropEvent评估为真,当你拖动文件到它? – 2010-11-11 06:07:22

+0

我在每个函数中都添加了print()语句,而且它甚至没有初始化控件! * sobs * – Blender 2010-11-12 13:46:05

回答

16

您用作示例的代码似乎工作正常,看起来相当干净。根据你的评论你的列表小部件没有得到初始化;这应该是你问题的根源。我已经简化了你的代码,在我的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() 

希望这会有所帮助,至于

+0

哇,这一定会有所帮助。我已经让我的程序运行了,这会让它变得更好!是否有可能完全覆盖QListWidget类?我想添加一些新的功能。 – Blender 2010-11-15 16:04:05

+2

对你的问题的回答取决于你想要达到的目标。我可能会开始使用QListView和QAbstractModel后代之一(或写我自己的)。有很多例子可供你开始玩。 – 2010-11-15 16:19:58

+1

你应该将所有'event.mimeData()。hasUrls'编辑到'event.mimeData()。hasUrls()'(至少在PyQt 4.8中) – 2016-03-17 19:55:32