如何實現窗口中子控件的繪圖(paintEvent())事件


在重寫paintEvent()函數時,這個paintEvent()屬於哪個對象,那么就會重新繪制該對象,但是這樣也面臨着一個問題:

假如我重寫了一個mainwindow的paintEvent(),那么該paintEvent只對MainWindow生效,

如果想繪制的圖形是在MainWindow上的子的組件應該怎么繪制在哪里繪制?

一般想到的是直接在paintEvent()更改,但是想要在哪個 控件上繪圖,就需要在它的 paintEvent() 函數里繪圖,對於用Qt designer中編輯的控件,必須新建一個類繼承自控件,然后在它的 paintEvent() 里繪圖,如果單獨就這個問題創建一個新的類就會有點小題大作了

因此可以用事件過濾器來解決這個問題

首先需要在頭文件中添加 eventFilter函數,

class MainWindow : public QMainWindow
{
    Q_OBJECT
protected:
    bool eventFilter(QObject *watched, QEvent *event) ;
}

在源文件中實現eventFilter

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(ui->stackedWidget_3->currentIndex() == 1)
    {
        if (watched == ui->linkWidget_1 && event->type() == QEvent::Paint)
        {
            for(int i = 0;i < linkLinePoints.count();i++)
            {
                int x1,y1,x2,y2;
                x1 = linkLinePoints.at(i).at(0)+10;
                y1 = linkLinePoints.at(i).at(1)+10;
                x2 = linkLinePoints.at(i).at(2)+10;
                y2 = linkLinePoints.at(i).at(3)+10;

                QPainter painter(ui->linkWidget_1 );
                QPen pen;  // creates a default pen
                pen.setWidth(3);

                if(i == 0)
                   pen.setBrush(Qt::black);
                else if(i == 1)
                    pen.setBrush(Qt::red);
                else if(i == 2)
                    pen.setBrush(Qt::blue);
                else if(i == 3)
                    pen.setBrush(Qt::green);

                painter.setPen(pen);
                painter.drawLine(x1,y1, x2,y2);
            }
        }
    }
    else if(ui->stackedWidget_3->currentIndex() == 0)
    {
        if(watched == ui->linkWidget_2 && event->type() == QEvent::Paint)
        {

            for(int i = 0;i < linkLinePoints.count();i++)
            {
                int x1,y1,x2,y2;
                x1 = linkLinePoints.at(i).at(0)+10;
                y1 = linkLinePoints.at(i).at(1)+10;
                x2 = linkLinePoints.at(i).at(2)+10;
                y2 = linkLinePoints.at(i).at(3)+10;

                QPainter painter(ui->linkWidget_2 );
                QPen pen;  // creates a default pen
                pen.setWidth(3);

                if(i == 0)
                   pen.setBrush(Qt::black);
                else
                    pen.setBrush(Qt::red);

                painter.setPen(pen);
                painter.drawLine(x1,y1, x2,y2);
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}

之后,再將我們想要繪制的控件與這個過濾函數關聯起來

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->linkWidget_1->installEventFilter(this);
    ui->linkWidget_2->installEventFilter(this);
}

在這個程序中,我分別將兩個widget子控件ui->linkWidget_1 和 ui->linkWidget_2 和這個事件關聯起來,關聯起來之后,在eventfilter函數中,需要注意紅色字體代碼所在處,要正確關聯watch對象和設置painter對象才可正確繪制。

最后,在相應的地方調用upDate函數,即可實現對子控件的繪制。

 用該方法實現的子控件繪制,不需要重寫MainWindow的paintEvent函數,將其刪除或者注釋掉就行。

需要注意的是,如果控件有了自己的styleSheet,那么再重新實現paintEvent是不會生效的,這兩個功能互相沖突。


免責聲明!

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



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