2010-11-11 12 views
11

Kodowałem element do skanowania książki OCR (zmienia nazwę stron, czytając numer strony) i przełączyłem się na GUI z mojego podstawowego skryptu Python CLI.PyQT4: Przeciąganie i upuszczanie plików do QListWidget

Używam PyQT4 i patrzę na mnóstwo dokumentów na temat przeciągania i upuszczania, ale bez powodzenia. Po prostu odmawia wykonania tych plików! Używałem tych artykułów dla mojego projektu UI:

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

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

Zauważyłem, że istnieje mnóstwo sposobów Aby ustawić PyQt4 GUI. Który z nich działa najlepiej?

Ups, oto kod źródłowy projektu.

Głównym scenariusz:

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

a plik 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)) 

Dzięki każdemu, kto może pomóc!

+0

Wystarczy, aby mieć pewność, czy "jeśli event.mimeData(). HasUrls" w dropEvent ocenia True kiedy przeciąganie plików do niego? –

+0

Dodałem instrukcję print() wewnątrz każdej funkcji i nawet nie wydaje się, aby zainicjować sterowanie! * szloch * – Blender

Odpowiedz

16

Kod, którego używasz jako przykładu, działa dobrze i wygląda całkiem nieźle. Według twojego komentarza twój widget listy nie jest inicjowany; to powinna być podstawowa przyczyna twojego problemu. Uprościliśmy twój kod nieco wypróbowany na moim Ubuntu 10.04LTS i działało dobrze. Mój kod jest wymieniony poniżej, sprawdź, czy to również dla ciebie. Powinieneś być w stanie przeciągnąć i upuścić plik do widżetu listy; po upuszczeniu zostaje dodany nowy element z obrazem i nazwą pliku obrazu.

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

nadzieję, że to pomaga, chodzi

+0

Wow, to na pewno ci pomoże. Mam już uruchomiony mój program, a to jeszcze sprawi, że będzie jeszcze lepszy! Czy byłoby możliwe całkowite zastąpienie klasy QListWidget? Chciałem dodać do niego nowe funkcje. – Blender

+2

odpowiedź na pytanie zależy od tego, co dokładnie chcesz osiągnąć. Prawdopodobnie zacznę od używania QListView i jednego z potomków QAbstractModel (lub mojego własnego). Jest mnóstwo przykładów, z którymi możesz zacząć grać. –

+1

Powinieneś edytować wszystkie 'event.mimeData(). HasUrls' na' event.mimeData(). HasUrls() '(przynajmniej dla PyQt 4.8) –

Powiązane problemy