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();
}