Attention question changed (added a piece of code)

Hello!

How to create a custom widget in the form of a form, and then you could move it around the form. Those. there is a form, and inside it there is a widget that moves inside the form. And there, for example, he has LineEdit, PushButton .

It is possible through the drawline , but it does not roll like that, I need the widget to move while holding the left mouse button

Sample form:

Sample form

If it is not possible, then how is this area to be moved, via mouse pressed ?

  #include <QtGui> int main(int argc, char *argv[]) { QApplication a(argc, argv); QGraphicsScene scene(QRectF(-100, -100, 300, 300)); QGraphicsView view(&scene); QTextEdit* text = new QTextEdit(); text->setFixedSize(100,30); text->setGeometry(-40,-70,100,30); QGraphicsProxyWidget* widgetItem = scene.addWidget(text); widgetItem->setFlag(QGraphicsItem::ItemIsMovable, true);//Π’Π°ΠΊ Π½Π΅ пСрСдвигаСтся ΠΏΠΎ Ρ„ΠΎΡ€ΠΌΠ΅ QPushButton cmd("Button"); widgetItem = scene.addWidget(&cmd); widgetItem->setFlag(QGraphicsProxyWidget::ItemIsMovable); QGraphicsRectItem* rect = new QGraphicsRectItem(0, &scene); rect->setBrush(QBrush(Qt::gray)); rect->setRect(QRectF(-20, -20, 120, 70)); rect->setFlags(QGraphicsItem::ItemIsMovable); view.show(); return a.exec(); } 

That's what I want to do

It turns out you have to add a mouse pressed event? Or, as in the example of alexeinaumov , add the class MyWidget?

New question . The campaign that the button is pressed or edited cannot be moved. Whereas, it can be done so that, inside some area (the area we will have to specify through QGraphicsItem) there was a button (QGraphicsProxyWidget) and it (using QGraphicsItem) moved, i.e. is the button inside the area and using the area moving?

  • Looked, it turns out I do not use QGraphicsWidget, only I inherit from it? - marioxxx
  • You can inherit if conveniently, you can use QGraphicsProxyWidget) From the documentation: Note: QWidget-based widgets can be directly embedded into a QGraphicsScene using QGraphicsProxyWidget. - progzdeveloper 6:24 pm
  • one
    Good day! I understand that you want to move a group of objects: a button and some area. In this case, use QGraphicsGroupItem. Add your button and area to it. - progzdeveloper
  • button is not Item ... - marioxxx
  • one
    Hmmm .. I meant a button like QGraphicsProxyWidget. There is also a method: You can make your proxy for a button a child of a region for example (code did not check): QGraphicsRectItem* rect = new QGraphicsRectItem(0, &scene); rect->setBrush(QBrush(Qt::gray)); rect->setRect(QRectF(-20, -20, 120, 70)); rect->setFlags(QGraphicsItem::ItemIsMovable); QPushButton cmd("Button"); QGraphicsProxyWidget *btnProxy = new QGraphicsProxyWidget(rect, &scene); // btnProxy Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ для rect btnProxy->setWidget(&cmd); btnProxy->setFlag(QGraphicsProxyWidget::ItemIsMovable); QGraphicsRectItem* rect = new QGraphicsRectItem(0, &scene); rect->setBrush(QBrush(Qt::gray)); rect->setRect(QRectF(-20, -20, 120, 70)); rect->setFlags(QGraphicsItem::ItemIsMovable); QPushButton cmd("Button"); QGraphicsProxyWidget *btnProxy = new QGraphicsProxyWidget(rect, &scene); // btnProxy Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ для rect btnProxy->setWidget(&cmd); btnProxy->setFlag(QGraphicsProxyWidget::ItemIsMovable); - progzdeveloper

2 answers 2

