學習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())後,再次顯示時,窗體上的組件就會失去焦點!
好了,二維繪圖基本就介紹到這裏,代碼實現可以不盡相同,只要掌握原理,實現起來就會遊刃有餘!