【qt】CAD下

简介: 【qt】CAD下

一.前言

我的发,好久没有更新了,忙着考试去了,只剩下最后一科英语了,我赶紧来更新,哈哈,上节课我们的CAD项目还没有做完呢,OK,那就来咯!

我们上节课的成果:

上节课我们只实现了左边工具栏的功能,但是我们上面的工具栏的功能还没有进行实现,所以我们现在话不多说,直接开干!

二.缩放

1.逻辑

我们可以选择一个或者多个图形项

为了演示功能,我们如果选择的一个就对图形项进行缩放

如果选择的多个就对视图进行缩放

2.获取图形项选中的个数

void MainWindow::on_actionBig_triggered()
{
    int count=scene->selectedItems().count();
}

看不懂?不存在的,看我的

**selectedItems()返回的一个装图形项指针的列表,所以我们可以用count()**来统计个数,哈哈.

3.获取图形项并放大

if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setScale(item->scale()+0.1);
    }

如果选中的个数为1,那么是对图形项进行操作!

刚刚说了**selectedItems()返回的是一个列表,所以可以用at()**来获取到图形项.

**setScale()**见名知意,这个就是用来缩放图形项的,此处是在原有的基础上进行缩放.

4.视图缩放

其他的情况我们就用视图的缩放

else
    {
        ui->graphicsView->scale(1.1,1.1);
    }

可以直接设置,不用像图形项一样获取原来的,因为看下图的翻译

5.完整代码

void MainWindow::on_actionBig_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setScale(item->scale()+0.1);
    }
    else
    {
        ui->graphicsView->scale(1.1,1.1);
    }
}

6.效果展示

这个是放大了的,可惜暂时还不会给你录动态图进行展示,哈哈.

7.缩小完整代码

解:由上同理可得,哈哈,想起了我的初中数学.

void MainWindow::on_actionSmall_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setScale(item->scale()-0.1);
    }
    else
    {
        ui->graphicsView->scale(0.9,0.9);
    }
}

运行结果就你们自己去试了!

三.旋转

1.图形项进行旋转

讲过的地方我就不讲了.

int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(item->rotation()-30);
    }

还是在原有的基础上进行旋转.

2.视图的旋转

else
    {
        ui->graphicsView->rotate(-30);
    }

负号是逆时针进行旋转哦.

3.完整代码

void MainWindow::on_actionLeft_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(item->rotation()-30);
    }
    else
    {
        ui->graphicsView->rotate(-30);
    }
}

4.效果展示

5.右转代码

void MainWindow::on_actionRight_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(item->rotation()+30);
    }
    else
    {
        ui->graphicsView->rotate(+30);
    }
}

四.恢复

1.图形项复原

int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(0);
        item->setScale(1.0);
    }

只需要将缩放倍数设置为1,旋转设置为0即可

2.视图复原

else
    {
        ui->graphicsView->resetTransform();
    }

3.完整代码

void MainWindow::on_actionHuifu_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(0);
        item->setScale(1.0);
    }
    else
    {
        ui->graphicsView->resetTransform();
    }
}

4.效果展示

自己去玩完.

五.前后置

1.设置z轴的值

void MainWindow::on_actionTop_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setZValue(item->zValue()+1);
    }
}

在原来的基础上对,z的值进行加1层!

2.后置代码

void MainWindow::on_actionButton_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setZValue(item->zValue()-1);
    }
}

自己去运行效果,我这里运行了,截图你们也看不出来!

六.组合和拆分

1.逻辑

我们将选中的多个图形项,放在一个图形项组中,相当于一个新的图像项.

2.创建图形项组

QGraphicsItemGroup* group=new QGraphicsItemGroup;
scene->addItem(group);

因为组可以视为当个项,所有我们可以添加到场景.

3.图形项添加到组

for(int i=0;i<count;i++)
        {
            auto item=scene->selectedItems().at(0);
            item->setSelected(false);
            item->clearFocus();
            group->addToGroup(item);
        }

当我们添加到组以后,原来的图像项的选中和聚焦状态都取消.

4.设置组的标识

group->setFlags(QGraphicsItem::ItemIsMovable|
                QGraphicsItem::ItemIsSelectable|
                QGraphicsItem::ItemIsFocusable);
        group->setZValue(ZVaule++);
        scene->clearSelection();
        group->setSelected(true);

设置成可选中,可移动,可聚焦,同时设置z轴的值.

并将其设置为新的选中.

5.完整代码

void MainWindow::on_actionZuhe_triggered()
{
    int count=scene->selectedItems().count();
    if(count>1)
    {
        QGraphicsItemGroup* group=new QGraphicsItemGroup;
        scene->addItem(group);
        for(int i=0;i<count;i++)
        {
            auto item=scene->selectedItems().at(0);
            item->setSelected(false);
            item->clearFocus();
            group->addToGroup(item);
        }
        
        group->setFlags(QGraphicsItem::ItemIsMovable|
                        QGraphicsItem::ItemIsSelectable|
                        QGraphicsItem::ItemIsFocusable);
        group->setZValue(ZVaule++);
        scene->clearSelection();
        group->setSelected(true);
    }
    
}

