Qt学习_QGraphics进阶学习笔记
Posted Leslie X徐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt学习_QGraphics进阶学习笔记相关的知识,希望对你有一定的参考价值。
QGraphics进阶学习
1.保存图片函数
QPixmap QWidget::grab(const QRect &rectangle = QRect(QPoint(0, 0), QSize(-1, -1)))
Renders the widget into a pixmap restricted by the given rectangle. If the widget has any children, then they are also painted in the appropriate positions.
If a rectangle with an invalid size is specified (the default), the entire widget is painted.
2.场景里面添加QWidget部件
QGraphicsProxyWidget* item = _scene->addWidget(new QLineEdit("hello"));
item->resize(50,50);
item->setPos(_scene->sceneRect().center());
item->setFlags(QGraphicsItem::ItemIsMovable|
QGraphicsItem::ItemIsSelectable|
QGraphicsItem::ItemIsFocusable);
3.对QWidget部件的移动,对scene重写
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
/** 可以移动QGraphicsProxyWidget的scene
* @brief The GraphicsScene class
*/
class GraphicsScene : public QGraphicsScene
Q_OBJECT
public:
explicit GraphicsScene(QObject *parent = nullptr);
void setMoveMode(bool move)m_isMoveMode=move;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private:
QGraphicsItem *m_pItemSelectedQ_NULLPTR; // 鼠标单选item
QPoint m_shiftOrg; // 鼠标点选item中位置相对于item原点的偏移量
bool m_isMoveModefalse;
;
#endif // GRAPHICSSCENE_H
#include "GraphicsScene.h"
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>
#include <QMenu>
GraphicsScene::GraphicsScene(QObject *parent) : QGraphicsScene(parent)
// 鼠标按下获取当前单选中的QGraphicsProxyWidget图元对象
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
// qDebug() << "scene mouse press";
QGraphicsScene::mousePressEvent(event);
//左键则弹出menu框
if (event->button() == Qt::RightButton)
m_pItemSelected = nullptr;
if(items(event->scenePos()).isEmpty())
QMenu *menu = new QMenu();
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addAction("editMode",this,[this]()
setMoveMode(false);
);
menu->addAction("moveMode",this,[this]()
setMoveMode(true);
);
menu->popup(event->screenPos());
//进入edit模式则直接退出
if(m_isMoveMode==false)
m_pItemSelected = nullptr;
return;
//进入move模式则不可编辑
if (event->button() == Qt::LeftButton)
// 检测光标下是否有 item
m_pItemSelected = nullptr;
foreach (QGraphicsItem *item, items(event->scenePos()))
if (item->type() == QGraphicsProxyWidget::Type) // 代理Widget
QGraphicsProxyWidget *proxyWidget = qgraphicsitem_cast<QGraphicsProxyWidget *>(item);
QPointF point = proxyWidget->mapToScene(QPointF(0.0, 0.0));
m_shiftOrg.setX(event->scenePos().x() - point.x());
m_shiftOrg.setY(event->scenePos().y() - point.y());
m_pItemSelected = item;
break;
// 鼠标移动过程中跟随位置改变
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// qDebug() << "scene mouse move";
QGraphicsScene::mouseMoveEvent(event);
if(m_pItemSelected != nullptr)
m_pItemSelected->setPos(event->scenePos().x() - m_shiftOrg.x(), event->scenePos().y() - m_shiftOrg.y());
// 鼠标释放后作为最后的位置
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
// qDebug() << "scene mouse release";
QGraphicsScene::mouseReleaseEvent(event);
if(m_pItemSelected != nullptr)
m_pItemSelected->setPos(event->scenePos().x() - m_shiftOrg.x(), event->scenePos().y() - m_shiftOrg.y());
m_pItemSelected = nullptr;
4.自定义QGraphicsLineItem 创建动态连线
需要重写 QRectF boundingRect()
和 void paint()
函数
需要添加头尾两个item指针
头文件
#ifndef CONNECTLINE_H
#define CONNECTLINE_H
#include <QGraphicsLineItem>
class ConnectLine : public QGraphicsLineItem
public:
ConnectLine();
ConnectLine(QGraphicsItem* startitem, QGraphicsItem* enditem);
~ConnectLine();
double getlength()return _length;
private:
QGraphicsItem* _startItem;
QGraphicsItem* _endItem;
double _length=0;
// QGraphicsItem interface
public:
virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
;
#endif // CONNECTLINE_H
源文件
#include "ConnectLine.h"
#include <QPainter>
#include <QDebug>
ConnectLine::ConnectLine()
ConnectLine::ConnectLine(QGraphicsItem *startitem, QGraphicsItem *enditem)
_startItem = startitem;
_endItem = enditem;
this->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
ConnectLine::~ConnectLine()
QRectF ConnectLine::boundingRect() const
return QRectF(_startItem->pos()-QPointF(10,10),_endItem->pos()+QPointF(10,10));
void ConnectLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
// painter->drawLine(_startItem->pos(),_endItem->pos());
QPainterPath path;
path.moveTo(_startItem->pos());
path.cubicTo(_startItem->pos()+QPointF(50,0),_endItem->pos()-QPointF(50,0),_endItem->pos());
_length = path.length();
painter->drawPath(path);
5.自定义 textitem 双击可以编辑
知识点:
flags Qt::TextInteractionFlags
QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlag::TextEditorInteraction);
头文件
#ifndef GRAPHICSEDITABLETEXTITEM_H
#define GRAPHICSEDITABLETEXTITEM_H
#include <QGraphicsTextItem>
class GraphicsEditableTextItem : public QGraphicsTextItem
Q_OBJECT
public:
GraphicsEditableTextItem();
GraphicsEditableTextItem(const QString& str);
// QGraphicsItem interface
protected:
void focusOutEvent(QFocusEvent *event) override;
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
;
#endif // GRAPHICSEDITABLETEXTITEM_H
源文件
#include "GraphicsEditableTextItem.h"
GraphicsEditableTextItem::GraphicsEditableTextItem()
this->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable|
QGraphicsItem::ItemIsSelectable);
GraphicsEditableTextItem::GraphicsEditableTextItem(const QString &str)
this->setPlainText(str);
this->setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable|
QGraphicsItem::ItemIsSelectable);
void GraphicsEditableTextItem::focusOutEvent(QFocusEvent *event)
this->setSelected(false);
if(this->textInteractionFlags()==Qt::TextInteractionFlag::TextEditorInteraction)
this->setTextInteractionFlags(Qt::TextInteractionFlag::NoTextInteraction);
QGraphicsTextItem::focusOutEvent(event);
void GraphicsEditableTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
if(this->textInteractionFlags()==Qt::TextInteractionFlag::NoTextInteraction)
this->setTextInteractionFlags(Qt::TextInteractionFlag::TextEditorInteraction);
QGraphicsTextItem::mouseDoubleClickEvent(event);
6.绘制外轮廓
// 绘制轮廓
void ConnectLine::drawOutline(QPainter *painter, QPainterPath path)
// 生成可填充的轮廓
QPainterPathStroker stroker;
stroker.setCapStyle(Qt::RoundCap); // 端点风格
stroker.setJoinStyle(Qt::RoundJoin); // 连接样式
stroker.setDashPattern(Qt::DashLine); // 虚线图案
stroker.setWidth(10); // 宽度
// 生成一个新路径(可填充区域),表示原始路径 path 的轮廓
QPainterPath outlinePath = stroker.createStroke(path);
// 绘制轮廓时所用的画笔(轮廓外边框灰色部分)
QPen pen = painter->pen();
pen.setColor(QColor(0, 160, 230));
pen.setWidth(10);
// 用指定的画笔 pen 绘制 outlinePath
// painter->strokePath(outlinePath, pen);
painter->setPen(pen);
painter->drawPath(outlinePath);
// 用指定的画刷 brush 填充路径 outlinePath
painter->fillPath(outlinePath, QBrush(Qt::yellow));
7.MyMind思维导图
void MainWindow::on_pushButton_clicked()
QGraphicsItem* previtem=0;
qDebug()<<_scene->selectedItems();
if(!_scene->selectedItems().isEmpty())
previtem = _scene->selectedItems().at(0);
qDebug()<<"selected previtem";
GraphicsEditableTextItem* textitem = new GraphicsEditableTextItem("hello");
_scene->addItem(textitem);
if(previtem)
qDebug()<<"draw line";
textitem->setPos(previtem->pos()+QPointF(100,0));
ConnectLine* line = new ConnectLine(previtem,textitem);
_scene->addItem(line);
8.保存
void MainWindow::on_actsave_triggered()
QPixmap pic = ui->View->grab(scene->sceneRect().toRect());
pic.save("D:\\\\lesliex\\\\test.jpg");
9.给QgraphicsTextItem加上背景色
void GraphicsEditableTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
painter->setBrush(Qt::yellow);
painter->drawRect(this->boundingRect());
QGraphicsTextItem::paint(painter,option,widget);
10.利用boundingrect获取起始点和终点
void ConnectLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
QPointF startpos = mapFromItem(_startItem, _startItem->boundingRect().center());
QPointF endpos =mapFromItem( _endItem,_endItem->boundingRect().center());
painter->setPen(this->pen());
QPainterPath path;
path.moveTo(startpos);
if(startpos.x()>endpos.x())
path.cubicTo(startpos-QPointF(100,0),endpos+QPointF(100,0),endpos);
else
path.cubicTo(startpos+QPointF(100,0),endpos-QPointF(100,0),endpos);
painter->drawPath(path);
11.向下移动
if(previtem)
qDebug()<<"draw line";
textitem->setPos(previtem->pos()+QPointF(100,0));
while(!textitem->collidingItems().isEmpty())
textitem->setPos(textitem->collidingItems()以上是关于Qt学习_QGraphics进阶学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
MYSQL进阶学习笔记四:MySQL存储过程之定义条件,处理过程及存储过程的管理!(视频序号:进阶_11,12)
MYSQL进阶学习笔记五:MySQL函数的创建!(视频序号:进阶_13)