今天主要研究如何在屏幕上绘制点线,以及如何跟踪鼠标活动。目的是将来结合这两者,实现手工在图像上涂抹选择需要修补的区域。
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
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
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();
}
}
}