6.效果演示

嘿嘿嘿,自己就可以组合成任何的图像,哈哈哈.

7.拆分代码

获取的图形项,强转类型转换为图形项组然后进行拆分.

void MainWindow::on_actionChaifen_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto group=(QGraphicsItemGroup*)scene->selectedItems().at(0);
        scene->destroyItemGroup(group);
    }
}

8.效果展示

七.删除

1.删除代码

void MainWindow::on_actionDel_triggered()
{
    int count=scene->selectedItems().count();
    if(count>0)
    {
        for(int i=0;i<count;i++)
        {
            auto item=scene->selectedItems().at(0);
            scene->removeItem(item);
        }
    }
}

八.双击编辑图形项颜色

1.逻辑

因为每个图形项的设置颜色方式,不一定相同

有的设置画刷,有的设置画笔,所以我们要对图形项的类型进行判断

因为有很多不同的图形项,所以我们可以用一个模板函数来传参来进行处理.

2.获取图形项的类型

void MainWindow::on_graphicsView_mouseDoubleClick(QPoint point)
{
    int count =scene->selectedItems().count();
    if(count==0)
    {
        return;
    }
    auto item=scene->selectedItems().at(0);
    switch (item->type()) {
    }

type()返回的一个整数,可以用switch来进行判断!

3.画刷模版函数

template <class T>
void setBrushColor(T *item)
{
    QColor color=item->brush().color();
    color=QColorDialog::getColor(color,NULL,"选择填充颜色");
    if(color.isValid())
    {
        item->setBrush(QBrush(color));
    }
}

4.图形项类型的判断

switch (item->type()) {
    case QGraphicsRectItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsRectItem*>(item);
        setBrushColor(item2);
        break;
    }
    case QGraphicsEllipseItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
        setBrushColor(item2);
        break;
    }
    case QGraphicsPolygonItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
        setBrushColor(item2);
        break;
    }
    }

这个几个都是一种类型的,调用模版函数设置画刷的颜色就可以!

5.画笔模版函数

template <class T>
void setPenColor(T*item)
{
    QPen pen;
    QColor color=item->pen().color();
    color=QColorDialog::getColor(color,NULL,"选择填充颜色");
    if(color.isValid())
    {
        pen.setColor(color);
        item->setPen(pen);
    }
}

6.线条图形项

因为不是用画刷进行填充颜色的,所以我们用画笔.

case QGraphicsLineItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsLineItem*>(item);
        setPenColor(item2);
        break;
    }

7.文本图形项

case QGraphicsTextItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsTextItem*>(item);
        QFont font;
        font=item2->font();
        bool ok=false;
        font=QFontDialog::getFont(&ok,font,this,"选择字体");
        if(ok)
        {
            item2->setFont(font);
        }
        break;
    }

用了一个字体对话框.

8.效果展示

非常的银杏.

九.按键微移

1.逻辑

我们上节课不写写了一个键盘事件嘛

现在我们可以根据键盘来对图形项进行操作

2.删除图形项

if(scene->selectedItems().count()!=1)
    {
        return;
    }
    
    auto item=scene->selectedItems().at(0);
    
    if(event->key()==Qt::Key_Delete)
    {
        scene->removeItem(item);
    }

就是键盘上的Delete键

3.旋转图形项

else if(event->key()==Qt::Key_Space)
    {
        item->setRotation(item->rotation()+10);
    }

Key_Space就是空格键.

4.放大,放小

else if(event->key()==Qt::Key_PageUp)
    {
        item->setScale(item->scale()+0.1);
    }
    else if(event->key()==Qt::Key_PageDown)
    {
        item->setScale(item->scale()-0.1);
    }

5.上下左右

else if(event->key()==Qt::Key_Left)
    {
        item->setX(item->x()-1);
    }
    else if(event->key()==Qt::Key_Right)
    {
        item->setX(item->x()+1);
    }
    else if(event->key()==Qt::Key_Up)
    {
        item->setY(item->y()-1);
    }
    else if(event->key()==Qt::Key_Down)
    {
        item->setY(item->y()+1);
    }

6.完整代码

void MainWindow::on_graphicsView_keyPress(QKeyEvent *event)
{
    if(scene->selectedItems().count()!=1)
    {
        return;
    }
    auto item=scene->selectedItems().at(0);
    if(event->key()==Qt::Key_Delete)
    {
        scene->removeItem(item);
    }
    else if(event->key()==Qt::Key_Space)
    {
        item->setRotation(item->rotation()+10);
    }
    else if(event->key()==Qt::Key_PageUp)
    {
        item->setScale(item->scale()+0.1);
    }
    else if(event->key()==Qt::Key_PageDown)
    {
        item->setScale(item->scale()-0.1);
    }
    else if(event->key()==Qt::Key_Left)
    {
        item->setX(item->x()-1);
    }
    else if(event->key()==Qt::Key_Right)
    {
        item->setX(item->x()+1);
    }
    else if(event->key()==Qt::Key_Up)
    {
        item->setY(item->y()-1);
    }
    else if(event->key()==Qt::Key_Down)
    {
        item->setY(item->y()+1);
    }
}

