1. QT事件介绍
1.1事件介绍
事件是对各种应用程序需要的知道由应用程序内部或者外部产生的事情或者动作的通称,在QT中使用一个对象来表示一个事件,它继承自QEvent类。
常见事件:鼠标事件,键盘事件,定时事件,上下菜单事件,关闭事件,拖放事件,绘制事件,触摸屏事件。
1.2事件的处理
重载Event函数
重新实现事件的paintEvent(),mousePressEvent()事件处理函数。这是最常用的一种方法,不过这只能用来处理特定部件的特定事件。像实现拖放操作,就是用的这种方法。
安装事件过滤器
在对象上安装事件过滤器。实现事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。
2.键盘按键
QKeyEvent : QKeyEvent类用来描述一个键盘事件,当键盘按键被按下或者被释放时,键盘事件会被发送消息给拥有键盘输入焦点的部件。
处理键盘事件需要重载keyPressEvent:
2.1找到KeyPressEvent接口
首先需要在头文件中加入KeyPressEvent
然后按住Ctrl + 鼠标左键找到虚函数接口,在qwidget.h中。
复制到头文件中,保持protected属性不变
protected: virtual void keyPressEvent(QKeyEvent *event);
2.2鼠标按下事件
keyPressEvent
event->key();
void Widget::keyPressEvent(QKeyEvent *event)
{
if(event->key()==Qt::Key_T)
{
qDebug()<<"Key T is pressed";
}
else if(event->key()==Qt::Key_Z)
{
qDebug()<<"Key Z is pressed";
}
}
2.3 组合按键按下事件
keyPressEvent
event->modifiers();
组合按键需要借助Ctrl和Shift等按键,在QT中又叫修饰按键,这里需要使用QKeyEvent的modifiers()函数来获取它们;
void Widget::keyPressEvent(QKeyEvent *event)
{
//Ctrl组合键
// if(event->modifiers()==Qt::ControlModifier)
// {
// if(event->key()==Qt::Key_T)
// {
// qDebug()<<"Ctrl+Key_T is pressed";
// }
// else if(event->key()==Qt::Key_Z)
// {
// qDebug()<<"Crtl+Key_Z is pressed";
// }
// }
//Shift组合键
if(event->modifiers()==Qt::ShiftModifier)
{
if(event->key()==Qt::Key_T)
{
qDebug()<<"Shift+Key_T is pressed";
}
else if(event->key()==Qt::Key_Z)
{
qDebug()<<"Shift+Key_Z is pressed";
}
}
}
2.4按键释放
keyReleaseEvent
event->key()
void Widget::keyPressEvent(QKeyEvent *event)
{
if(event->key()==Qt::Key_T)
{
qDebug()<<"Key_T is pressed";
}
else if(event->key()==Qt::Key_Z)
{
qDebug()<<"Key_T is pressed";
}
}
void Widget::keyReleaseEvent(QKeyEvent *event)
{
if(event->key()==Qt::Key_T)
{
qDebug()<<"Key_T is released";
}
else if(event->key()==Qt::Key_Z)
{
qDebug()<<"Key_T is released";
}
}
3.鼠标与滚轮事件
QMouseEvent: QMouseEvent类用来表示一个鼠标事件,当窗口部件按下鼠标或者移动鼠标指针时,都会产生鼠标事件。利用QMouseEvent类可以获知鼠标是否按下了,还有鼠标指针当前位置信息。通常是重定义部件的鼠标事件处理函数来进行一些自定义的操作。
QWheelEvent:QWheelEvent类用来表示鼠标滚轮事件,在这个类中主要是获取滚轮移动的方向和距离。在滚轮事件处理函数中,使用QWheelEvent类的delta()函数获取了滚轮移动的距离,每当滚轮旋转一次,默认的是15度,当滚轮向远离使用者的方向旋转时,返回负值。这样便可以利用这个函数的返回值来判断滚轮的移动方向。
delta()函数在复制,选中时很有用。
3.1鼠标单击事件
mousePressEvent
event->button();
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
qDebug()<<QStringLiteral("鼠标左键按下");
}
else if(event->button()==Qt::RightButton)
{
qDebug()<<QStringLiteral("鼠标右键按下");
}
else if(event->button()==Qt::MiddleButton)
{
qDebug()<<QStringLiteral("鼠标中键按下");
}
}
3.2鼠标释放事件
event->button()
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
switch(event->button())
{
case Qt::LeftButton:
qDebug()<<QStringLiteral("鼠标左键释放");
break;
case Qt::RightButton:
qDebug()<<QStringLiteral("鼠标右键释放");
break;
case Qt::MiddleButton:
qDebug()<<QStringLiteral("鼠标中键释放");
break;
}
}
3.3鼠标双击事件
mouseDoubleClickEvent
event->button();
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
switch(event->button())
{
case Qt::LeftButton:
qDebug()<<QStringLiteral("鼠标左键双击事件");
break;
case Qt::RightButton:
qDebug()<<QStringLiteral("鼠标右键双击事件");
break;
case Qt::MiddleButton:
qDebug()<<QStringLiteral("鼠标中键双击事件");
break;
}
}
3.4鼠标移动事件
mouseMoveEvent
setMouseTracking(true);
event->pos()
event->globalPos()
setMouseTracking默认为false及只有鼠标按下时才追踪鼠标移动事件演示实时鼠标所在的坐标
void Widget::mouseMoveEvent(QMouseEvent *event)
{
setMouseTracking(true);
QString str=QString(QStringLiteral("鼠标当前坐标为:(%1,%2)")).arg(event->pos().x()).arg(event->pos().y());
ui->pushButton->setText(str);//借助一个pushbutton将坐标显示在pushbutton中
}
3.5滚轮事件
wheelEvent
event->delta();
void Widget::wheelEvent(QWheelEvent *event)
{
if(event->delta()>0)
{
qDebug()<<QStringLiteral("滚轮往前推......");
}
else
{
qDebug()<<QStringLiteral("滚轮往后推......");
}
}
4.事件过滤器
使用事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。只要是对象或者部件安装了事件过滤器,就会进入事件过滤器函数,eventFilter(QObject obj,QEvent event)。采用了类似于mousePressEvent重写函数事件来实现此功能。
installEventFilter
eventFilter
event->type()
首先需要判断这个需要处理的事件是否属于textEdit,如果是则处理
public: virtual bool eventFilter(QObject *watched, QEvent *event);
在构造函数中添加
ui‐>textEdit‐>installEventFilter(this); //安装Event过滤器
这里需要在ui界面中添加一个textEdit对话框
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(watched==ui->textEdit)
{
if(event->type()==QEvent::KeyPress)
{
QKeyEvent *keyEvent=static_cast<QKeyEvent*>(event);
qDebug()<<"At key press"<<keyEvent->key();
return true;
}
else
{
return false;
}
}
else
{
return Widget::eventFilter(watched,event);
}
}
5.定时器
QTimerEvent : QTimerEvent类用来描述一个定时器事件。对于一个QObject的子类,只需要使用int QObject::startTimer(int interval)函数来开启一个定时器,这个函数需要输入一个以毫秒为单位的整数作为参数来表明设定时间,它返回一个整型编号代表这个定时器。当定时器溢出时就可以在timerEvent()函数中获取该定时器编号来进行相关操作。
QTimer : QTimer类来实现一个定时器,它提供了更高层次的编程接口,比如可以使用信号,还可以设置只运行一次的定时器。
5.1QTimerEvent
startTimer
timeEvent
event->timerId()
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
id1=startTimer(1000);
id2=startTimer(2000);
id3=startTimer(3000);
id4=startTimer(4000);
}
Widget::~Widget()
{
delete ui;
}
void Widget::timerEvent(QTimerEvent *event)
{
if(event->timerId()==id1)
{
qDebug()<<"timer1 timeout";
return;
}
else if(event->timerId()==id2)
{
qDebug()<<"timer2 timeout";
return;
}
else if(event->timerId()==id3)
{
qDebug()<<"timer3 timeout";
return;
}
else if(event->timerId()==id4)
{
qDebug()<<"timer4 timeout";
return;
}
}
5.2QTimer定时器
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer *timer=new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(refreshTime()));
timer->start(1000);
QTime time=QTime::currentTime();
QString text=time.toString("hh:mm:ss");
ui->lcdNumber->display(text);
}
6.随机数
6.1产生随机数种子
可以使用QTimer().secsTo 设置随机数
在使用qrand()函数产生随机数之前,一般要使用qsrand()函数为其设置初值,如果不设初值,那么每次运行程序,qrand()都会产生相同的一组随机数。为了每次运行程序时,都可以产生不同的随机数,我们要使用qsrand()设置一个不同的初值。
产生随机数种子
/* 指从零点整到当前时间所经过的秒数 */
qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
6.2随机数种子
得到随机数
int rand=qrand()%300;