Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Drag and drop d'objets de QPainter

+3 votes

Je me suis initié à PySide, mais j'ai assez de mal a déterminer si on peut faire telle ou telle chose avec cette énorme bibliothèque.

Peut-on déplacer des figures géométriques créées avec QPainter ?

Et si non, comment faire pour avoir un background statique créé avec QPainter, et pouvoir déplacer par dessus une simple figure géométrique ?

demandé 26-Avr-2016 par Gloups

Jette un œuil à cette dépèche:

http://pyqt.developpez.com/actu/80721/Le-projet-PySide-est-declare-abandonne-en-2015-il-ne-reste-plus-que-PyQt-comme-binding-Python-de-Qt/

Je serai toi, j'y regarderai à 2 fois avant de me lancer dans du dev PySide...

Le projet n'est pas mort, cette info date de janvier 2015, alors que la dernière release date d'octobre 2015.

De toute façon les deux se ressemblent énormément, le portage de l'un à l'autre est généralement l'affaire de très peu de temps.

3 Réponses

+2 votes

QPainter est plutôt bas niveau, et comme son nom l'indique n'est pas destiné à être un conteneur de widgets (ce dont tu as a priori besoin si tu veux déplacer simplement des formes).

Pour faire quelque chose qui ressemble à ce que tu veux, tu pourrais essayer d'utiliser une QGraphicsView et les classes qui vont avec.

répondu 26-Avr-2016 par yoch (2,066 points)
0 votes

Je comprends pas comment faire, et plus je lis la doc, enfin si on peut considérer ça comme de la doc..
Plus je suis paumé.
Même les exemples forunis dans le package de la bibliothèque ne sont pas commentés :-/

Je n'arrive vraiment pas à relier la figure tracée dans la scène à l'event.
Il doit manquer quelque chose, mais je patauge.

Exemple d'un code simpliste :

class Fenetre(QtGui.QMainWindow) :
    def __init__(self) :
        QtGui.QMainWindow.__init__(self)

        self.sg = SceneGraphique(0, 0, 400, 400, self)
        self.vue = QtGui.QGraphicsView()
        self.setCentralWidget(self.vue)
        self.vue.setScene(self.sg)

class SceneGraphique(QtGui.QGraphicsScene) :
    def __init__(self, *params) :
        QtGui.QGraphicsScene.__init__(self, *params)

        pinceau = QtGui.QPen(QtCore.Qt.blue, 50, QtCore.Qt.SolidLine, QtCore.Qt.FlatCap, QtCore.Qt.MiterJoin)
        brosse = QtGui.QBrush()
        brosse.setStyle(QtCore.Qt.SolidPattern)

        mrect = RectangleBleu(150, 150, 50, 50)
        self.addRect(mrect.rect(), pen=pinceau, brush=brosse)

    def mousePressEvent(self, evt):
        print('Clic scene')

    def mouseReleaseEvent(self, evt):
        print('Clic relâché scene')        

class RectangleBleu(QtGui.QGraphicsRectItem):
    def __init__(self, *args) :

        QtGui.QGraphicsRectItem.__init__(self)
        # Ok, si j'ai bien compris la doc, setPen et setBrush
        # ne fonctionnent pas avec GraphicsItem...
        #self.setPen(QtGui.QPen(QtCore.Qt.blue, 50, QtCore.Qt.SolidLine, QtCore.Qt.FlatCap, QtCore.Qt.MiterJoin))
        #brosse = QtGui.QBrush()
        #brosse.setStyle(QtCore.Qt.SolidPattern)
        #self.setBrush(brosse)

        self.setRect(*args)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)

    def mousePressEvent(self, evt):
        print('Clic Rectangle')
        #QtGui.QGraphicsScene.mousePressEvent(self, evt)

    def mouseReleaseEvent(self, evt):
        print('Clic relâché Rectangle')
        #QtGui.QGraphicsScene.mouseReleaseEvent(self, evt)

app = QtGui.QApplication(sys.argv)
f = Fenetre()
f.show()
sys.exit(app.exec_())

En passant par addItem, là j'ai une réaction, mais ça merdouille pas mal, en plus faut que je lui pass l'objet, et vu que les setX ne fonctionnent pas, je peux pas configurer le rectangle, couleur et brosse.

répondu 28-Avr-2016 par Gloups (142 points)
0 votes

Bon, j'ai trouvé à force de persévérance quelque chose de fonctionnel.

Je met un simple exemple pour ceux qui aurait besoin de faire quelque chose de ce type.

try :
    from PySide import QtGui, QtCore
except :
    from PyQt4 import QtGui, QtCore


class Fenetre(QtGui.QMainWindow) :
    def __init__(self) :
        QtGui.QMainWindow.__init__(self)    

class Scene(QtGui.QGraphicsScene) :
    def __init__(self, *params) :
        QtGui.QGraphicsScene.__init__(self, *params)
        print(params)

class Cadre(QtGui.QGraphicsView) :
    def __init__(self, scene) :
        QtGui.QGraphicsView.__init__(self, scene)
        self.scene = scene

    def rectangle(self, *params) :
        r = Rectangle(*params)
        r.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
        r.setAcceptHoverEvents(True)
        self.scene.addItem(r)

class Rectangle(QtGui.QGraphicsRectItem) :

    def __init__(self, *params) :
        QtGui.QGraphicsRectItem.__init__(self)        
        pinceau = QtGui.QPen(QtGui.QColor(QtCore.Qt.green))
        brosse = QtGui.QBrush(pinceau.color())

        self.setPen(pinceau)
        self.setBrush(brosse)
        self.setRect(*params)

    def mousePressEvent(self, evt) :
        print('clicE')

    def mouseReleaseEvent(self, evt) :
        print('clicR')
        return QtGui.QGraphicsRectItem.mouseReleaseEvent(self, evt)

    def hoverEnterEvent(self, evt) :
        print('Entre dans l\'objet')

    def hoverLeaveEvent(self, evt) :
        print('Sort de l\'objet')

app = QtGui.QApplication(())
f = Fenetre()
s = Scene(0, 0, 400, 400, f)
c = Cadre(s)
c.rectangle(150, 150, 50, 50)
c.show()
app.exec_()
répondu 29-Avr-2016 par Gloups (142 points)

Tu devrais te servir de super(), là tu te complique pas mal la vie...

...