效果自己去用键盘玩哦!

十.鼠标移动

1.逻辑

当我们的鼠标进行移动的时候,我们就显示视图坐标和场景的坐标.

可通过视图坐标转到场景坐标.

同时,我们希望在状态栏中进行显示,所以我们需要在状态栏中,添加标签.

2.状态栏添加标签

我们原来讲过,状态栏添加组件,只能通过代码.

头文件中进行创建:

构造函数中,进行实现:

labView=new QLabel("视图坐标:");
    labScene=new QLabel("场景坐标:");
    labItem=new QLabel("图形项坐标:");
    labInfo=new QLabel("图形项信息:");
    labView->setMinimumWidth(150);
    labScene->setMinimumWidth(150);
    labItem->setMinimumWidth(150);
    labInfo->setMinimumWidth(150);
    this->statusBar()->addWidget(labView);
    this->statusBar()->addWidget(labScene);
    this->statusBar()->addWidget(labItem);
    this->statusBar()->addWidget(labInfo);

运行结果:

3.设置视图,场景坐标

void MainWindow::on_graphicsView_mouseMove(QPoint point)
{
    labView->setText(QString::asprintf("视图坐标:%d,%d",point.x(),point.y()));
    QPointF pointScene=ui->graphicsView->mapToScene(point);
    labScene->setText(QString::asprintf("场景坐标:%.0f,%.0f",pointScene.x(),pointScene.y()));
}

返回的浮点坐标.

4.效果展示

会随着我的鼠标移动而变化!

十一.鼠标单击

1.逻辑

当我们单击一个图形项的时候,就显示图形项坐标和图形项的信息.

2.通过场景坐标获取图形项

QPointF pointScene=ui->graphicsView->mapToScene(point);
auto item=scene->itemAt(pointScene,ui->graphicsView->transform());

通过场景坐标得到场景中的项

3.场景坐标转换成图形项坐标

QPointF pointItem=item->mapFromScene(pointScene);//场景坐标转图形项坐标
labItem->setText(QString::asprintf("图形项坐标:%.0f,%.0f",pointItem.x(),pointItem.y()));

4.设置图形项的信息

还记得我们原理自己定义的数据嘛,就是setDate()

现在我们就可以拿出来用了.

labInfo->setText(item->data(ITEMINFO).toString()+"ITEMID:"+
                         item->data(ITEMID).toString());

这就是当年我们自定义数据的地方

现在就可以根据键来获取到,当时我们设置的图像名称和ID.

5.完整代码

void MainWindow::on_graphicsView_mousePress(QPoint point)
{
    QPointF pointScene=ui->graphicsView->mapToScene(point);
    auto item=scene->itemAt(pointScene,ui->graphicsView->transform());
    
    if(item)
    {
        QPointF pointItem=item->mapFromScene(pointScene);//场景坐标转图形项坐标
        labItem->setText(QString::asprintf("图形项坐标:%.0f,%.0f",pointItem.x(),pointItem.y()));
        labInfo->setText(item->data(ITEMINFO).toString()+" ID:"+
                         item->data(ITEMID).toString());
    }
}

6.效果展示

OK,到这里,咱们这个项目就完结撒花啦,期待与你一起进步!

十二.总结

这就是基于QGraphicsView架构做的CAD项目,当然啦,还可以有更多的创意,你也试试看吧!

播下一颗种子…

相关文章
|
2月前
【qt】平面CAD(计算机辅助设计 )项目 上
【qt】平面CAD(计算机辅助设计 )项目 上
40 0
|
5月前
[Qt5] 实现CAD中的十字标辅助线效果
[Qt5] 实现CAD中的十字标辅助线效果
180 0
|
3月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
163 1
Qt(C++)开发一款图片防盗用水印制作小工具
|
2月前
|
监控 C++ 容器
【qt】MDI多文档界面开发
【qt】MDI多文档界面开发
61 0
|
28天前
|
开发工具 C++
qt开发技巧与三个问题点
本文介绍了三个Qt开发中的常见问题及其解决方法,并提供了一些实用的开发技巧。
|
1月前
|
2月前
|
C++
C++ Qt开发:QUdpSocket网络通信组件
QUdpSocket是Qt网络编程中一个非常有用的组件,它提供了在UDP协议下进行数据发送和接收的能力。通过简单的方法和信号,可以轻松实现基于UDP的网络通信。不过,需要注意的是,UDP协议本身不保证数据的可靠传输,因此在使用QUdpSocket时,可能需要在应用层实现一些机制来保证数据的完整性和顺序,或者选择在适用的场景下使用UDP协议。
105 2
Qt开发网络嗅探器02
Qt开发网络嗅探器02
|
2月前
|
存储 运维 监控
Qt开发网络嗅探器01
Qt开发网络嗅探器01
|
2月前
|
网络协议 容器
Qt开发网络嗅探器03
Qt开发网络嗅探器03