• 12373阅读
  • 5回复

Qt5实现类似cad画图功能 [复制链接]

上一主题 下一主题
离线ingenious
 

只看楼主 倒序阅读 楼主  发表于: 2015-11-07
— 本帖被 XChinux 执行加亮操作(2016-04-23) —
MyWidget.cpp (2 K) 下载次数:58 MyWidget.h (1 K) 下载次数:52 T08Draw.pro (1 K) 下载次数:44 包含三个文件Draw.pro  MyWidget .h   MyWidget.cpp

Draw.pro:
   QT += core widgets gui
HEADERS += \    MyWidget.h
SOURCES += \    MyWidget.cpp

MyWidget .h :
  #ifndef MYWIDGET_H#define MYWIDGET_H
#include <QWidget>
typedef struct MyLine{    QPoint startPnt;    QPoint endPnt;}myLine;

class MyWidget : public QWidget{    Q_OBJECTpublic:    explicit MyWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *);
    void mouseMoveEvent(QMouseEvent *);    void mousePressEvent(QMouseEvent *);    void mouseReleaseEvent(QMouseEvent *);


signals:
public slots:
public:    //QVector< QVector<QPoint> > lines;
    QPoint startPnt;    QPoint endPnt;
    QVector<myLine*> lines;    bool isPressed;
};
#endif // MYWIDGET_H

MyWidget.cpp
#include "MyWidget.h"#include <QPainter>#include <QPixmap>#include <QMouseEvent>#include <QDebug>
MyWidget::MyWidget(QWidget *parent) :    QWidget(parent){
}

void MyWidget::paintEvent(QPaintEvent *) //执行过程painting-pressed-moved-painting-released{
    QPainter painter(this);    if(startPnt != endPnt)        painter.drawLine(startPnt, endPnt);
    for(int i = 0;i<lines.size();i++)    {              //重绘时需要画出所有线        myLine* pLine = lines;        painter.drawLine(pLine->startPnt,pLine->endPnt);    }}
void MyWidget::mouseMoveEvent(QMouseEvent *ev){

    if(isPressed==false)//鼠标移动,但是鼠标是松开的    {        endPnt = ev->pos();        update();        qDebug()<<ev->pos();    }    else    {        setMouseTracking(false);    }}void MyWidget::mousePressEvent(QMouseEvent *ev){    isPressed=true;    if (hasMouseTracking())    {        myLine* line = new myLine;        line->startPnt = startPnt;        line->endPnt = endPnt;        this->lines.push_back(line);
        setMouseTracking(false);    }    else    {        startPnt = endPnt = ev->pos();        setMouseTracking(true);//默认情况下mouse tracking是false的,由于左键被按下之后,被设为了true,所以在上面要被设为false        update();    }}
void MyWidget::mouseReleaseEvent(QMouseEvent *ev){
    isPressed = false;    update();    qDebug()<<lines.size();}

#include <QApplication>int main(int argc, char** argv){    QApplication app(argc, argv);
    MyWidget w;    w.show();
    return app.exec();}


上面的代码,实现了鼠标点击两点画直线,但我想对上面实现改进:
如何才能实现画多条折线,每画完一条折线后,用滚轮键结束命令,总之一句话就是类似于cad画直线的操作,最好也要像cad一样,弹出一个LineEdit,在里面输入点的位置画直线。希望各路大神,积极发表意见,感激不尽,这样每个人都能学到知识!



本帖提到的人: @XChinux @zzs0829 @1123078843
离线z609932088

只看该作者 1楼 发表于: 2015-11-12
帮你顶,希望楼主分享更多的优秀代码


我的想法就是申请一个list  这里面放着你的点的坐标,这样才能实现重回


还有一种方法就是自己新建一个widget
将你鼠标的上一个点和现在当前点击的点传入这个widet 需要做坐标转换
完了再讲这个widget显示到这个途中
有阳光的地方就是青春

只看该作者 2楼 发表于: 2015-11-12
建议你看看QGraphicsView
博客地址:https://waleon.blog.csdn.net
微信公众号:高效程序员
QQ 群:242790253
微信群:加微信(iwaleon),邀请入群。

承接各种 C++/Qt/QML 项目,专业的团队,一流的服务,不二的选择!
离线yyzq

只看该作者 3楼 发表于: 2015-11-12
http://www.qcad.org/en/https://github.com/LibreCAD/LibreCAD都是开源的,可以拿去参考
离线tylan

只看该作者 4楼 发表于: 2015-11-13
画图的话,使用qt的视图场景模型会比你用widget有优势,画折线,可以根据鼠标事件,当鼠标按下的时候画出一个点,然后当鼠标移动的时候画出直线,并不断改变直线的角度和长度,当松开的时候记录直线结束的点作为下一条直线的起点。
离线dplusplus

只看该作者 5楼 发表于: 2015-11-13
现在我也写这个;用的类似状态机,对每个draw item type定义和维护一个State,针对mouse Press/Move/Release切换state.
QQ: 1262-3572-97 @SUZHOU
快速回复
限100 字节
 
上一个 下一个