Qt實現畫板部件並和自定義button按鈕結合例項
阿新 • • 發佈:2019-02-17
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();
}