QPainter繪制遇到的小問題


 
        

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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM