一 软件启动界面 注册表使用
- 知识点1:这样创建的界面是不可以拖动的,需要手动创建函数来进行拖动,以下的3个函数是从父类继承过来的函数
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
步骤1:新建Qt设计师类,进行界面设计
- 添加背景图片,label标签,
pixmap
可以直接在标签所在位置插入图片
- 对于确认和取消按钮里面的图片,在如下所示地方插入即可
步骤2:main.cpp
文件中,添加对话框
#include "mainwindow.h"
#include <QApplication>
#include "dialoglogin.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DialogLogin *login = new DialogLogin();
if(login->exec() != QDialog::Accepted)
{
return 0;
}
MainWindow w;
w.show();
return a.exec();
}
步骤3:代码
dialoglogin.h
#ifndef DIALOGLOGIN_H
#define DIALOGLOGIN_H
#include <QDialog>
namespace Ui {
class DialogLogin;
}
class DialogLogin : public QDialog
{
Q_OBJECT
public:
explicit DialogLogin(QWidget *parent = nullptr);
~DialogLogin();
private slots:
void on_pushButtonCancle_clicked();
void on_pushButtonLog_clicked();
private:
Ui::DialogLogin *ui;
void loadSetting(); //读取本地的配置
void saveSetting();
QString m_user;
QString m_pwd;
int m_count = 0;
QString Encrypt(const QString &str); //对密码加密
bool m_moving= false;
QPoint m_lastPosition;
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
};
#endif // DIALOGLOGIN_H
dialoglogin.cpp
#include "dialoglogin.h"
#include "ui_dialoglogin.h"
#include <QSettings>
#include <QCryptographicHash>
#include <QMessageBox>
#include <QMouseEvent>
DialogLogin::DialogLogin(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogLogin)
{
ui->setupUi(this);
//设置密码
ui->lineEditNameCode->setEchoMode(QLineEdit::Password);
this->setAttribute(Qt::WA_DeleteOnClose);
//去掉登录窗口的左上角的标题
this->setWindowFlags(Qt::FramelessWindowHint); //任务栏中会显示标题
//this->setWindowFlag(Qt::SplashScreen); //任务栏中也不会显示标题
//读取本地电脑存储的用户名和密码,演示注册表的使用
loadSetting();
}
DialogLogin::~DialogLogin()
{
delete ui;
}
void DialogLogin::on_pushButtonCancle_clicked()
{
this->reject();
}
void DialogLogin::on_pushButtonLog_clicked()
{
QString useName = ui->lineEditName->text().trimmed(); //trimmed去掉首位空格
QString pwd = ui->lineEditNameCode->text().trimmed();
if(useName == m_user && Encrypt(pwd) == m_pwd){
//保存注册表
saveSetting();
this->accept();
}else{
m_count ++;
if(m_count > 3)
{
QMessageBox::critical(this,"错误","用户名和密码错误次数太多");
this->reject();
}
else{
QMessageBox::warning(this,"错误","用户名和密码错误");
}
}
}
void DialogLogin::loadSetting()
{
QSettings setting("WD","IMAGE PROCESSING"); //公司名字 当前软件名字
m_user = setting.value("user_name", "rook").toString(); //读默认值
m_pwd = setting.value("pwd", Encrypt("123456")).toString();
bool saved = setting.value("saved",false).toBool(); //默认保存
if(saved){
ui->lineEditName->setText(m_user);
ui->checkBox->setChecked(saved);
}
}
void DialogLogin::saveSetting()
{
QSettings setting("WD","IMAGE PROCESSING");
setting.setValue("user_name", m_user);
setting.setValue("pwd", m_pwd);
setting.setValue("saved", ui->checkBox->isChecked());
}
QString DialogLogin::Encrypt(const QString &str)
{
//MD5加密
QByteArray array;
array.append(str);
QCryptographicHash hash(QCryptographicHash::Md5); //设置加密算法
hash.addData(array);
QByteArray result = hash.result();
QString md5 = result.toHex();
return md5;
}
void DialogLogin::mousePressEvent(QMouseEvent *event)
{
if(event->button() ==Qt::LeftButton){
m_moving = true;
m_lastPosition = event->globalPos() - this->pos();
}
return QDialog::mousePressEvent(event);
}
void DialogLogin::mouseReleaseEvent(QMouseEvent *event)
{
m_moving = false;
}
void DialogLogin::mouseMoveEvent(QMouseEvent *event)
{
if(m_moving){
move(event->globalPos() - m_lastPosition);
m_lastPosition = event->globalPos()- this->pos();
}
return QDialog::mouseMoveEvent(event);
}
mainwindow.cpp
和mainwindow.h
文件没有任何改变和代码添加
二 QT绘图
2.1 矩形
- 知识点:需要重写父类的
virtual void paintEvent(QPaintEvent *event);
- widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
virtual void paintEvent(QPaintEvent *event);
};
#endif // WIDGET_H
- widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen pen;
pen.setWidth(4); //线宽
pen.setColor(Qt::red);
painter.setPen(pen);
//使用刷子进行填充
QBrush brush;
brush.setColor(Qt::green);
brush.setStyle(Qt::SolidPattern);
painter.setBrush(brush);
QRect rect(50,50,200,200); //左上角坐标(x,y,宽度,高度)
painter.drawRect(rect);
}
2.1.1
- 圆角矩形:将2.1 函数
void Widget::paintEvent(QPaintEvent *event)
中painter.drawRect(rect);
代码修改为painter.drawRoundedRect(rect,20,20);
- 椭圆:
painter.drawEllipse(rect);
- 圆弧:
//绘制圆弧 绘制0~90度 painter.drawArc(rect,0,90*16);
,Qt最小度单位不是1度,是1/16度 - 弦长:
painter.drawChord(rect, 0,*16,90*16)
- 多边形:
QPainter painter(this);
QPen
pen;
pen.setWidth(4); //线宽
pen.setColor(Qt::red); //划线颜色
painter.setPen(pen);
//注意,点的顺序,就是绘制的顺序
QPoint points[5] = {
{50, 100},
{100, 50},
{500, 160},
{200, 200},
{110, 400}};
painter.drawPolygon(
points,
5); //表示有几个点
- 图片
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QRect rect(10, 10, 400, 300);
//QImage image(":image/bg.png");
QPixmap pixmap(":image/bg.png");
//会自动在 rect 区域进行缩放
//painter.drawImage(rect, image);
painter.drawPixmap(rect, pixmap);
}
- 直线
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen
pen;
pen.setWidth(4); //线宽
pen.setColor(Qt::red); //划线颜色
painter.setPen(pen);
QLine line(50, 50, 400, 400);
painter.drawLine(line);
}
- 多条直线
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen
pen;
pen.setWidth(4); //线宽
pen.setColor(Qt::red); //划线颜色
painter.setPen(pen);
QRect rect(50, 50, 400, 300);
QVector<QLine>lines;
lines.append(QLine(rect.topLeft(), rect.bottomRight()));
lines.append(QLine(rect.bottomLeft(), rect.topRight()));
lines.append(QLine(rect.topLeft(), rect.bottomLeft()));
painter.drawLines(lines);
}
- 绘制多条连接的直线
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen
pen;
pen.setWidth(4); //线宽
pen.setColor(Qt::red); //划线颜色
painter.setPen(pen);
//注意,点的顺序,就是绘制的顺序
QPoint points[5] = {
{50, 100},
{100, 50},
{500, 160},
{200, 200},
{110, 400}};
painter.drawPolyline(points, 5);
}
- 绘制线路径
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen
pen;
pen.setWidth(4); //线宽
pen.setColor(Qt::red); //划线颜色
painter.setPen(pen);
QRect rect(50, 50, 400, 300);
//绘制由 QPaintPath 对象定义的路线
QPainterPath path;
path.addEllipse(rect); //在 rect 内的内接椭圆
path.addRect(rect);
painter.drawPath(path);
}
- 绘制扇形
- 画点
- 绘制文本
- 擦除指定区域
- 填充指定位置
三 坐标变换
3.1 平移
- 知识点:依然是需要继承父类的
void Widget::paintEvent(QPaintEvent *event)
函数,在改函数内进行相应的实现
3.2 旋转
3.3 扭转
3.4 放大缩小
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QImage img(":/images/bg.png");
QRect rect(0,0,200,150);
painter.drawImage(rect,img);
QRect rect2(200,200,200,150);
painter.scale(2.0,1.0);
painter.drawImage(rect2,img);
}
3.5 案例展示
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); //使得图行没有锯齿
QPen pen;
pen.setWidth(4);
pen.setColor(Qt::red);
painter.setPen(pen);
QFont font;
font.setPointSize(20);
painter.setFont(font);
qreal r = 200; //qreal其实就是double
qreal unit = 72*3.141596/180;
QPoint points[5] = {
QPoint(r,0),
QPoint(r*cos(unit),r*sin(unit)),
QPoint(r*cos(2*unit),r*sin(2*unit)),
QPoint(r*cos(3*unit),r*sin(3*unit)),
QPoint(r*cos(4*unit),r*sin(4*unit))
};
QPainterPath path;
path.moveTo(points[0]); //把画笔移动到该位置
path.lineTo(points[2]);
path.lineTo(points[4]);
path.lineTo(points[1]);
path.lineTo(points[3]);
path.closeSubpath();
path.addText(points[0],font,"0");
path.addText(points[1],font,"1");
path.addText(points[2],font,"2");
path.addText(points[3],font,"3");
path.addText(points[4],font,"4");
//保存此时坐标
painter.save();
painter.translate(250,210);
painter.rotate(-18);
painter.drawPath(path);
painter.restore();
}
四 视图和窗口绘图
- 功能,能使得建立的图片,随着窗口的大小变化而变化
- 知识点:需要重写
void paintEvent( QPaintEvent *event);
- 知识点:也就是说,
painter.setWindow
是重定义视口的原点的逻辑大小
案例1:
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//设计一个视口,也即是绘图窗口
QPainter painter(this);
painter.drawRect(QRect(200,0,200,200));
painter.setViewport(
200,0, //视口区域的左上角坐标,实际大小
200,200); //视口区域的左上角宽度和高度,实际大小
//设置视口后,一定要设置对应的窗口坐标
//否则会使用默认的窗口坐标,导致绘制效果不是预期的
//如下代码表示在当前的视口区域内,设置一个窗口坐标,
//在这个窗口坐标下,视口的左上角坐标是(-50, -50),
//视口的宽度是 100 个逻辑大小,视口的高度是 100 个逻辑大小
painter.setWindow(
-50,-50, //在这个窗口坐标系下,视口左上角的坐标
100, //在这个窗口坐标系下,视图区域的宽度大小,逻辑大小,不是实际大小
100);//在这个窗口坐标系下,视图区域的高度大小,逻辑大小,不是实际大小
QPen pen;
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawRect(QRect(0,0,50,50));
}
案例2:
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//设计一个视口,也即是绘图窗口
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
int w= qMin(this->width(), this->height());
QRect rect((this->width() - w)/2,(this->height() - w)/2,w,w);
painter.drawRect(rect);
//设置视口区域
painter.setViewport(rect);
//设置视口的窗口坐标系
painter.setWindow(-100,-100,200,200);
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(1);
pen.setStyle(Qt::SolidLine);
painter.setPen(pen);
int count = 10;
for(int i =0; i< count ;i ++){
painter.drawEllipse(QPoint(50,0),50,50);
painter.rotate(360/count);
}
}
五 Graphics View绘图框架
5.1 案例1 视图,场景,图形项之间的关系
- 知识点1:
scene->addItem(item3);
默认父节点是场景,如果要设置其他的图形项是当前图i图形项目的父节点,需要使用函数`item->setParentItem(item2) - 知识点2:设置item可拖动
item2->setFlags(QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建场景,当前的原点创建在了场景的中心
scene = new QGraphicsScene(-200,-100, //场景区域的左上角在场景坐标下的坐标,也就是原点被设置成矩形框的正中心
400,200); //场景的宽度,场景的高度
ui->graphicsView->setScene(scene);
//图形项 当前创建了和场景一样大小的图形项
QGraphicsRectItem *item = new QGraphicsRectItem(
-200,-100, //矩形图形项的左上角在图像项内部的坐标系下的坐标
400,200);
//设置图形项的原点,在场景坐标系下的位置
item->setPos(0,0);
//设置图形项的画笔
QPen pen;
pen.setColor(Qt::blue);
pen.setWidth(2);
item->setPen(pen);
scene->addItem(item);
//图形项2 当前创建了和场景一样大小的图形项
QGraphicsRectItem *item2 = new QGraphicsRectItem(
0,0, //矩形图形项的左上角在图像项内部的坐标系下的坐标,也就是原点被设置成左上角
200,100);
//设置图形项的原点,在场景坐标系下的位置
item2->setPos(-200,-100);
item2->setBrush(QBrush(Qt::red));
scene->addItem(item2);
//图形项2 当前创建了和场景一样大小的图形项
QGraphicsRectItem *item3 = new QGraphicsRectItem(
-100,-50, //矩形图形项的左上角在图像项内部的坐标系下的坐标,也就是原点被设置图形项的正中心
200,100);
//设置图形项的原点,在场景坐标系下的位置,
item3->setPos(0,0);
item3->setBrush(QBrush(Qt::yellow));
scene->addItem(item3);默认父节点是场景
}
5.1 案例2: 拖动鼠标或者图形项,显示鼠标当前所在位置的,对应的视图,场景以及图形项中的坐标
- 也是图形项发出信号
- mainwindow
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include "mygraphicview.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsScene *scene;
private slots:
void on_graphicsView_mousePress(QPoint point);
void on_graphicsView_mouseMove(QPoint point);
};
#endif // MAINWINDOW_H
#######################################################################################
#######################################################################################
#######################################################################################
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsRectItem>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建场景,当前的原点创建在了场景的中心
scene = new QGraphicsScene(-200,-100, //场景区域的左上角在场景坐标下的坐标,也就是原点被设置成矩形框的正中心
400,200); //场景的宽度,场景的高度
ui->graphicsView->setScene(scene);
//图形项 当前创建了和场景一样大小的图形项
QGraphicsRectItem *item = new QGraphicsRectItem(
-200,-100, //矩形图形项的左上角在图像项内部的坐标系下的坐标
400,200);
//设置图形项的原点,在场景坐标系下的位置
item->setPos(0,0);
//设置图形项的画笔
QPen pen;
pen.setColor(Qt::blue);
pen.setWidth(2);
item->setPen(pen);
scene->addItem(item);
//图形项2 当前创建了和场景一样大小的图形项
QGraphicsRectItem *item2 = new QGraphicsRectItem(
0,0, //矩形图形项的左上角在图像项内部的坐标系下的坐标,也就是原点被设置成左上角
200,100);
//设置图形项的原点,在场景坐标系下的位置
item2->setPos(-200,-100);
item2->setBrush(QBrush(Qt::red));
scene->addItem(item2);
item2->setFlags(QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable);
//图形项2 当前创建了和场景一样大小的图形项
QGraphicsRectItem *item3 = new QGraphicsRectItem(
-100,-50, //矩形图形项的左上角在图像项内部的坐标系下的坐标,也就是原点被设置图形项的正中心
200,100);
//设置图形项的原点,在场景坐标系下的位置,
item3->setPos(0,0);
item3->setBrush(QBrush(Qt::yellow));
scene->addItem(item3);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_graphicsView_mousePress(QPoint point)
{
//把视图坐标转换成场景坐标
QPointF pointSence =ui->graphicsView->mapToScene(point);
//判断当前按下了哪个图形项
QGraphicsItem *item = scene->itemAt(pointSence,ui->graphicsView->transform());
if(item)
{
//把场景坐标,进一步转换成对应的图形项的坐标
QPointF pointItem = item->mapFromScene(pointSence);
ui->labelGraph->setText(QString::asprintf("item坐标:%.0f, %.0f",
pointItem.x(),pointItem.y() ));
}
}
void MainWindow::on_graphicsView_mouseMove(QPoint point)
{
ui->labelView->setText(QString::asprintf("视图坐标:%d, %d",
point.x(),point.y() ));
QPointF pointSence =ui->graphicsView->mapToScene(point);
ui->labelSence->setText(QString::asprintf("场景坐标:%.0f, %.0f",
pointSence.x(),pointSence.y() ));
}
- MyGraphicView
#ifndef MYGRAPHICVIEW_H
#define MYGRAPHICVIEW_H
#include <QObject>
#include <QGraphicsView>
class MyGraphicView : public QGraphicsView
{
Q_OBJECT
public:
explicit MyGraphicView(QObject *parent = nullptr);
signals:
//这里是自己定义的,不是查的
void mousePress(QPoint point);
void mouseMove(QPoint point);
private:
//重载父类QGraphicsView鼠标事件
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
};
#endif // MYGRAPHICVIEW_H
#######################################################################################
#######################################################################################
#######################################################################################
#include "mygraphicview.h"
#include <QMouseEvent>
MyGraphicView::MyGraphicView(QObject *parent)
{
setMouseTracking(true); //直接拖动鼠标,也能显示坐标的改变
}
void MyGraphicView::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
QPoint point = event->pos();
emit mousePress(point);
}
QGraphicsView::mousePressEvent(event); //调用父类的mousePressEvent
}
void MyGraphicView::mouseMoveEvent(QMouseEvent *event)
{
QPoint point = event->pos();
emit mouseMove(point);
QGraphicsView::mouseMoveEvent(event); //调用父类的mouseMoveEvent
}
5.1.1 创建项目的步骤
-Graphics View
组件对应的类对象是QGraphicsView
,是标准类对象,无法进行修改,需要自定义一个视图,去重载该类的鼠标事件
步骤1:自定义视图类
- add new->c++ class->QObject
选项里面并没有我们要继承的QGraphicsView
类,所以可以随便选一个要继承的类,在代码里进行修改即可
步骤2:修改自定义视图类,使其继承QGraphicsView
,在QGraphicsView
中寻找到鼠标相关时事件,在自定义视图类中重写。由于本身本没有信号,但是要实现鼠标移动或单击时发送信号,因此要MyGraphicView
中定义信号,在mianwindow
中定义槽函数
`MyGraphicView`
signals:
//这里是自己定义的,不是查的
void mousePress(QPoint point);
void mouseMove(QPoint point);
private:
//重载父类QGraphicsView鼠标事件
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
mainwindow
private slots:
void on_graphicsView_mousePress(QPoint point);
void on_graphicsView_mouseMove(QPoint point);
步骤3:选中graphics View
组件,右键单击,选择提升为,
6 案例2 简易版CAD项目
- 知识点:如何添加侧面的toolbox
6.1 创建界面
- 定义界面
2.自定义mygraphicsview.h``,Add new->c++->c++ class ->父类选择Qobject, 步骤同5中的创建步骤,新定义的继承QObject类的来要修改成继承
QGraphicsView`
6.2 代码
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsScene *sence;
int itemZvalue = 0; //图形堆叠的顺序,数字越大,叠放越上面
int itemID =0;
static const int ITEM_ID = 1; //图形项的编号
static const int ITEM_DISCRIPTION = 2; //图形项的描述信息
//手动代码添加标签
QLabel *labelViewCoord; //视图坐标
QLabel *labelFigureCoord; //图形项坐标
QLabel *labelSenceCoord; //场景坐标
QLabel *itemName;
private slots:
void on_graphicsView_keyPress(QKeyEvent *event);
void on_graphicsView_mouseDouble(QPoint point);
void on_graphicsView_mousePress(QPoint point);
void on_graphicsView_mouseMove(QPoint point);
void on_actionRectangle_triggered();
void on_actionElipse_triggered();
void on_actionCilcle_triggered();
void on_actionTriangle_triggered();
void on_actionLine_triggered();
void on_actionTixing_triggered();
void on_actionText_triggered();
void on_actionZoom_triggered();
void on_actionSmall_triggered();
void on_actionRestore_triggered();
void on_actionLeft_triggered();
void on_actionRight_triggered();
void on_actionTop_triggered();
void on_actionBottom_triggered();
void on_actionCombine_triggered();
void on_actionDepart_triggered();
void on_actionDel_triggered();
void on_actionExit_triggered();
};
#endif // MAINWINDOW_H
mygraphicsview.h
#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H
#include <QObject>
#include <QGraphicsView>
class MyGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
explicit MyGraphicsView(QWidget *parent = nullptr);
signals:
void keyPress(QKeyEvent *event);
void mouseDouble(QPoint point);
void mousePress(QPoint point);
void mouseMove(QPoint point);
protected:
//override重载关键字
void keyPressEvent(QKeyEvent *event) override; //按键按下
void mouseDoubleClickEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
};
#endif // MYGRAPHICSVIEW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsRectItem>
#include <QTime>
#include <QPoint>
#include <QInputDialog>
#include <QDebug>
#include <QColorDialog>
#include <QColor>
#include <QFontDialog>
#include <QKeyEvent>
//设置填充色
template <class T>
void setItemBrushColor(T *item){
QColor color = item->brush().color();
color = QColorDialog::getColor(color, NULL, "选择填充颜色");
if(color.isValid()){
item->setBrush(color);
}
}
//设置画笔色
template <class T>
void setItemPenColor(T *item){
QPen pen = item->pen();
QColor color = pen.color();
color = QColorDialog::getColor(color, NULL, "选择填充颜色");
if(color.isValid()){
pen.setColor(color);
item->setPen(pen);
}
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->graphicsView->setCursor(Qt::CrossCursor); //设置鼠标样式是十字
//设置鼠标跟踪
ui->graphicsView->setMouseTracking(true);
//设置视图的拖动模式
ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
//创建场景
sence = new QGraphicsScene(-300,-100,600,200);
ui->graphicsView->setScene(sence);
//设置随机种子
qsrand(QTime::currentTime().second());
labelViewCoord = new QLabel("视图坐标:");
labelViewCoord->setMinimumWidth(150);
ui->statusbar->addWidget(labelViewCoord);
labelSenceCoord = new QLabel("场景坐标:");
labelSenceCoord->setMinimumWidth(150);
ui->statusbar->addWidget(labelSenceCoord);
labelFigureCoord = new QLabel("图形项坐标:");
labelFigureCoord->setMinimumWidth(150);
ui->statusbar->addWidget(labelFigureCoord);
itemName = new QLabel("图形项信息:");
itemName->setMinimumWidth(150);
ui->statusbar->addWidget(itemName);
}
MainWindow::~MainWindow()
{
delete ui;
}
//按键控制旋转平移操作
void MainWindow::on_graphicsView_keyPress(QKeyEvent *event)
{
//只管选一个的情况
if(sence->selectedItems().count() != 1){
return;
}
auto item = sence->selectedItems().at(0);
if(event->key() == Qt::Key_Delete){
sence->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);
}
}
void MainWindow::on_graphicsView_mouseDouble(QPoint point)
{
//双击图形项,自动弹出颜色编辑器
//QGraphicsRectItem : public QAbstractGraphicsShapeItem
// QGraphicsEllipseItem : public QAbstractGraphicsShapeItem
//QGraphicsPolygonItem : public QAbstractGraphicsShapeItem 三角形
//QGraphicsPolygonItem : public QAbstractGraphicsShapeItem 梯形
qDebug() << "in in --------------";
//由于不同图形继承的类不同
QPointF pointSence = ui->graphicsView->mapToScene(point); //获取场景坐标
QGraphicsItem *item = sence->itemAt(pointSence, ui->graphicsView->transform()); //计算改场景坐标对应是哪个图形
if(!item){
return;
}
switch (item->type()) {
case QGraphicsRectItem::Type:{
//矩形
auto item2 =qgraphicsitem_cast<QGraphicsRectItem*>(item);
setItemBrushColor(item2);
break;
}
case QGraphicsEllipseItem::Type:{
//椭圆/园
auto item2 =qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
setItemBrushColor(item2);
break;
}
case QGraphicsPolygonItem::Type:{
//多边形
auto item2 =qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
setItemBrushColor(item2);
break;
}
case QGraphicsLineItem::Type:{
//直线
auto item2 =qgraphicsitem_cast<QGraphicsLineItem*>(item);
setItemPenColor(item2);
break;
}
case QGraphicsTextItem::Type:{
//多边形
auto item2 =qgraphicsitem_cast<QGraphicsTextItem*>(item);
QFont font = item2->font();
bool ok = false;
font = QFontDialog::getFont(&ok,font, this,"设置字体");
if(ok)
{
item2->setFont(font);
}
break;
}
}
}
//图形项目坐标需要单击选中图形项
void MainWindow::on_graphicsView_mousePress(QPoint point)
{
QPointF pointScene = ui->graphicsView->mapToScene(point); //视图坐标转场景坐标
QGraphicsItem *item = sence->itemAt(pointScene,
ui->graphicsView->transform());
//图形项坐标
if(item){
QPointF pointItem = item->mapFromScene(pointScene); //获取点的图形项坐标
labelFigureCoord->setText(QString::asprintf("图形项坐标:%.0f %.0f",pointItem.x(),pointItem.y()));
itemName->setText(item->data(ITEM_DISCRIPTION).toString());
}
}
void MainWindow::on_graphicsView_mouseMove(QPoint point)
{
labelViewCoord->setText(QString::asprintf("视图坐标:%d %d",point.x(),point.y()));
QPointF pointScene = ui->graphicsView->mapToScene(point);
labelSenceCoord->setText(QString::asprintf("场景坐标:%.0f %.0f",pointScene.x(),pointScene.y()));
}
void MainWindow::on_actionRectangle_triggered()
{
QGraphicsRectItem *item = new QGraphicsRectItem(-100,-50,200,100);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
item->setBrush(QBrush(Qt::lightGray)); //填充颜色
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"矩形");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionElipse_triggered()
{
QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-100,-50,200,100);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
item->setBrush(QBrush(Qt::blue)); //填充颜色
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"椭圆");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionCilcle_triggered()
{
QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-100,-100,200,200);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
item->setBrush(QBrush(Qt::yellow)); //填充颜色
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"圆");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionTriangle_triggered()
{
QGraphicsPolygonItem *item = new QGraphicsPolygonItem;
QPolygonF points;
points.append(QPointF(0,-80));
points.append(QPointF(-50,0));
points.append(QPointF(0,50));
item->setPolygon(points);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
item->setBrush(QBrush(Qt::red)); //填充颜色
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"三角形");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionLine_triggered()
{
QGraphicsLineItem *item = new QGraphicsLineItem(50, 50, 200, 200);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"直线");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionTixing_triggered()
{
QGraphicsPolygonItem *item = new QGraphicsPolygonItem;
QPolygonF points;
points.append(QPointF(-50,-50));
points.append(QPointF(-100,50));
points.append(QPointF(100,50));
points.append(QPointF(50,-50));
item->setPolygon(points);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
item->setBrush(QBrush(Qt::black)); //填充颜色
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"梯形");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionText_triggered()
{
//弹出文本提示框,输入文本
QString str = QInputDialog::getText(this,"输入文本","请输入文本");
if(str.isEmpty()){
return;
}
QGraphicsTextItem *item = new QGraphicsTextItem(str);
item->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
QFont font;
font.setFamily("微软雅黑");
font.setPointSize(20);
font.setBold(true);
item->setFont(font);
item->setZValue(itemZvalue++);
//设置图形项位置,在视图的中心位置附近设计随机变量 0~100 -50
item->setPos(qrand()%100-50,qrand()%100-50);
//设置图形项的自定义数据
item->setData(ITEM_ID,itemID++);
item->setData(ITEM_DISCRIPTION,"文本");
sence->addItem(item);
sence->clearSelection();
item->setSelected(true); //选中当前新生成的图形
}
void MainWindow::on_actionZoom_triggered()
{
//如果当前选择了一个图元,那么对这个图元进行放大
//如果选择了多个图,对多个放大
int count = sence->selectedItems().count();
if(count ==1)
{
QGraphicsItem *item= sence->selectedItems().at(0); //取出图形
item->setScale(item->scale()+0.1);
}else if(count >1)
{
for(int i =0 ; i < count; i++)
{
QGraphicsItem *item= sence->selectedItems().at(i); //取出图形
item->setScale(item->scale()+0.1);
}
}
}
void MainWindow::on_actionSmall_triggered()
{
int count = sence->selectedItems().count();
if(count ==1)
{
QGraphicsItem *item= sence->selectedItems().at(0); //取出图形
item->setScale(item->scale()-0.1);
}else if(count >1)
{
for(int i =0 ; i < count; i++)
{
QGraphicsItem *item= sence->selectedItems().at(i); //取出图形
item->setScale(item->scale()-0.1);
}
}
}
void MainWindow::on_actionRestore_triggered()
{
int count = sence->selectedItems().count();
for(int i =0 ; i < count; i++)
{
QGraphicsItem *item= sence->selectedItems().at(i); //取出图形
item->setScale(1);
item->setRotation(0);
}
}
void MainWindow::on_actionLeft_triggered()
{
int count = sence->selectedItems().count();
if(count ==1)
{
QGraphicsItem *item= sence->selectedItems().at(0); //取出图形
item->setRotation(item->rotation()-30);
}else if(count >1)
{
for(int i =0 ; i < count; i++)
{
QGraphicsItem *item= sence->selectedItems().at(i); //取出图形
item->setRotation(item->rotation()-30);
}
}
}
void MainWindow::on_actionRight_triggered()
{
int count = sence->selectedItems().count();
if(count ==1)
{
QGraphicsItem *item= sence->selectedItems().at(0); //取出图形
item->setRotation(item->rotation()+30);
}else if(count >1)
{
for(int i =0 ; i < count; i++)
{
QGraphicsItem *item= sence->selectedItems().at(i); //取出图形
item->setRotation(item->rotation()+30);
}
}
}
void MainWindow::on_actionTop_triggered()
{
int count = sence->selectedItems().count();
if(count >0)
{
QGraphicsItem *item= sence->selectedItems().at(0);
item->setZValue(item->zValue()+1);
}
}
void MainWindow::on_actionBottom_triggered()
{
int count = sence->selectedItems().count();
if(count >0)
{
QGraphicsItem *item= sence->selectedItems().at(0);
item->setZValue(item->zValue()-1);
}
}
void MainWindow::on_actionCombine_triggered()
{
int count = sence->selectedItems().count();
qDebug() <<"count = " << count;
if(count >=2)
{
QGraphicsItemGroup *group = new QGraphicsItemGroup;
sence->addItem(group);
for(int i =0 ; i < count; i++)
{
auto item = sence->selectedItems().at(0); //获取每次循环的第一个item
item->setSelected(false);
item->clearFocus();
group->addToGroup(item);
}
group->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable |
QGraphicsItem:: ItemIsSelectable);
group->setZValue(itemZvalue++);
sence->clearSelection();
group->setSelected(true);
}
}
void MainWindow::on_actionDepart_triggered()
{
int count = sence->selectedItems().count();
if(count ==1)
{
auto group = (QGraphicsItemGroup *)sence->selectedItems().at(0);
sence->destroyItemGroup(group);
}
}
void MainWindow::on_actionDel_triggered()
{
int count = sence->selectedItems().count();
if(count > 0){
auto item = sence->selectedItems().at(0);
sence->removeItem(item);
}
}
void MainWindow::on_actionExit_triggered()
{
close();
}
mygraphicsview.cpp
#include "mygraphicsview.h"
#include <QMouseEvent>
#include <QDebug>
MyGraphicsView::MyGraphicsView(QWidget *parent):QGraphicsView(parent)
{
}
void MyGraphicsView::keyPressEvent(QKeyEvent *event)
{
emit keyPress(event);
QGraphicsView::keyPressEvent(event);
}
void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
//qDebug() << "mouseDoubleClickEvent ";
if(event->button() == Qt::LeftButton){
//获取视图坐标
QPoint point = event->pos();
emit mouseDouble(point);
}
QGraphicsView::mouseDoubleClickEvent(event);
}
void MyGraphicsView::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton){
//获取视图坐标
QPoint point = event->pos();
emit mousePress(point);
}
QGraphicsView::mousePressEvent(event);
}
void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
QPoint point = event->pos();
emit mouseMove(point);
QGraphicsView::mouseMoveEvent(event);
}