Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. French
  4. Drag & Drop d'un Widget

Drag & Drop d'un Widget

Scheduled Pinned Locked Moved Solved French
drag&dropwidgetdrag and drop
5 Posts 2 Posters 917 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Morgatte
    wrote on 6 Sept 2021, 08:33 last edited by
    #1

    Bonjour,

    J'ai testé pleins de choses pour déplacer/déposer un Widget et rien n'y fait.
    J'ai testé les pages suivantes sans succès jusqu'à maintenant :
    [https://askcodez.com/en-faisant-glisser-un-qwidget-dans-qt-5.html"]https://askcodez.com/en-faisant-glisser-un-qwidget-dans-qt-5.html](link url)
    [https://qt.developpez.com/doc/4.7/dnd/"]https://qt.developpez.com/doc/4.7/dnd/](link url)
    Et autres :
    [https://doc.qt.io/qt-5/examples-draganddrop.html"]https://doc.qt.io/qt-5/examples-draganddrop.html](link url)

    1.png

    J'aimerais pouvoir déplacer le Widget Vert nommé Navire1.
    Son parent est lui-même un Widget (la barre Bleue) nommé TimeLine1

    Je n'arrive pas à Dragger un Widget dans un Widget.

    Auriez vous un code pour une situation similaire ?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 6 Sept 2021, 18:27 last edited by
      #2

      Bonsoir,

      En fonction du but de la manœuvre, il est plus simple de générer une image du widget à la bonne taille et d'utiliser QDrag de manière classique, quand le drop est exécuté, déplacer le widget à ce moment là.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Morgatte
        wrote on 7 Sept 2021, 07:54 last edited by Morgatte 9 Jul 2021, 07:58
        #3

        Bonjour,

        Houlà, je n'en suis pas là !
        Oui en lisant j'ai cru comprendre qu'il était possible de faire une copie sous forme d'image du widget à déplacer (QByteArray), mais j'ai des soucis plus basics.

        Que l'on voit la trace du widget en train de se déplacer, c'est super, mais là je n'arrive même pas à déplacer quoique ce soit. En fait dès le départ, j'ai un doute sur le widget sur lequel sont appliqué certaines fonctions.

        En particulier dans cette page link text je vois que mousePressEvent() est appliqué des fois sur MainWindows d'autres fois sur DragWidget.

        Ce n'est pas clair. DragWidget est-il le Widget à déplacer ou bien est-ce MainWindow qui a été renommé pour un second exemple ?

        Moi, j'ai un widget (déplaçable) contenu dans un widget (parent).
        A qui attribue-je ces différentes fonctions ?
        QDragEnterEvent
        QDragLeaveEvent
        QDragMoveEvent
        QDropEvent
        Au parent ou au widget déplaçable ? (ou un mixte ?)

        Merci.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 7 Sept 2021, 20:04 last edited by
          #4

          Les deux widgets sont là pour présenter deux cas de figures différents. Ils n'ont aucun lien l'un avec l'autre hormis que les deux font usage de D'n'D.

          Aucun des deux n'est déplacé en fait. Le drag and drop est utilisé en général comme pour le déplacement de fichiers dans l'explorateur.

          L'exemple fridge magnets pourrait être un bon point de départ.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • M Offline
            M Offline
            Morgatte
            wrote on 10 Sept 2021, 13:11 last edited by
            #5

            J'ai fini par réussir à partir de l'exemple cité ci-dessu.

            Voici le code :

            mainwidget.h

            #ifndef WIDGETPARENT_H
            #define WIDGETPARENT_H
            
            
            
            #include <QObject>
            #include <QtWidgets>
            #include <QPainter>
            #include <QPen>
            
            
            QT_BEGIN_NAMESPACE
            class QDragEnterEvent;
            class QDropEvent;
            QT_END_NAMESPACE
            
            
            
            class MainWidget : public QWidget
            {
                Q_OBJECT
            public:
                explicit MainWidget(QWidget *parent = nullptr);
            
            protected:
                void paintEvent(QPaintEvent *event) override;
            
                void dragEnterEvent(QDragEnterEvent *event) override;
                void dragMoveEvent(QDragMoveEvent *event) override;
                void dropEvent(QDropEvent *event) override;
                void mousePressEvent(QMouseEvent *event) override;
            
            
            signals:
            
            public slots:
            
            };
            
            
            #endif // WIDGETPARENT_H
            
            

            mainwindow.h

            #ifndef MAINWINDOW_H
            #define MAINWINDOW_H
            
            #include <QObject>
            #include <QWidget>
            
            
            class MainWindow : public QWidget
            {
            public:
                explicit MainWindow(QWidget *parent = nullptr);
            
            protected:
            
            
            };
            
            
            #endif // MAINWINDOW_H
            
            

            movable_child_widget.h

            #ifndef MOVABLE_CHILD_WIDGET_H
            #define MOVABLE_CHILD_WIDGET_H
            
            #include <QtWidgets>
            #include <QLabel>
            
            
            
            class Movable_Child_Widget : public QLabel
            {
            public:
                Movable_Child_Widget(const QString &text, QWidget *parent);
                QString labelText() const;
            
            private:
                QString m_labelText;
            };
            
            
            #endif // MOVABLE_CHILD_WIDGET_H
            
            

            main.cpp

            #include <QApplication>
            #include "mainwindow.h"
            
            
            
            int main(int argc, char *argv[])
            {
                QApplication app(argc, argv);
            
            #ifdef QT_KEYPAD_NAVIGATION
                QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
            #endif
            
                MainWindow window;
            
                bool smallScreen = QApplication::arguments().contains(QStringLiteral("-small-screen"));
                if (smallScreen)
                    window.showFullScreen();
                else
                    window.show();
            
                return app.exec();
            }
            
            

            mainwidget.cpp

            #include "mainwidget.h"
            #include "movable_child_widget.h"
            
            
            static inline QString MemeFamilleDeProgrammes() { return QStringLiteral("application/x-ceTypeDeProgramme"); }
            // MemeFamilleDeProgrammes définit un type personnalisé de données à transmettre au presse papier.
            // Si deux occurences de ce même programme sont lancées, il sera ainsi possible de passer des widgets
            // d'un programme à l'autre.
            
            
            
            
            MainWidget::MainWidget(QWidget *parent)
                : QWidget(parent)
            {
                this->setFixedWidth(1000);
                this->setFixedHeight(100);
            
                Movable_Child_Widget *newChild = new Movable_Child_Widget("Child widget", this);
                newChild->setAttribute(Qt::WA_DeleteOnClose);
            
                QPalette pal = QPalette();
                this->setGeometry(0, 0, 600, 100);
                pal.setColor(QPalette::Window, QColor("#CC773C")); this->setAutoFillBackground(true); this->setPalette(pal);
            
                setAcceptDrops(true);       // <------------------------ Important de le mettre dans le parent du widget à déplacer
            }
            
            
            
            
            
            void MainWidget::paintEvent(QPaintEvent *event)
            {
                Q_UNUSED(event);
            
            
                QPainter painter(this);
                painter.setPen(Qt::blue);
                //painter.setBrush(QBrush("#539e47"));
                painter.drawRect(0, 0, this->width()-1, this->height()-1);
            
            
                // on place les quarts d'heures
                QPen pen0(Qt::green);
                pen0.setWidth(1);
                pen0.setStyle(Qt::DashDotLine);
                painter.setPen(pen0);
                for (int i=0; i<=24*4; i++){
                    painter.drawLine(int (i*this->width()/96),int (0.5*this->height()-10), int (i*this->width()/96), int (0.5*this->height()+10));
                }
            
                // on place les heures
                QPen pen1(Qt::blue);
                pen1.setWidth(3);
                painter.setPen(pen1);
                //painter.setPen(Qt::blue);
                for (int i=0; i<=24; i++){
                    painter.drawLine(int (i*this->width()/24), int (0.5*this->height()-10), int (i*this->width()/24), int (0.5*this->height()+10));
                }
            
                //updateGeometry();
            }
            
            
            
            
            
            void MainWidget::dragEnterEvent(QDragEnterEvent *event)
            {
                if (event->mimeData()->hasFormat(MemeFamilleDeProgrammes())) {
                    if (children().contains(event->source())) {
                        event->setDropAction(Qt::MoveAction);
                        event->accept();
                    } else {
                        event->acceptProposedAction();
                    }
            
                } else if (event->mimeData()->hasText()) {
                    event->acceptProposedAction();
                } else {
                    event->ignore();
                }
            
            }
            
            
            
            void MainWidget::dragMoveEvent(QDragMoveEvent *event)
            {
                if (event->mimeData()->hasFormat(MemeFamilleDeProgrammes())) {
                    if (children().contains(event->source())) {
                        event->setDropAction(Qt::MoveAction);
                        event->accept();
                    } else {
                        event->acceptProposedAction();
                    }
                } else if (event->mimeData()->hasText()) {
                    event->acceptProposedAction();
                } else {
                    event->ignore();
                }
            
            }
            
            
            
            
            void MainWidget::dropEvent(QDropEvent *event)
            {
                if (event->mimeData()->hasFormat(MemeFamilleDeProgrammes())) {
                    const QMimeData *mime = event->mimeData();
            
                    QByteArray itemData = mime->data(MemeFamilleDeProgrammes());
                    QDataStream dataStream(&itemData, QIODevice::ReadOnly);
            
                    QString text;
                    QPoint offset;
                    dataStream >> text >> offset;
                    Movable_Child_Widget *newChild = new Movable_Child_Widget(text, this);
                    newChild->move(event->pos() - offset);
                    newChild->show();
                    newChild->setAttribute(Qt::WA_DeleteOnClose);
            
                    if (event->source() == this) {
                        event->setDropAction(Qt::MoveAction);
                        event->accept();
                    } else {
                        event->acceptProposedAction();
                    }
            
                } else if (event->mimeData()->hasText()) {
                    QStringList pieces = event->mimeData()->text().split(QRegularExpression(QStringLiteral("\\s+")));
                    QPoint position = event->pos();
            
                    for (const QString &piece : pieces) {
                        Movable_Child_Widget *newChild = new Movable_Child_Widget(piece, this);
                        newChild->move(position);
                        newChild->show();
                        newChild->setAttribute(Qt::WA_DeleteOnClose);
            
                        position += QPoint(newChild->width(), 0);
                    }
            
                    event->acceptProposedAction();
                } else {
                    event->ignore();
                }
            }
            
            
            
            void MainWidget::mousePressEvent(QMouseEvent *event)
            {
                Movable_Child_Widget *child = static_cast<Movable_Child_Widget*>(childAt(event->pos()));
                if (!child)
                    return;
            
                QPoint hotSpot = event->pos() - child->pos();
            
                QByteArray itemData;
                QDataStream dataStream(&itemData, QIODevice::WriteOnly);
                dataStream << child->labelText() << QPoint(hotSpot);
            
                QMimeData *mimeData = new QMimeData;
                mimeData->setData(MemeFamilleDeProgrammes(), itemData);
                mimeData->setText(child->labelText());
            
                QDrag *drag = new QDrag(this);
                drag->setMimeData(mimeData);
            
                const QPixmap *ch = child->pixmap();     drag->setPixmap(*ch);
            
                drag->setHotSpot(hotSpot);
            
                child->hide();
            
                //if (drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::CopyAction) == Qt::MoveAction)
                if (drag->exec(Qt::MoveAction))
                    child->close();
                else
                    child->show();
            }
            

            mainwindow.cpp

            #include "movable_child_widget.h"
            #include "mainwindow.h"
            #include "mainwidget.h"
            
            
            
            
            MainWindow::MainWindow(QWidget *parent)
                : QWidget(parent)
            {
                setWindowTitle(tr("Fenêtre principale"));            //
                QPalette newPalette = palette();                     // Fenêtre principale
                newPalette.setColor(QPalette::Window, Qt::gray);     //
                setPalette(newPalette);                              //
                this->setWindowState(Qt::WindowMaximized);           //
                this->setFixedSize(2000, 1000);           //
            
            
                MainWidget *Widget1 = new MainWidget(this);          // Création d'un premier widget
                Widget1->move(200, 200);                             //
            
                MainWidget *Widget2 = new MainWidget(this);          // Création d'un second widget
                Widget2->move(200, 400);                             //
            
            }
            

            movable_child_widget.cpp

            #include "movable_child_widget.h"
            
            
            
            Movable_Child_Widget::Movable_Child_Widget(const QString &text, QWidget *parent)
                : QLabel(parent)
            {
                QFontMetrics metric(font());
                QSize size = metric.size(Qt::TextSingleLine, text);
            
                QImage image(size.width() + 12, size.height() + 12, QImage::Format_ARGB32_Premultiplied);
                image.fill(qRgba(0, 0, 0, 0));
            
                QFont font;
                font.setStyleStrategy(QFont::ForceOutline);
            
                QLinearGradient gradient(0, 0, 0, image.height()-1);
                gradient.setColorAt(0.0, Qt::white);
                gradient.setColorAt(0.2, QColor(200, 200, 255));
                gradient.setColorAt(0.8, QColor(200, 200, 255));
                gradient.setColorAt(1.0, QColor(127, 127, 200));
            
                QPainter painter;
                painter.begin(&image);
                painter.setRenderHint(QPainter::Antialiasing);
                painter.setBrush(gradient);
                painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1), 25, 25, Qt::RelativeSize);
            
                painter.setFont(font);
                painter.setBrush(Qt::black);
                painter.drawText(QRect(QPoint(6, 6), size), Qt::AlignCenter, text);
                painter.end();
            
                QPushButton *bt = new QPushButton ("bt", this);
                bt->move(this->width()/2, 0);
            
                setPixmap(QPixmap::fromImage(image));
            
                m_labelText = text;
            }
            
            
            QString Movable_Child_Widget::labelText() const
            {
                return m_labelText;
            }
            
            
            1 Reply Last reply
            1

            2/5

            6 Sept 2021, 18:27

            • Login

            • Login or register to search.
            2 out of 5
            • First post
              2/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved