Qt實現畫板部件並和自定義button按鈕結合例項

readyao發表於2015-11-30

1.首先新建一個空專案,新增一個類,該類繼承自QWidget, 然後使該視窗部件實現畫板的功能,這個功能是比較簡單的畫線;

實現該功能的思路是:當滑鼠按下的時候記錄滑鼠的位置(一個點ev->pos())並更新視窗部件,當滑鼠移動的時候也記錄滑鼠的位置並更新視窗部件,當滑鼠離開的時候也記錄滑鼠的位置並更新視窗部件;(一定要更新update(),否則不會顯示剛剛的線,因為呼叫update()的時候,會呼叫paintEvent()函式,該函式會重畫那些記錄的畫線);

每次滑鼠按下的時候就要新建一個Vector<QPoint>物件,因為每次滑鼠按下的時候是一個新的線要畫;

備註:什麼時候視窗會呼叫void MyWidget::paintEvent(QPaintEvent *)?

(1):視窗初始化的時候;

(2):手動呼叫update()的時候;本例就用到了這個函式

(3):當視窗的大小發生了改變;

2:自定義一個button按鈕,在該專案上新增一個類,該類也是繼承自QWidget;

實現該功能的思路是:當滑鼠點選該按鈕的時候就將按鈕的顏色變為黃色,當滑鼠離開該按鈕的時候,該按鈕的顏色變為灰色;當滑鼠按下和離開的時候,都要手動呼叫update()函式,這樣才會重繪該部件;

還在該部件上面新增了clicked()訊號,當滑鼠按下該按鈕,並且滑鼠離開的位置在按鈕上面,則發出該訊號;

當按下按鈕,會發出clicked()訊號,則會呼叫MyWidget部件自定義的slotButtonClicked槽函式,列印This is button clicked;


mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QWidget>

class MyButton : public QWidget
{
    Q_OBJECT
public:
    explicit MyButton(QWidget *parent = 0);
    MyButton(const QString &text, QWidget *parent = 0);

    QRect _rect;//位置
    QString _text;//按鈕上的字型
    bool mousePressed;//滑鼠是否按下,按下則是true,否則是false
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
signals:
    void clicked();//clicked()訊號,當滑鼠按下該按鈕,並且滑鼠離開的位置在按鈕上面,則發出該訊號
public slots:
    
};

#endif // MYBUTTON_H

mybutton.cpp

#include "mybutton.h"
#include <QPainter>
#include <QMouseEvent>

MyButton::MyButton(QWidget *parent) :
    QWidget(parent), _rect(0, 0, 100, 30), _text("Button")
{
    mousePressed = false;
    this->setGeometry(_rect);
}

MyButton::MyButton(const QString &text, QWidget *parent):QWidget(parent), _text(text), _rect(0, 0, 100, 30)
{
    mousePressed = false;
    this->setGeometry(_rect);
}

void MyButton::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    if(mousePressed)//如果按鈕按下,則按鈕變為黃色
        p.setBrush(Qt::yellow);
    else
        p.setBrush(Qt::darkGray);//如果按鈕沒有按下,則按鈕是灰色

    p.drawRect(_rect);
    p.drawText(_rect,_text, QTextOption(Qt::AlignCenter));
}

void MyButton::mousePressEvent(QMouseEvent *)
{
    mousePressed = true;
    update();
}

void MyButton::mouseReleaseEvent(QMouseEvent *ev)
{
    mousePressed = false;
    update();

    if(_rect.contains(ev->pos()))//如果滑鼠離開的位置在button按鈕上面,則發出訊號
        emit clicked();
}


mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include "mybutton.h"

class MyWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *ev);
    void mouseMoveEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);
    //QVector<QPoint> _line;//記錄滑鼠經過的每一個點
    QVector<QVector<QPoint> > _lines;
    MyButton * button;
signals:

public slots:
    void slotButtonClicked();
};

#endif // MYWIDGET_H

mywidget.cpp

#include "mywidget.h"
#include <QApplication>
#include <QPainter>
#include <QPushButton>
#include <QMouseEvent>
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)
{
    button = new MyButton(this);//呼叫第一個系統生成的建構函式
    //button = new MyButton("MyButton", this);//呼叫第二個自定義的建構函式
    button->setGeometry(150, 150, 100, 30);
    connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));//當按下按鈕,會發出clicked()訊號,則會呼叫slotButtonClicked槽函式,列印This is button clicked
}

/*這個函式什麼時候會被呼叫?
*1.視窗初始化的時候
*2.手動呼叫update的時候
*3.視窗的大小發生改變的時候
*/
void MyWidget::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    for(int i = 0; i < _lines.size(); ++i){
        const QVector<QPoint> & line = _lines.at(i);
        for (int j = 0; j < line.size()-1; ++j){
            p.drawLine(line.at(j), line.at(j+1));
        }
    }

}
void MyWidget::mousePressEvent(QMouseEvent *ev)
{
    QVector<QPoint> line;
    _lines.append(line);
    QVector<QPoint> & lastLine = _lines.last();//最後一條線

    lastLine.append(ev->pos());
    update();
}

void MyWidget::mouseMoveEvent(QMouseEvent *ev)
{
    if(_lines.isEmpty()){  //為了防止點選button按鈕然後移動到其它位置時出現異常,因為下面要對_lines操作
        QVector<QPoint> line;
        _lines.append(line);
    }
    QVector<QPoint> & lastLine = _lines.last();//最後一條線
    lastLine.append(ev->pos());
    update();
}

void MyWidget::mouseReleaseEvent(QMouseEvent *ev)
{
    QVector<QPoint> & lastLine = _lines.last();//最後一條線
    lastLine.append(ev->pos());
    update();
}

void MyWidget::slotButtonClicked()
{
    qDebug() << "This is button clicked";
}

int main(int argc, char **argv)
{

    QApplication app(argc, argv);

    MyWidget w;
    w.setGeometry(400, 150, 400,400);
    w.show();

    app.exec();
}




相關文章