2010-11-11 12 views
11

Ich habe eine OCR-Buchscansache programmiert (sie benennt Seiten durch Lesen der Seitennummer um) und habe von meinem grundlegenden CLI Python-Skript zu einer GUI gewechselt.PyQT4: Dateien in QListWidget ziehen und ablegen

Ich benutze PyQT4 und schaute auf eine Tonne von Dokumenten auf Drag & Drop, aber kein Glück. Es weigert sich einfach, diese Dateien zu nehmen! Ich war mit diesen Einträgen für mein UI-Design:

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

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

Ich habe bemerkt, dass es eine Tonne von Möglichkeiten zur Einrichtung ist ein PyQT4 GUI. Welche funktioniert am besten?

Hoppla, hier ist der Quellcode für das Projekt.

Das Hauptskript:

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

Und die UI-Datei ...

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

Dank jemand, der helfen kann!

+0

Nur um sicher zu sein, bedeutet "wenn event.mimeData(). HasUrls" in dropEvent True ergibt, wenn Sie Dateien in sie bist ziehen? –

+0

Ich habe eine print() Anweisung in jeder Funktion hinzugefügt, und es scheint nicht einmal das Steuerelement zu initialisieren! * schluchzt * – Blender

Antwort

16

Der Code, den Sie als Beispiel verwenden, scheint gut zu funktionieren und sieht ziemlich sauber aus. Laut Ihrem Kommentar wird Ihr Listen-Widget nicht initialisiert. Dies sollte die Ursache Ihres Problems sein. Ich habe deinen Code ein wenig vereinfacht und es auf meinem Ubuntu 10.04LTS versucht und es hat gut funktioniert. Mein Code ist unten aufgelistet, sehen Sie, ob es auch für Sie wäre. Sie sollten eine Datei per Drag & Drop in das Listenwidget ziehen können. Sobald es gelöscht wird, wird ein neues Element hinzugefügt, das den Dateinamen des Bildes und des Bildes anzeigt.

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

hoffe, das hilft, sieht

+0

Wow, das wird definitiv helfen. Ich habe mein Programm bereits gestartet, und das wird es noch besser machen! Wäre es möglich, die QListWidget-Klasse vollständig zu überschreiben? Ich wollte einige neue Funktionen hinzufügen. – Blender

+2

Antwort auf Ihre Frage hängt davon ab, was genau Sie erreichen möchten. Ich würde wahrscheinlich anfangen, QListView und eine von QAbstractModel Nachkommen zu verwenden (oder schrieb meine eigene). Es gibt viele Beispiele für Sie, mit denen Sie anfangen zu spielen. –

+1

Sie sollten alle 'event.mimeData(). HasUrls' zu' event.mimeData(). HasUrls() '(zumindest für PyQt 4.8) bearbeiten –

Verwandte Themen