Qt 中View ,Scene的简单实用案例
程序员文章站
2022-05-28 11:56:05
...
view ,scene简介
要显示文字,图形,图形等项目,可以先把这些显示项目的描述数据,添加到Scene,然后View设置Scene,即可实现显示的项目。
- Scene是一个显示场景,一个场景中可以显示多个显示项目。
- View可以看做一个窗口,在窗口设置一个场景,即可将Scene显示出来。
案例介绍
1、显示一条线,文字,图片。
2、保存或打印窗口。
设置view 和 scene
_scene = new QGraphicsScene;
_view = new QGraphicsView(this); //view 的父窗口为this
_view->setScene(_scene);
显示形状项目
QGraphicsLineItem *lineItem = new QGraphicsLineItem(QLine(QPoint(0, 0), QPoint(100, 100))); _scene->addItem(lineItem);//在场景中添加一条线段
显示文字项目
QGraphicsTextItem *textItem = new QGraphicsTextItem("hello world"); _scene->addItem(textItem);//添加文字
可以给文字设置显示样式
textItem->setFont(QFont("family", 50, 10, true));
textItem->setPos(100, 100);
QTransform tran;//旋转,缩放等
tran.rotate(90);
textItem->setTransform(tran);
显示图片项目
QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(QPixmap(R"(..\1.png)")); _scene->addItem(pixmapItem);//添加一幅图片
可以给图片添加效果
pixmapItem->setPos(100, 100);
QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;//给图片添加动画
QTimeLine *timeLine = new QTimeLine(3000);
timeLine->setLoopCount(2);
animation->setTimeLine(timeLine);
animation->setItem(pixmapItem);
animation->setTranslationAt(1,400,400);
timeLine->start();//开始动画
在窗口大小变换时,同步调整view大小
窗口大小变化时,会调用resizeEvent函数,在函数里同步更改view的大小
void Graphic::resizeEvent(QResizeEvent *event)
{
//使view的大小布满整个窗口
_view->setGeometry(QRect(QPoint(0,0), size()));
}
将view 或者scene 中图像保存下来。
view和scene的render函数,会将自己的图像或图像数据提供给画家,画家就可以画在任何可以绘制的对象上。
void Graphic::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)//右击保存界面
{
QPixmap pixmap(size());
QPainter painter(&pixmap);
painter.fillRect(QRectF(0, 0, size().width(), size().height()), Qt::white);//先画白色背景
//_view->render(&painter);//将窗口提供给画家,画家自动会画出来
_scene->render(&painter); //将场景中的数据提供给画家,这些数据可以没有显示出来。
pixmap.save(R"(..\result.png)");//保存画出来的图片
}
}
打印view 或者scene 中的图像
qt自带的打印对话框或者打印预览对话框,在打印之前都会发生信号paintRequested和要打印的对象,接受该信号并将需要打印的项目绘制到打印对象,即可实现打印任意项目。
1 先预览再打印
void Graphic::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton)
{
/*先预览,在打印*/
QPrintPreviewDialog printPreViewDlg;
//打印之前会发生此信号,打印的图像就是QPrinter,在QPrinter上绘制图像,即可实现打印
connect(&printPreViewDlg, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));
printPreViewDlg.exec();
}
}
void Graphic::slotPaintRequested(QPrinter *printer)
{
QPainter painter(printer);
_scene->render(&painter);
painter.setFont(QFont("family", 50, 100));
painter.drawText(QPointF(300, 300), "Ma Ling Shu");//添加文字,水印效果
}
2 直接打印:和预览基本一样,只需要更改为打印对话框即可
void Graphic::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton)
{
/*直接打印*/
QPrintDialog printDlg;
connect(&printDlg, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));
printDlg.exec();
}
}
完整代码实现
头文件
#ifndef graphic_h__
#define graphic_h__
#include <QWidget>
class QGraphicsScene;
class QGraphicsView;
class QPrinter;
class Graphic : public QWidget
{
Q_OBJECT
public:
Graphic(QWidget *parent);
void resizeEvent(QResizeEvent *event);
void mousePressEvent(QMouseEvent *event);
public slots:
void slotPaintRequested(QPrinter *printer);
private:
QGraphicsScene *_scene;
QGraphicsView *_view;
};
#endif // graphic_h__
源代码
#include "graphic.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QApplication>
#include <QFont>
#include <QVBoxLayout>
#include <QLine>
#include <QGraphicsPixmapItem>
#include <QTransform>
#include <QGraphicsItemAnimation>
#include <QTimeLine>
#include <QMouseEvent>
#include <QPointer>
#include <QPrintPreviewDialog>
#include <QPrintDialog>
#include <QPrinter>
Graphic::Graphic(QWidget *parent):
QWidget(parent)
{
_scene = new QGraphicsScene;
_view = new QGraphicsView(this);//view 的父窗口为this
_view->setScene(_scene);
// 设置布局,根据现实内容大小,自动调整view大小
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addWidget(_view);
this->setLayout(vlayout);
QGraphicsLineItem *lineItem = new QGraphicsLineItem(QLine(QPoint(0, 0), QPoint(100, 100)));
QGraphicsTextItem *textItem = new QGraphicsTextItem("hello world");
QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(QPixmap(R"(C:\Users\admin\Pictures\Saved Pictures\1.png)"));
_scene->addItem(lineItem);//在场景中添加一条线段
_scene->addItem(textItem);//添加文字
_scene->addItem(pixmapItem);//添加一幅图片
//设置格式
textItem->setFont(QFont("family", 50, 10, true));
textItem->setPos(100, 100);
QTransform tran;//旋转,缩放等
tran.rotate(90);
textItem->setTransform(tran);
pixmapItem->setPos(100, 100);
//QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;//给图片添加动画
//QTimeLine *timeLine = new QTimeLine(3000);
//timeLine->setLoopCount(2);
//animation->setTimeLine(timeLine);
//animation->setItem(pixmapItem);
//animation->setTranslationAt(1,400,400);
//timeLine->start();//开始动画
}
void Graphic::resizeEvent(QResizeEvent *event)
{
//使view的大小布满整个窗口
_view->setGeometry(QRect(QPoint(0,0), size()));
}
void Graphic::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)//右击保存界面
{
QPixmap pixmap(size());
QPainter painter(&pixmap);
painter.fillRect(QRectF(0, 0, size().width(), size().height()), Qt::white);//先画白色背景
//_view->render(&painter);//将窗口提供给画家,画家自动会画出来
_scene->render(&painter); //将场景中的数据提供给画家,这些数据可以没有显示出来。
pixmap.save(R"(..\result.png)");//保存画出来的图片
}
if (event->button() == Qt::RightButton)
{
/*先预览,在打印*/
QPrintPreviewDialog printPreViewDlg;
//打印之前会发生此信号,打印的图像就是QPrinter,在QPrinter上绘制图像,即可实现打印
connect(&printPreViewDlg, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));
printPreViewDlg.exec();
/*直接打印*/
//QPrintDialog printDlg;
//connect(&printDlg, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));
//printDlg.exec();
}
}
void Graphic::slotPaintRequested(QPrinter *printer)
{
QPainter painter(printer);
_scene->render(&painter);
painter.setFont(QFont("family", 50, 100));
painter.drawText(QPointF(300, 300), "Ma Ling Shu");//添加文字,水印效果
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Graphic graphic(nullptr);
//graphic.showMaximized();
graphic.show();
return app.exec();
}