.h-file of the widget that we drag

 #ifndef MYWIDGET_H #define MYWIDGET_H #include <QtGui> #include "ui_MyWidget.h" class MyWidget : public QWidget, public Ui::MyWidgetClass { Q_OBJECT public: MyWidget(QWidget *parent = 0); ~MyWidget(); QPoint mousePressPoint() const {return _mousePressPoint;} protected: void mouseMoveEvent (QMouseEvent* mouseEvent); void mousePressEvent(QMouseEvent* mouseEvent); void mouseReleaseEvent(QMouseEvent* mouseEvent); signals: void move(const QPoint& point); // Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΌΡ‹ΡˆΠΈ ΠΏΡ€ΠΈ пСрСтаскивании Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° private: QPoint _mousePressPoint; // ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ Π½Π° Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π΅ bool _isBeingDragged; // выполняСтся Π»ΠΈ пСрСтаскиваниС Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π°? }; #endif // MYWIDGET_H 

The .cpp file of the widget that we drag

 #include "MyWidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { setupUi(this); } MyWidget::~MyWidget() { } void MyWidget::mouseMoveEvent (QMouseEvent* mouseEvent) { if (_isBeingDragged) emit move(mouseEvent->pos()); } void MyWidget::mousePressEvent(QMouseEvent* mouseEvent) { _isBeingDragged = true; // Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ пСрСтаскиваниС Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° _mousePressPoint = mouseEvent->pos(); // сохраняСм ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ } void MyWidget::mouseReleaseEvent(QMouseEvent* mouseEvent) { _isBeingDragged = false; // Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅ΠΌ пСрСтаскиваниС Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° } 

.h-file of the widget on which we are dragging

 #ifndef DIALOG_H #define DIALOG_H #include <QtGui> #include <QDebug> #include "ui_Dialog.h" #include "MyWidget.h" class Dialog : public QDialog, public Ui::DialogClass { Q_OBJECT public: Dialog(QWidget* parent = 0); ~Dialog(); private slots: void onMove(const QPoint& point); private: MyWidget* _myWidget; }; #endif // DIALOG_H 

The .cpp file of the widget on which we are dragging

 #include "Dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent) { setupUi(this); _myWidget = new MyWidget(this); bool result = true; result &= connect(_myWidget, SIGNAL(move(const QPoint&)), this, SLOT(onMove(const QPoint&))); if (!result) qDebug() << "Error connecting signals and slots in " << __PRETTY_FUNCTION__; } Dialog::~Dialog() { } void Dialog::onMove(const QPoint& point) { QRect before = _myWidget->geometry(); // располоТСниС Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° Π΄ΠΎ пСрСтаскиваниz QRect after; // располоТСниС Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° послС пСрСтаскивания int deltaX = point.x()-_myWidget->mousePressPoint().x(); // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΡ‹ΡˆΠΈ ΠΏΠΎ оси X int deltaY = point.y()-_myWidget->mousePressPoint().y(); // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΡ‹ΡˆΠΈ ΠΏΠΎ оси Y after.setX(before.x()+deltaX); after.setY(before.y()+deltaY); after.setWidth(before.width()); after.setHeight(before.height()); _myWidget->setGeometry(after); // ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ полоТСния Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° } 

main.cpp

 #include "Dialog.h" #include <QtGui> #include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); Dialog dialog; dialog.show(); return app.exec(); } 

Sources here

  • Thank you !!) It turns out that you can still add widgets that we drag (for example mywidget2.cpp)? Those. For example, when you click on the push button, another widget is added to the widget on which we are dragging. - marioxxx
  • I made an addition when I clicked, first I create two objects, then I put the second one setvisible (false), then when I click on the button I put setvisible (true). So right?) - marioxxx
  • Adding the second widget when I clicked on the button, first I create two objects, then I put the second setvisible (false), then when I click on the button I put setvisible (true). - Alexei Naumov
  • one
    In "Qt Examples and Demos" there is a detailed example of creating custom components with the ability to drag and drop around the scene. It is called "Ported Canvas" and is located in the "Graphics View" tab. Just what you are looking for. - Alexei Naumov
  • The campaign that the button is being pressed or edited does not work, as it can be done so that within some area (the Area will be set via QGraphicsItem) there was a button (QGraphicsProxyWidget) and it (via QGraphicsItem) moved, i.e. button with area? - marioxxx 4:34 pm

Good day!
Use QGraphicsWidget in conjunction with QGraphicsScene and QGraphicsView .

  • Upstairs added program code - marioxxx