今天主要研究如何在屏幕上繪製點線,以及如何跟蹤鼠標活動。目的是將來結合這兩者,實現手工在圖像上塗抹選擇需要修補的區域。
1. 如果要繪製的點線直接顯示在住窗口中,則可以直接在mainwindow.h文件中直接定義一個public函數,並在對應的cpp文件中實現,即可。
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPen pointPen(Qt::red);
pointPen.setWidth(6);
painter.setPen(pointPen);
painter.drawPoint(100,100);
}QPainter對應的畫圖動作的完成者,QPen指的是完成動作者使用的工具,可定義其顏色,寬度等
QPainter可以對應多種畫法,drawLine,drawPoint等等均可。
2. 跟蹤鼠標,首先建立一個鼠標檢測區域,如label組件,右擊項目名,新建一個類,對應該組件,對應的方法是在ui界面右擊該組件,選擇prompt,選擇對應的新建類。這個新建類是組件本身所在類的子類。在這個新建類中,將定義該組件特有的一些SLOT,signal等。如這個label區域是用來檢測鼠標區域的,所以特有類包括鼠標按下、移動等SIGNAL,以及產生這些signal的函數。
新建的類my_label.h
#ifndef MY_LABEL_H
#define MY_LABEL_H
#include <QLabel>
#include <QMouseEvent>
#include <QEvent>
class my_label : public QLabel
{
Q_OBJECT
public:
explicit my_label(QWidget *parent = 0);
void mouseMoveEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
void leaveEvent(QEvent *);
int x,y;
signals:
void mousePressed();
void mousePos();
void mouseLeft();
// void mouseEnter();
public slots:
};
#endif // MY_LABEL_H
新建類的實現my_label.cpp
#include "my_label.h"
my_label::my_label(QWidget *parent) :
QLabel(parent)
{
}
void my_label::mouseMoveEvent(QMouseEvent *ev)
{
this->x = ev->y();
this->y = ev->y();
emit mousePos();
}
void my_label::mousePressEvent(QMouseEvent *ev)
{
emit mousePressed();
}
void my_label::leave_enter_Event(QEvent *)
{
emit mouseLeft();
}
新建這個類之後編譯時可能出現問題“Cannot open include file in ui_mainwindow.h”,這是因爲在ui_mainwindow.h中新建的.h文件自動生成的include格式不對,需要手動修改,從<>改爲""(有自動修改的方法嗎?偶木有找到)
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QWidget>
#include "my_label.h" //不能用<>
3. 新建組件label之所以會產生鼠標按鍵、移動等SIGNAL,是因爲相應的函數中採用的相關QMouseEvent,Event的對象,這兩個event的意思我理解爲,鼠標一移動就產生一個QMouseEvent的對象,這些對象就會導致相應public函數的產生,而函數的主題部分emit出的就是SIGNAL.
這些SIGNAL將會在mainwindow中跟之前的SIGNAL一樣應用,如connect到相應的SLOT,完成對其他組件的控制等。
如這裏,我在mainwindow.h中定義了對應的SLOTS,
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
#include <QtGui>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void mouse_pos();
void mouse_pressed();
void mouse_left();
// void mouse_enter();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
並實現在其他label中顯示鼠標位置(這裏的位置是對應LABEL的左上方點的座標值)和狀態
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->label,SIGNAL(mousePos()),this, SLOT(mouse_pos()));
connect(ui->label,SIGNAL(mousePressed()),this,SLOT(mouse_pressed()));
connect(ui->label,SIGNAL(mouseLeft()),this,SLOT(mouse_left()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::mouse_pos()
{
ui->label_2->setText("x: "+QString::number(ui->label->x)+" , y: "+ QString::number(ui->label->y));
ui->label_3->setText("Mouse moving!");
}
void MainWindow::mouse_pressed()
{
ui->label_3->setText("Mouse pressed!");
}
void MainWindow::mouse_left()
{
ui->label_3->setText("Mouse left!");
}
結果如下
4. 區分鼠標左右鍵,用QMouseEvent對象的成員函數buttons()值來判斷
if(ev->buttons()==Qt::LeftButton){
this->x = ev->x();
this->y = ev->y();
emit mousePos();
}
但問題是,按理說應該是button()返回一個值,buttons()返回的是一個三個鍵的真假組合,網上找到的例子也是用button()較多,但上面的代碼換成button()就不行。。。不知道爲啥。。。 以後類似的情況就多試試吧。。。==!
5. 鼠標必須在LABEL區域內移動纔會有顯示以及對鼠標進入離開LABEL區域的判定,上面的代碼中靠一個Event對象來檢測,不過,我試了一下,不知道哪裏有問題,一直不對勁,所以改成靠判斷鼠標的座標值來判斷是否在合法區域內部。
void my_label::mouseMoveEvent(QMouseEvent *ev)
{
if(ev->buttons()==Qt::LeftButton){
this->x = ev->x();
this->y = ev->y();
if(this->x > this->width()||this->x<0 || this->y<0||this->y>this->height()){
emit mouseLeft();
}
else{
emit mousePos();
}
}
}