#cpp #qt #gui #qt5 #интерфейс
Я работаю в qt5. Эта кнопка("addButton") отвечает за создание этих кнопок("GreenButton") . В слоте addButton создается GreenButton: void SearchForm::on_AddButtonButton_pressed() { Editor.pobj = new GreenButton(this); } Код GreenButton: QPoint delta; void mousePressEvent(QMouseEvent* e) { delta.rx() = e->pos().x(); delta.ry() = e->pos().y(); } void mouseMoveEvent(QMouseEvent* e) { setGeometry( geometry().x() + e->pos().x() - delta.x(), geometry().y() + e->pos().y() - delta.y(), width(), height() ); } explicit GreenButton(QWidget *parent = 0 ) { setGeometry(QCursor::pos().x() - parent->geometry().x() - 8, QCursor::pos().y() - parent->geometry().y() - 8, 111, 111 ); show(); QMouseEvent event1(QEvent::MouseButtonPress, this->pos(), Qt::LeftButton,Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(this, &event1); } GreenButton создается , перемещается мышью. Как сделать чтобы при нажатии на addButton и не отпускании ее перемещался GreenButton? Я думал поможет искуственное создание событий, но не помогло: QMouseEvent event1(QEvent::MouseButtonPress, this->pos(), Qt::LeftButton,Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(this, &event1);
Ответы
Ответ 1
Т.к. у нас есть форма, на которой размещена «добавляющая кнопка», и на ту же форму мы добавляем другие кнопки, предлагаю воспользоваться следующей стратегией: Устанавливаем фильтр сообщений на нашу «добавляющую» кнопку. Будем ловить нажатие и перемещение мыши. Во время нажатия будем создавать новую кнопку и запоминать её. Во время появления события перемещения, будем перемещать нашу кнопку. Всё это довольно просто реализовать: MainWindow.h: #pragma once #includeclass QPushButton; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget* parent = 0); bool eventFilter(QObject* obj, QEvent* event); private: QPushButton* m_CurrentButton; }; MainWindow.cpp: #include #include #include #include #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { auto widget = new QWidget(this); auto addButton = new QPushButton("add", widget); setCentralWidget(widget); addButton->installEventFilter(this); } bool MainWindow::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::MouseButtonPress) { auto mouseEvent = static_cast (event); m_CurrentButton = new QPushButton("new", centralWidget()); auto localPoint = mapFromGlobal(mouseEvent->globalPos()); m_CurrentButton->move(localPoint); m_CurrentButton->show(); return true; } if(event->type() == QEvent::MouseMove) { auto mouseEvent = static_cast (event); auto localPoint = mapFromGlobal(mouseEvent->globalPos()); m_CurrentButton->move(localPoint); return true; } return QObject::eventFilter(obj, event); } На базе этого кода, Вы можете адаптировать свой код. Ответ 2
Сначала решение: class MyForm: public QWidget { QTimer * Ticker ; QPushButton * MovingButton; public: MyForm(QWidget * parent = nullptr) : QWidget (parent ) , Ticker (nullptr) , MovingButton(nullptr) { Ticker = new QTimer(this); connect(Ticker, &QTimer::timeout, this, &MyForm::moveButton); } ~MyForm() { stopMoving(); } public slots: void addPressed() { MovingButton = new QPushButton(this); // настраиваем новую кнопку MovingButton->show(); // Начинаем перемещение через пол секунды Ticker->setSigngleShot(true); Ticker->setInterval(500); Ticker->start(); } void addReleased() { stopMoving(); // останавливаем движение } void moveButton() { if(MovingButton) { if(Ticker->singleShot()) // ускоряем таймер до 30 мс { Tciker->setSignleShot(false); Ticker->setInterval(30); } // двигаем кнопку MovingButton->move(MovingButton->pos() + QPoint(8,8)); } } private: void stopMoving() { MovingButton = nullptr; Ticker->stop(); } }; Здесь addPressed() и addReleased() слоты которые должны быть подключены с сигналам кнопки AddButton pressed() и released() соответственно. Работает код следующим образом: В обработчике нажатия addPressed() создаем новую кнопку и запоминаем указатель на нее в MovingButton, потом стартуем таймер Ticker на пол секунды по окончании которого выполняем перемещение. Пол секунды нужно для того чтобы была пауза перед началом движения. В обработчике таймера Ticker moveButton() ускоряем таймер до 30 мс а также перемещаем текущую кнопку MovingButton если таковая имеется. В обработчике отпускания addRelease() просто зануляем указатель на перемещаемую кнопку MovingButton и останавливаем таймер Ticker - таким образом останаваливаем движение.Ответ 3
предложу необычный вариант: - AddButton сделать наследником от GreenButton - Как только AddButton кликнули, что означает добавление, AddButton меняет своё рисование, на рисование предка. То есть, начинает рисоваться, как GreenButton. - Новый AddButton на месте старого можно сделать как в начале таскания, так и по его окончанию - зависит от сценария
Комментариев нет:
Отправить комментарий