qt creator 畫點線,跟蹤鼠標

今天主要研究如何在屏幕上繪製點線,以及如何跟蹤鼠標活動。目的是將來結合這兩者,實現手工在圖像上塗抹選擇需要修補的區域。


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();
        }

    }

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章