Qt中建立場景並將該創景顯示在視窗上面例項

readyao發表於2015-11-30
QPainter 是一個畫家類
畫紙有好多種:視窗,印表機,QPixmap;
影像類:QPixmap, QImage, QBitmap, QPicture;
經常用的是QPixmap;效能比較高,各個系統中介面是一樣的,但是影像是根據各個系統優化過的;QImage:與平臺不關,都是一樣的;


該例項主要的功能是:
1.建立一個場景,在該場景中新增部件,比如:圖片,文字,直線等等
2.新增動畫,將靜態部件(如圖片)變為動態部件;有一個時間線;
3.右鍵點選該視窗部件,將該視窗的場景儲存到一個圖片上面;
3.右鍵點選該視窗部件,將該視窗的場景輸入到印表機預覽;
4.右鍵點選該視窗部件,將該視窗的場景輸入到印表機直接列印(此處是列印為pdf檔案);
5.畫家可以直接將文字列印;
6.簡單的使用定時器;


mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <QGraphicsScene>//場景
//#include <QGraphicsItem>//場景的東西
#include <QGraphicsLineItem>//線
#include <QGraphicsPixmapItem>//影像
#include <QGraphicsView>//顯示場景
#include <QGraphicsPixmapItem>
#include <QGraphicsItemAnimation>//動畫
#include <QTimeLine>
#include <QPrintDialog>        //列印
#include <QPrintPreviewDialog>//列印預覽
#include <QTimer>//定時器
class MyWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *);
    void resizeEvent(QResizeEvent *);
    void mousePressEvent(QMouseEvent *);

    QGraphicsScene *_scene;//場景
    QGraphicsView * _view;//顯示場景

    QTimer * _timer;
signals:
    
public slots:
    void slotPaintRequested(QPrinter *);
    void slotTimeout();
};

#endif // MYWIDGET_H

mywidget.cpp

#include <QApplication>
#include "mywidget.h"
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QDebug>
#include <QPainter>
#include <QPixmap>
#include <QPrinter>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)
{
    QGraphicsLineItem * lineItem;
    QGraphicsTextItem * textItem;
    QGraphicsPixmapItem *pixmapItem;

    //QVBoxLayout *layout = new QVBoxLayout(this);
    _view = new QGraphicsView(this);
   // _view->setBackgroundBrush(Qt::red);
    //layout->addWidget(_view);
    _view->setScene(_scene = new QGraphicsScene);
    _scene->addItem(lineItem = new QGraphicsLineItem(QLineF(QPoint(0, 0), QPoint(100, 100))));
    _scene->addItem(textItem = new QGraphicsTextItem("Hello World"));
    _scene->addItem(pixmapItem = new QGraphicsPixmapItem(QPixmap("../aaa.png")));

    QTransform trans;
    trans.rotate(15);//選擇15度
    textItem->setTransform(trans);//"Hello World"旋轉15度
    textItem->setPos(QPointF(200, 200));
    textItem->setFont(QFont("Times", 30, 20, true));

    pixmapItem->setPos(QPointF(100, 0));
    //動畫animation
    QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
    animation->setItem(pixmapItem);

    QTimeLine *timeline = new QTimeLine(3000);
    timeline->setLoopCount(3);//設定迴圈次數為1次
    animation->setTimeLine(timeline);//設定時間
    //animation->setRotationAt();
    animation->setTranslationAt(1, 200, 200);//會從  100, 100移動到200, 200
   // timeline->start();//動畫開始
#if 0
    _timer = new QTimer();
    _timer->setInterval(3000);
    connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
    _timer->start();
#endif
    QTimer::singleShot(300, this, SLOT(slotTimeout()));
}

void MyWidget::slotTimeout()
{
    qDebug() << "timeout";
    //sender()->deleteLater();//釋放掉該定時器
}

void MyWidget::paintEvent(QPaintEvent *)
{

}

void MyWidget::mousePressEvent(QMouseEvent *ev)
{
    //右鍵點選該視窗,儲存該視窗的內容
    if(ev->button() == Qt::RightButton){

#if 0
        //儲存該場景view
        QPixmap pixmap(size());
        QPainter painter(&pixmap);
        painter.fillRect(QRect(0, 0, size().width(), size().height()), Qt::white);//先將pixmap畫為白色
       // _scene->render(&painter);//render,渲染,畫,向pixmap中畫
        _view->render(&painter);//和上面的語句效果是一樣的
        pixmap.save("../bbb.png");
#endif
#if 0
        //右鍵列印預覽該部件內容
        QPrintPreviewDialog dig;
        connect(&dig, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));
        dig.exec();
#endif

#if 1
        //真正的列印,因為沒有印表機,但是它可以列印成pdf的檔案;
        QPrintDialog dig;
        connect(&dig, SIGNAL(accepted(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)));//
        dig.exec();

#endif
    }
}

void MyWidget::slotPaintRequested(QPrinter *printer)//QPrinter繼承自QPaintDevice,是一個裝置;
{
    //我們用painter向該裝置中畫東西;
    QPainter painter(printer);
   // this->render(&painter);//把widget中顯示的東西都送到painter中,也就是送到印表機裡;把視窗部件的所有內容都列印
   // _view->render(&painter);//僅僅是把當前視窗中顯示內容列印下來;render函式相當於是拷貝
    _scene->render(&painter);//可以把視窗的內容列印下來
    //painter.drawText(QRectF(200, 200, 100, 100), "Hello World");//將Hello World列印
}

void MyWidget::resizeEvent(QResizeEvent *)
{
    //設定_vew的大小等於視窗的大小
    _view->setGeometry(QRect(QPoint(0, 0), size()));
}



int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    MyWidget w;
    w.setGeometry(400, 400, 600, 500);
    w.show();

    app.exec();
}

列印預覽的時候右鍵點選該視窗會出現下面的介面:

如果是直接列印的話,會出現下面的介面:

如果是儲存視窗部件的場景到2.png,儲存的圖片2.png如下圖所示


相關文章