Partage
  • Partager sur Facebook
  • Partager sur Twitter

[PyQt4] Signaux, Slots et Drag&Drop

    2 novembre 2011 à 18:01:55

    Bonjour,


    Je suis en train de développer une application dans laquelle j'utilise du Drag&Drop de fichiers pour les ajouter à un QTreeWidget.
    J'ai donc trois fichiers avec une classe dans chaque.
    dropbox.py : contient la classe dérivée de QtGui.QWidget et qui est en fait la classe qui récupère les fichiers et qui lance un signal avec en paramètres le chemin des fichiers.
    superstooge_gui.py : contient la classe générée par pyuic4
    et superstooge.py : contient la classe qui permet de créer la fenêtre.



    dropbox.py:
    # -*- coding: utf8 -*-
    
    from PyQt4 import QtCore, QtGui
    
    class DropBox(QtGui.QWidget):
        def __init__(self, parent):
            super(DropBox, self).__init__(parent)
            self.parent = parent
            self.setAcceptDrops(True)
    
        def dragEnterEvent(self, e):
            # If the dragged item is a file, it has an URL
            if e.mimeData().hasUrls(): e.accept()
            else: e.ignore()
    
        def dropEvent(self, e):
            pathList = list()
            urlList = e.mimeData().urls()
            for i in urlList:
                path = str(i.toLocalFile())
                pathList.append(path.encode('utf8'))
                print path.encode('utf8')
    
            for path in pathList:
                pass
    





    superstooge_gui.py:
    # -*- coding: utf8 -*-
    
    # Form implementation generated from reading ui file 'superstooge.ui'
    #
    # Created: Tue Nov  1 12:08:00 2011
    #      by: PyQt4 UI code generator 4.8.5
    
    from PyQt4 import QtCore, QtGui
    from dropbox import DropBox
    
    
    class Ui_SuperStooge(object):
        def setupUi(self, SuperStooge):
            SuperStooge.setFixedSize(340, 480)
            SuperStooge.setWindowTitle('SuperStooge')
            icon = QtGui.QIcon()
            icon.addPixmap(QtGui.QPixmap('icon.xpm'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
            SuperStooge.setWindowIcon(icon)
            SuperStooge.setStyleSheet('')
            self.centralwidget = QtGui.QWidget(SuperStooge)
            self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
            self.gridLayout = QtGui.QGridLayout()
            self.gridLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
            self.rankBtn = QtGui.QPushButton(self.centralwidget)
            self.rankBtn.setText(QtGui.QApplication.translate('SuperStooge', 'Ranger', None, QtGui.QApplication.UnicodeUTF8))
            self.gridLayout.addWidget(self.rankBtn, 5, 0, 1, 1)
            self.treeWidget = QtGui.QTreeWidget(self.centralwidget)
            self.treeWidget.setFrameShape(QtGui.QFrame.StyledPanel)
            self.treeWidget.setFrameShadow(QtGui.QFrame.Sunken)
            self.treeWidget.setAlternatingRowColors(True)
            self.treeWidget.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
            self.treeWidget.headerItem().setText(0, QtGui.QApplication.translate('SuperStooge', 'Dropped files', None, QtGui.QApplication.UnicodeUTF8))
            self.treeWidget.headerItem().setText(1, QtGui.QApplication.translate('SuperStooge', 'Destination', None, QtGui.QApplication.UnicodeUTF8))
            self.gridLayout.addWidget(self.treeWidget, 2, 0, 1, 1)
            self.separator = QtGui.QFrame(self.centralwidget)
            self.separator.setEnabled(True)
            self.separator.setFrameShape(QtGui.QFrame.HLine)
            self.separator.setFrameShadow(QtGui.QFrame.Sunken)
            self.gridLayout.addWidget(self.separator, 1, 0, 1, 1)
            self.dropbox = DropBox(self.centralwidget)
            self.dropbox.setMinimumSize(QtCore.QSize(0, 200))
            self.dropbox.setStyleSheet("background-color: rgb(148, 148, 148);\n"
    "font: 36pt \"Bitstream Vera Sans Mono\";")
            self.dropLabel = QtGui.QLabel(self.dropbox)
            self.dropLabel.setGeometry(QtCore.QRect(0, 60, 320, 80))
            self.dropLabel.setStyleSheet('')
            self.dropLabel.setText(QtGui.QApplication.translate('SuperStooge', "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
    "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
    "p, li { white-space: pre-wrap; }\n"
    "</style></head><body style=\" font-family:\'Bitstream Vera Sans Mono\'; font-size:36pt; font-weight:400; font-style:normal;\">\n"
    "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Drop Here</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
            self.gridLayout.addWidget(self.dropbox, 0, 0, 1, 1)
            self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
            SuperStooge.setCentralWidget(self.centralwidget)
    
            self.retranslateUi(SuperStooge)
            QtCore.QMetaObject.connectSlotsByName(SuperStooge)
    
        def retranslateUi(self, SuperStooge):
            __sortingEnabled = self.treeWidget.isSortingEnabled()
            self.treeWidget.setSortingEnabled(False)
            self.treeWidget.setSortingEnabled(__sortingEnabled)
    



    Et ici le fichier qui me permet de créer ma fenêtre:
    #!/usr/bin/python2
    # -*- coding: utf8 -*-
    
    import sys
    from PyQt4 import QtGui, QtCore
    from superstooge_gui import Ui_SuperStooge
    
    
    class SuperStooge_GUI(QtGui.QMainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
    
            self.ui = Ui_SuperStooge()
            self.ui.setupUi(self)
    
        def addItem(self, src, dest):
            # n is the number of lines in the QTreeWidget
            n = self.ui.treeWidget.topLevelItemCount()
            item_0 = QtGui.QTreeWidgetItem(self.ui.treeWidget)
            # Add the source path file
            self.ui.treeWidget.topLevelItem(n).setText(0, QtGui.QApplication.translate('SuperStooge', src, None, QtGui.QApplication.UnicodeUTF8))
            # Add the destination path file
            self.ui.treeWidget.topLevelItem(n).setText(1, QtGui.QApplication.translate('SuperStooge', dest, None, QtGui.QApplication.UnicodeUTF8))
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        window = SuperStooge_GUI()
    
        window.show()
        sys.exit(app.exec_())
    




    Problème, je n'arrive pas à créer les Signaux/Slots qui me permettent de faire réagir ma classe principale quand un fichier est déposé dans ma DropBox.
    Et c'est là que vous intervenez ! ;)


    Merci d'avance.



    Edit à 18:02 le 02/11/11: Plusieurs personnes m'ont dit que j'avais codé comme un porc, mais en fait j'ai tellement ragé sur ce code que j'ai fini par modifier le fichier généré par pyuic4. Donc si vous savez comment faire ça un peu mieux, n'hésitez pas.


    Edit n°2 à 19:02 le 02/11/11: Sur les conseils de Mickael, j'ai modifié mon code et ait mis la classe DropBox dans un autre fichier
    • Partager sur Facebook
    • Partager sur Twitter
      2 novembre 2011 à 20:10:30

      ### dropbox.py
      
      # -*- coding: utf8 -*-
      
      from PyQt4 import QtCore, QtGui
      
      class DropBox(QtGui.QWidget):
          fileDropped = QtCore.pyqtSignal(str)
      
          def __init__(self, parent):
              super(DropBox, self).__init__(parent)
              self.parent = parent
              self.setAcceptDrops(True)
      
          def dragEnterEvent(self, e):
              # If the dragged item is a file, it has an URL
              if e.mimeData().hasUrls(): e.accept()
              else: e.ignore()
      
          def dropEvent(self, e):
              pathList = list()
              urlList = e.mimeData().urls()
              for i in urlList:
                  path = str(i.toLocalFile()).encode('utf8')
                  pathList.append(path)
                  self.fileDropped.emit(path)
                  
      
              for path in pathList:
                  pass
      
      
      
      ### main.py
      
      #!/usr/bin/python2
      # -*- coding: utf8 -*-
      
      import sys
      from PyQt4 import QtGui, QtCore
      from superstooge_gui import Ui_SuperStooge
      
      
      class SuperStooge_GUI(QtGui.QMainWindow):
          
          def __init__(self):
              QtGui.QMainWindow.__init__(self)
      
              self.ui = Ui_SuperStooge()
              self.ui.setupUi(self)
      
              self.ui.dropbox.fileDropped.connect(self.fileDropped)
      
              self.addItem('aaa', 'bbb')
          
          def fileDropped(self, path):
              print('Dropped : %s' % path)
      
          def addItem(self, src, dest):
              # n is the number of lines in the QTreeWidget
              n = self.ui.treeWidget.topLevelItemCount()
              item_0 = QtGui.QTreeWidgetItem(self.ui.treeWidget)
              # Add the source path file
              self.ui.treeWidget.topLevelItem(n).setText(0, QtGui.QApplication.translate('SuperStooge', src, None, QtGui.QApplication.UnicodeUTF8))
              # Add the destination path file
              self.ui.treeWidget.topLevelItem(n).setText(1, QtGui.QApplication.translate('SuperStooge', dest, None, QtGui.QApplication.UnicodeUTF8))
      
      
      if __name__ == "__main__":
          app = QtGui.QApplication(sys.argv)
          window = SuperStooge_GUI()
      
          window.show()
          sys.exit(app.exec_())
      
      • Partager sur Facebook
      • Partager sur Twitter
        2 novembre 2011 à 20:20:38

        Merci beaucoup Mickael ! Ça marche nickel.
        • Partager sur Facebook
        • Partager sur Twitter

        [PyQt4] Signaux, Slots et Drag&Drop

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown