Qt之二維繪圖

 學習Qt,那麼二維繪圖必不可少!而且在開發界面的時候很多樣式(點、線、矩形、弧形、餅狀圖、多邊形、貝塞爾弧線等)都會用到,所以建議認真學習二維繪圖!

    Qt的二維圖形引擎是基於QPainter類的,QPainter既可以繪製幾何圖形,也可以繪製像素映射、圖像和文字。此外,QPainter也支持一些高級特性,例如反走樣(針對文字和圖形邊緣)、像素混合、漸變填充和矢量路徑等,QPainter也支持線性變換,例如平移、旋轉、錯切和縮放。

    QPainter可以畫在“繪圖設備”上,例如:QWidget、QPixmap、QIamge或者QSvgGenerator。QPainter也可以與QPrinter一起使用來打印文件盒創建PDF文檔。這意味着通常可以用相同的代碼在屏幕上顯示數據,也可以生成打印形式的報告。

    如果要在繪圖設備(一般爲窗口部件)上繪圖,只需創建一個QPainter,再將指針傳到該設備中。

 

例如:

void MyWidget::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

}

    使用QPainter的draw...()函數,可以繪製各種各樣的形狀。圖8.1列出了其中最重要一些函數。繪製效果取決於QPainter的設置,一些是從設備中取得的,然而有些被初始化成默認值。三個主要設置是畫筆、畫刷、字體:

    畫筆:用來畫線和邊緣。它包含顏色、寬度、線性、拐點風格以及連線風格。

    畫刷:用來填充幾何圖形的圖案。它一般由顏色和風格組成,但同時也可以是紋理(一個不斷重複的圖像)或者是一個漸變。

    字體:用來繪製文字。字體有很多屬性,包括字體族和磅值大小。

    可以隨時調用QPen、QBrush或者QFont對象的setPen()、setBrush()和setFont()來修改這些設置。

    draw...,見明知義。繪製點drawPoint()、繪製直線drawLine()、繪製折線drawPolyLine()、繪製多點drawPoints()、繪製多直線drawLines()、繪製矩形區域drawRect()、繪製圓角區域drawRoundRect()、繪製橢圓drawEllipse()、繪製背景圖片drawPixmap()等!

 

舉例:

 

繪製直線:

1、在當前窗口繪製

void myWidget::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    painter.setPen(Qt::gray); //設置畫筆爲灰色

    painter.drawLine(0, 0, 100, 100); //(0, 0)爲初始座標,(100, 100)爲最終座標

}

2、在當前窗體上的子組件繪製

    paintEvent()可以實現圖形的繪製,前提是繪製當前窗體!如果界面上有其它組件,如何來繪製呢?

   (1)對子組件自定製,可以重新實現一個類,實現paintEvent()

   (2)添加監聽器line_label->installEventFilter(this),實現eventFilter()。

    關於(1)就不再多講,同1,(2)代碼如下:

line_label->installEventFilter(this);

bool myWidget::eventFilter(QObject *obj, QEvent *event)
{
 if(obj == line_label)
 {
  if(event->type() == QEvent::Paint)
  {
   int label_height = line_label->height();
   int label_width = line_label->width();
   QPainter painter(line_label);
   painter.setPen(QPen(Qt::gray, 1, Qt::DashLine));
   painter.drawLine(label_width/2, 0, label_width/2, label_height); 

  }
 }

 return QWidget::eventFilter(obj, event);
}

    這樣就可以實現在myWidget窗體上的QLabel的繪製!

    優劣性:如果窗口子部件較多,若每個部件的繪製相同,則可採用(1),若不相同,那麼根據(1)就會實現較多的類,而(2)只需要添加多個監聽器即可,建議採用方式(2)!

 

繪製背景圖片:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.drawPixmap(rect(), QPixmap(skin_name));

}

 

繪製矩形:

void myWidget::paintEvent(QPaintEvent *event)
{

 QPainter painter(this);
 QLinearGradient linear(rect().topLeft(), rect().bottomLeft());
 linear.setColorAt(0, Qt::red);
 linear.setColorAt(0.5, Qt::green);
 linear.setColorAt(1, Qt::blue); //設置紅、綠、藍變化
 painter.setPen(Qt::gray); //設定畫筆顏色,到時侯就是邊框顏色
 painter.setBrush(linear); //設置畫筆,到時候就是區域顏色
 painter.drawRect(QRect(0, 30, this->width(), this->height()-30)); //設置繪製區域
}

 

繪製折線:

void myWidget::paintEvent(QPaintEvent *event)
{

 QPainter painter(this);
 painter.setPen(Qt::gray);
 static const QPointF points[4] = {QPointF(0, 30), QPointF(0, this->height()-1), QPointF(this->width()-1, this->height()-1), QPointF(this->width()-1, 30)};
 painter.drawPolyline(points, 4); //由4個點連成的折線
}

 

繪製圓角:

setWindowFlags(Qt::FramelessWindowHint); //去掉標題欄

setAttribute(Qt::WA_TranslucentBackground); //不被繪製上的部分設置透明

void myWidget::paintEvent(QPaintEvent *event)
{

 QPainter painter(this);
 QBrush brush;
 brush.setTextureImage(QImage(background_image));
 painter.setBrush(brush); //設置畫刷,繪製背景圖片
 painter.setPen(Qt::black); //設置畫筆,繪製邊框色       
 painter.drawRoundedRect(QRect(0, 0, this->width()-1, this->height()-1), 5, 5); //繪製圓角,像素爲5

}

    就我所知,setAttribute(Qt::WA_TranslucentBackground)有一定的弊病,當窗體最小化(showMinimized())後,再次顯示時,窗體上的組件就會失去焦點!

    好了,二維繪圖基本就介紹到這裏,代碼實現可以不盡相同,只要掌握原理,實現起來就會遊刃有餘!


注:
    技術在於交流、溝通,轉載請註明出處並保持作品的完整性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章