2010-11-11 10 views
11

J'ai codé un objet de numérisation de livres OCR (il renomme les pages en lisant le numéro de page) et j'ai basculé vers une interface graphique de mon script Python de base CLI. J'utilise PyQT4 et j'ai regardé une tonne de documents par glisser-déposer, mais pas de chance. Il refuse juste de prendre ces fichiers! J'utilisais ces articles pour ma conception de l'interface utilisateur:PyQT4: Glissez et déposez des fichiers dans QListWidget

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

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

Je remarqué qu'il ya une tonne de façons de configurer une interface graphique pyqt4. Lequel fonctionne le mieux? Oups, voici le code source du projet.

Le script principal:

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

Et le fichier de l'interface utilisateur ...

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

Merci à tous ceux qui peuvent aider!

+0

juste pour être sûr, ne « si event.mimeData(). HasUrls » à dropEvent est évaluée à True lorsque vous faites glisser les fichiers dans tout cela? –

+0

J'ai ajouté une instruction print() à l'intérieur de chaque fonction, et il ne semble même pas initialiser le contrôle! * sanglots * – Blender

Répondre

16

Le code que vous utilisez comme exemple semble fonctionner correctement et semble assez propre. D'après votre commentaire, votre widget liste n'est pas initialisé; Cela devrait être la cause première de votre problème. J'ai un peu simplifié ton code et l'ai essayé sur mon Ubuntu 10.04LTS et ça a bien fonctionné. Mon code est énuméré ci-dessous, voir si cela serait aussi pour vous. Vous devriez être capable de glisser et déposer un fichier dans le widget liste; Une fois qu'il est déposé, un nouvel élément est ajouté montrant l'image et le nom du fichier de l'image.

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

espérons que cette aide, ce qui est

+0

Wow, cela va certainement aider. J'ai déjà mon programme en cours, et cela le rendra encore meilleur! Serait-il possible de surcharger complètement la classe QListWidget? Je voulais ajouter de nouvelles fonctions. – Blender

+2

réponse à votre question dépend de ce que vous essayez d'atteindre exactement. Je commencerais probablement à utiliser QListView et l'un des descendants QAbstractModel (ou a écrit le mien). Il y a beaucoup d'exemples pour commencer à jouer avec. –

+1

Vous devez éditer tout 'event.mimeData(). HasUrls' à' event.mimeData(). HasUrls() '(au moins pour PyQt 4.8) –