网站后台管理系统模板 html,古典 网站模板,xampp本地搭建网站,湛江网站制作之前项目上需要用Qt来绘制可拖拽改变形状的矩形。看了Qt Graphics相关的内容#xff0c;虽然对Qt怎么添加图元的有了些了解#xff0c;但是具体如何实现拖拽效果#xff0c;一时也没有什么好的想法。还好网上有人分享的例子#xff0c;很受启发。后来又回顾了一下这部分的代…之前项目上需要用Qt来绘制可拖拽改变形状的矩形。看了Qt Graphics相关的内容虽然对Qt怎么添加图元的有了些了解但是具体如何实现拖拽效果一时也没有什么好的想法。还好网上有人分享的例子很受启发。后来又回顾了一下这部分的代码发现了一种新的实现方式。希望这个例子也能帮助到需要的人吧。
这几篇文章对这个例子的顺利实现很有帮助非常感谢。
通过QGraphicsItem绘制可拖拽改变大小的矩形_qt 绘制多个可拖动矩形-CSDN博客
QGraphicsSceneBspTree::climbTree崩溃自记-CSDN博客
关于QGraphicsItem的scenePos一直为(0,0)的解决方案_qt scenepos-CSDN博客
运行效果 完整代码如下
GraphicsViewTest2.pro
QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES \main.cpp \mainwindow.cpp \mylane.cpp \testrect.cpp \testview.cppHEADERS \mainwindow.h \mylane.h \testrect.h \testview.hFORMS \mainwindow.ui# Default rules for deployment.
qnx: target.path /tmp/$${TARGET}/bin
else: unix:!android: target.path /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS targetmainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QGraphicsScene
#include mylane.h
#include testrect.hQT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();QListMyLane* laneList;
private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();private:Ui::MainWindow *ui;QGraphicsScene *scene;
};
#endif // MAINWINDOW_H
mylane.h
#ifndef MYLANE_H
#define MYLANE_H#include QGraphicsObject
#include testrect.hclass MyLane : public QGraphicsObject
{Q_OBJECT
public:explicit MyLane(QGraphicsObject *parent nullptr);~MyLane();QRectF boundingRect() const override;void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;void addToScene();void removeFromScene();
public:TestRect *item1;TestRect *item2;TestRect *item3;TestRect *item4;public slots:void updateLane();
};#endif // MYLANE_H
testrect.h
#ifndef TESTRECT_H
#define TESTRECT_H#include QGraphicsRectItemclass TestRect : public QObject, public QGraphicsRectItem
{Q_OBJECT
public:TestRect(qreal x, qreal y, qreal w, qreal h, QGraphicsRectItem *parent nullptr);~TestRect();void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;void mousePressEvent(QGraphicsSceneMouseEvent *event) override;TestRect operator(const TestRect pt);QPointF point;
public slots:void moveMove(QPointF point);
signals:void sendPos(QPointF point);
};#endif // TESTRECT_Htestview.h
#ifndef TESTVIEW_H
#define TESTVIEW_H#include QGraphicsViewclass TestView : public QGraphicsView
{Q_OBJECT
public:TestView(QWidget *parent nullptr);void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;
signals:void mouseMovePoint(QPoint point);void mouseClicked(QPoint point);
};#endif // TESTVIEW_H
main.cpp
#include mainwindow.h#include QApplicationint main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}mainwindow.cpp
#include mainwindow.h
#include ui_mainwindow.h
#include QGraphicsItem
#include QGraphicsRectItem
#include QDebugMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);QRectF rect(-200, -100, 400, 200);scene new QGraphicsScene(rect);//不加下面这行发现删除矩形的时候程序会概率性的挂在QGraphicsSceneBspTree函数里什么原因我也不清楚有清楚的欢迎留言指正scene-setItemIndexMethod(QGraphicsScene::NoIndex);QGraphicsRectItem *item new QGraphicsRectItem(rect);//item-setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsSelectable);QPen pen;pen.setWidth(2);item-setPen(pen);scene-addItem(item);ui-graphicsView-setScene(scene);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{if(!laneList.isEmpty()){MyLane* lane laneList.first();lane-removeFromScene();scene-removeItem(lane);laneList.removeOne(lane);delete lane;lane nullptr;}
}void MainWindow::on_pushButton_2_clicked()
{MyLane* lane new MyLane;scene-addItem(lane);lane-addToScene();laneList.append(lane);
}
mylane.cpp
#include mylane.h
#include testrect.h
#include QGraphicsScene
#include QGraphicsRectItem
#include QPainter
#include QDebugMyLane::MyLane(QGraphicsObject *parent) : QGraphicsObject(parent)
{item1 new TestRect(0, 0, 10, 10);item1-setFlags(QGraphicsItem::ItemIsFocusable |QGraphicsItem::ItemIsSelectable |QGraphicsItem::ItemIsMovable);item1-setPos(0, 0);item2 new TestRect(0, 0, 10, 10);item2-setFlags(QGraphicsItem::ItemIsFocusable |QGraphicsItem::ItemIsSelectable |QGraphicsItem::ItemIsMovable);item2-setPos(100, 0);item3 new TestRect(0, 0, 10, 10);item3-setFlags(QGraphicsItem::ItemIsFocusable |QGraphicsItem::ItemIsSelectable |QGraphicsItem::ItemIsMovable);item3-setPos(100, -100);item4 new TestRect(0, 0, 10, 10);item4-setFlags(QGraphicsItem::ItemIsFocusable |QGraphicsItem::ItemIsSelectable |QGraphicsItem::ItemIsMovable);item4-setPos(0, -100);connect(item1, TestRect::sendPos, item2, TestRect::moveMove);connect(item2, TestRect::sendPos, item1, TestRect::moveMove);connect(item3, TestRect::sendPos, item4, TestRect::moveMove);connect(item4, TestRect::sendPos, item3, TestRect::moveMove);connect(item1, TestRect::sendPos, this, MyLane::updateLane);connect(item2, TestRect::sendPos, this, MyLane::updateLane);connect(item3, TestRect::sendPos, this, MyLane::updateLane);connect(item4, TestRect::sendPos, this, MyLane::updateLane);}
MyLane::~MyLane(){qDebug() ~MyLane;delete item1;delete item2;delete item3;delete item4;item1 nullptr;item2 nullptr;item3 nullptr;item4 nullptr;
}
QRectF MyLane::boundingRect() const{QVectorfloat vecX;QVectorfloat vecY;vecX.append(item1-x());vecX.append(item2-x());vecX.append(item3-x());vecX.append(item4-x());vecY.append(item1-y());vecY.append(item2-y());vecY.append(item3-y());vecY.append(item4-y());float minX *std::min_element(std::begin(vecX), std::end(vecX));float minY *std::min_element(std::begin(vecY), std::end(vecY));float maxX *std::max_element(std::begin(vecX), std::end(vecX));float maxY *std::max_element(std::begin(vecY), std::end(vecY));QPointF startPoint(minX, minY);QPointF endPoint(maxX, maxY);QPointF pointOffset(10, 10);return { startPoint, endPoint pointOffset};
}void MyLane::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
// qDebug() item1: item1-pos();
// qDebug() item2: item2-pos();
// qDebug() item3: item3-pos();
// qDebug() item4: item4-pos();painter-save();painter-setPen(Qt::blue);painter-drawLine(item1-pos(), item2-pos());painter-drawLine(item2-pos(), item3-pos());painter-drawLine(item3-pos(), item4-pos());painter-drawLine(item4-pos(), item1-pos());
// painter-drawRect(boundingRect());
// qDebug() boundingRect: boundingRect().x() boundingRect().y() boundingRect().width() boundingRect().height();painter-restore();
}void MyLane::addToScene(){if(scene()){scene()-addItem(item1);scene()-addItem(item2);scene()-addItem(item3);scene()-addItem(item4);}
}
void MyLane::removeFromScene(){if(scene()){scene()-removeItem(item1);scene()-removeItem(item2);scene()-removeItem(item3);scene()-removeItem(item4);}
}void MyLane::updateLane(){scene()-update();
}testrect.cpp
#include testrect.h
#include QGraphicsSceneMouseEvent
#include QDebugTestRect::TestRect(qreal x, qreal y, qreal w, qreal h, QGraphicsRectItem *parent): QGraphicsRectItem(x, y, w, h, parent)
{}
void TestRect::mouseMoveEvent(QGraphicsSceneMouseEvent *event){emit sendPos(event-pos() - point);QGraphicsRectItem::mouseMoveEvent(event);
}
void TestRect::mousePressEvent(QGraphicsSceneMouseEvent *event){point event-pos();QGraphicsRectItem::mousePressEvent(event);
}void TestRect::moveMove(QPointF point){moveBy(point.x(), point.y());
}
TestRect TestRect::operator(const TestRect pt){setPos(pt.pos());return *this;
}
TestRect::~TestRect(){qDebug() ~TestRect;
}testview.cpp
#include testview.h#include QMouseEvent
#include QDebugTestView::TestView(QWidget *parent)
{}void TestView::mousePressEvent(QMouseEvent *event){if(event-button() Qt::LeftButton){QPoint point event-pos();qDebug() view: point;qDebug() scene: mapToScene(point);}QGraphicsView::mousePressEvent(event);
}void TestView::mouseMoveEvent(QMouseEvent *event){QGraphicsView::mouseMoveEvent(event);
}mainwindow.ui
?xml version1.0 encodingUTF-8?
ui version4.0classMainWindow/classwidget classQMainWindow nameMainWindowproperty namegeometryrectx0/xy0/ywidth800/widthheight600/height/rect/propertyproperty namewindowTitlestringMainWindow/string/propertywidget classQWidget namecentralwidgetlayout classQGridLayout namegridLayoutitem row0 column0widget classQGraphicsView namegraphicsView//itemitem row1 column0layout classQHBoxLayout namehorizontalLayoutitemspacer namehorizontalSpacerproperty nameorientationenumQt::Horizontal/enum/propertyproperty namesizeHint stdset0sizewidth40/widthheight20/height/size/property/spacer/itemitemwidget classQPushButton namepushButton_2property nametextstringAdd/string/property/widget/itemitemwidget classQPushButton namepushButtonproperty nametextstringRemove/string/property/widget/item/layout/item/layout/widgetwidget classQMenuBar namemenubarproperty namegeometryrectx0/xy0/ywidth800/widthheight26/height/rect/property/widgetwidget classQStatusBar namestatusbar//widgetresources/connections/
/ui