1.Qt繪圖基礎
(1)繪圖需畫筆和畫布:
- QPainter 相當於Qt中的一個畫筆,繪制時需要一塊畫布,
- Qt中扮演畫布角色的組件為QPaintDevice和他的各個子類,如: QWidget, QPixmap, QPixture...
- QPainter、QPaintDevice之間使用 QPaintEngine 進行通訊(也就是翻譯 QPainter 的指令的意思)
(2)怎么畫
- 通常都是要在哪個 widget 上繪圖,就需要在它的
paintEvent()
函數里繪圖,即重寫 paintEvent() 函數
(3)實例
PaintTest.h
1 #ifndef PAINTTEST_H 2 #define PAINTTEST_H 3 4 #include <QWidget> 5 #include <QLabel> 6 #include <QPainter> 7 class PaintTest : public QWidget 8 { 9 Q_OBJECT 10 private: 11 QLabel *la; 12 public: 13 explicit PaintTest(QWidget *parent = 0); 14 void paintEvent(QPaintEvent *); 15 16 17 18 }; 19 #endif // PAINTTEST_H
PaintTest.cpp
1 #include "PaintTest.h" 2 #include <QLabel> 3 #include <QEvent > 4 PaintTest::PaintTest(QWidget *parent) : 5 QWidget(parent),la(new QLabel(this)) 6 { 7 la->setText("PaintTest Label"); 8 la->resize(100,190); 9 10 la->installEventFilter(this); 11 } 12 void PaintTest::paintEvent(QPaintEvent *) { 13 QPainter painter(this); // this 是 PaintTest 的指針 14 painter.setPen(Qt::gray); 15 painter.setBrush(Qt::green); 16 painter.drawRect(10, 10, 50, 50); 17 }
main.cpp
1 #include <QApplication> 2 3 #include "PaintTest.h" 4 5 int main(int argc,char* argv[]) 6 { 7 QApplication a(argc, argv); 8 9 PaintTest pt; 10 pt.show(); 11 12 return a.exec(); 13 }
2.遇到的問題
如果行繪制的圖形是在Qwidget的子的組件上應該怎么繪制在哪里繪制?
一般想到的是直接在paintEvent()更改
1 void PaintTest::paintEvent(QPaintEvent *) { 2 // QPainter painter(this); // this 是 PaintTest 的指針 3 QPainter painter(this->la); 4 painter.setPen(Qt::gray); 5 painter.setBrush(Qt::green); 6 painter.drawRect(10, 10, 50, 50); 7 }
運行程序,結果並沒有在 Label 上繪制出矩形,而且還輸出了下面的錯誤:
QPainter::begin: Paint device returned engine == 0, type: 1 QPainter::setPen: Painter not active QPainter::setBrush: Painter not active QPainter::drawRects: Painter not active QPainter::begin: Paint device returned engine == 0, type: 1
上面1(2)提到了想要在哪個 widget 上繪圖,就需要在它的 paintEvent() 函數里繪圖,這里我們是想在這個Qlabel中繪圖,但是paintEvent()函數是PainterTest的,所以繪制出了問題繪制不成功。
因此想要在QLabel中繪制圖形,就必須新建一個類繼承自QLAbel,然后在它的 paintEvent() 里繪圖,如果單獨就這個問題創建一個新的類就會有點小題大作了
3.解決
在事件過濾器 eventFilter()
中攔截 QLabel 的 QEvent::Paint
事件,用 QLabel 創建 QPainter,就可以在 QLabel 上繪圖了
代碼為
PaintTest.h
1 #ifndef PAINTTEST_H 2 #define PAINTTEST_H 3 4 #include <QWidget> 5 #include <QLabel> 6 #include <QPainter> 7 class PaintTest : public QWidget 8 { 9 Q_OBJECT 10 private: 11 QLabel *la; 12 public: 13 explicit PaintTest(QWidget *parent = 0); 14 // void paintEvent(QPaintEvent *); 15 bool eventFilter(QObject *watched, QEvent *event) ; 16 void magicTime(); 17 signals: 18 19 public slots: 20 21 }; 22 #endif // PAINTTEST_H
PaintTest.cpp
1 #include "PaintTest.h" 2 #include <QLabel> 3 #include <QEvent > 4 PaintTest::PaintTest(QWidget *parent) : 5 QWidget(parent),la(new QLabel(this)) 6 { 7 //la=new QLabel(this); 8 9 la->setText("PaintTest Label"); 10 la->resize(100,190); 11 12 la->installEventFilter(this); 13 } 14 /*void PaintTest::paintEvent(QPaintEvent *) { 15 QPainter painter(this); // this 是 PaintTest 的指針 16 QPainter painter(this->la); 17 painter.setPen(Qt::gray); 18 painter.setBrush(Qt::green); 19 painter.drawRect(10, 10, 50, 50); 20 }*/ 21 22 bool PaintTest::eventFilter(QObject *watched, QEvent *event) { 23 if (watched == this->la && event->type() == QEvent::Paint) { 24 magicTime(); 25 } 26 27 return QWidget::eventFilter(watched, event); 28 } 29 30 void PaintTest::magicTime() { 31 QPainter painter(this->la ); 32 painter.setPen(Qt::gray); 33 painter.setBrush(Qt::green); 34 painter.drawRect(10, 10, 50, 50); 35 }