Qt:事件处理
来源:互联网 发布:学而知不足 编辑:程序博客网 时间:2024/06/13 11:46
事件是一个从QEvent类继承而来的对象,任何从QObject类派生的对象均可通过QObject::event()方法
接收事件,event()函数自身并不处理事件,而是根据事件类型调用响应的事件处理器。例如,QWidget
类中的event()函数实现将鼠标、键盘、重绘等常见事件交给mousePressEvent()、keyPressEvent()、
paintEvent()这些特定的事件处理器进行处理。事件可以被传递。
Qt中处理事件的5中方式:
1、重新实现特定的事件处理器:如mousePressEvent()、keyPressEvent()、paintEvent()
2、重新实现QObject::event()函数
3、在QObject中注册事件过滤器:
如果对象使用installEventFilter()函数注册了事件过滤器,目标对象中的所有事件将首先发给这个
监视对象的eventFilter()函数。
4、在QApplication中注册事件过滤器
5、继承QApplication并重新实现notify()函数:可同时有多个事件过滤器,而notify()函数只有一个
若Qt没有为某个特定事件提供默认的事件处理器,或者提供的默认事件处理器无法满足用户需求,可以
通过重新实现QObject::event()函数来处理:
bool MyWidget::event(QEvent* event){
if(event->type() == QEvent::KeyPress){
QKeyEvent *k = static_cast<QKeyEvent*>(event);
if(i->key() == Qt::Key_Tab){
//处理Tab键缩进
return true;
}
}else if(event->type() == MyCustomEventType){
//同上
}
return QWidget::event(event); //交给父类处理
}
eg:
void DrawArea::resizeEvent(QResizeEvent* event){
if(width() > image.width() || height() > image.height()){
int newWidth = qMax(width()+128,image.width());
int newHeight = qMax(height()+128,image.height);
....
update();
}
QWidget::resizeEvent(event);
} //窗口大小改变时调用
void MainWindow::showEvent(QShowEvent* event){
timeId = startTimer(10000);
} //主窗口可见时被调用
void MainWindow::hideEvent(QHideEvent* event){
killTimer(timeId);
} //窗口不可见时调用
void MainWindow::timerEvent(QTimerEvent* event){
if(event->timerId() == timeId)
scribbleArea->clearImage();
} //定时器事件到来时调用
void MainWindow::closeEvent(QCloseEvent* event){
if(maybeSave()){
event->accept();
}else{
event->ignore();
}
} //主窗口关闭时调用
/**************************************************************************************************/
一个QObject实例可以监视另一个QObject实例中的事件,方法是在目标对象中安装事件过滤器。事件过滤器会在事件
到达目标对象之前获取该事件,从而起到监视目标对象事件的效果。
设置事件过滤器需要两步:
1、通过对目标对象调用installEventFilter()来安装事件过滤器
2、在监视对象的eventFilter()函数中处理目标对象的事件
eg:
display = new QLineEdit("");
display->installEventFilter(this); //构造函数中安装
bool Digital::eventFilter(QObject* target,QEvent* event){
if(target == display){
if(event->type() == QEvent::MouseButtonPress
|| event->type() == QEvent::MouseButtonDblClick
|| event->type() == QEvent::MouseButtonRelease
|| event->type() == QEvent::ContextMenu){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->buttons() & Qt::LeftButton){
QPalette newPalette = palette();
newPalette.setColor(QPalette::Base,
display->palette().color(QPalette::Text));
newPalette.setColor(QPalette::Text,
display->palette().color(QPalette::Bast));
display->setPalette(newPalette);
}else{
display->setPalette(palette());
}
return true;
}
}
return QDialog::eventFilter(target,event);
}
/**************************************************************************************************/
为了加快用户界面响应,防止界面冻结,Qt提供了三种方法:
1、使用多线程
2、在处理耗时事件时频繁调用QApplication::processEvents()
3、推迟耗时事件处理,直到应用程序空闲下来
eg:
//使用processEvents()函数
void Dialog::doCopy(){
while(bytesToWrite > 0){
if(isStop){
rFile->close();
wFile->close();
wFile->remove(currentFile);
progressBar->setMaximum(totalBytes);
progressBar->setValue(0);
statusLabel->setText("终止");
saveButton->setEnabled(false);
stopButton->setEnabled(false);
qApp->processEvents();
return ;
}else{
tempBuf = rFile->read(qMin(bytesToWrite,loadSize));
wFile->write(tempBuf);
bytesWritten += qMin(bytesToWrite,loadSize);
bytesToWrite -= qMin(bytesToWrite,loadSize);
progressBar->setMaximum(totalBytes);
progressBar->setValue(bytesWritten);
statusLabel->setText(tr("已拷贝%1MB").arg(bytesWritten/(1024*1024)));
tempBuf.resize(0);
qApp->processEvents();
}
}
rFile->close();
wFile->close();
}//qApp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput); //忽略鼠标键盘事件
//使用定时器:
如果处理可以被安全打断并且随后可以继续执行,这种方法可生效。通过一个特定的“0毫秒定时器”
来实现,只要没有未被处理的事件,这个定时器就会被触发:
void Dialog::timerEvent(QTimerEvent *event){
if(event->timerId() == timeId){
while((bytesToWrite > 0) && (!qApp->hasPendingEvents())){
if(isStop){
rFile->close();
wFile->close();
wFile->remove(currentFile);
progressBar->setMaximum(totalBytes);
progressBar->setValue(0);
statusLabel->setText("终止");
saveButton->setEnabled(false);
stopButton->setEnabled(false);
return ;
}else{
tempBuf = rFile->read(qMin(bytesToWrite,loadSize));
wFile->write(tempBuf);
bytesWritten += qMin(bytesToWrite,loadSize);
bytesToWrite -= qMin(bytesToWrite,loadSize);
progressBar->setMaximum(totalBytes);
progressBar->setValue(bytesWritten);
statusLabel->setText(tr("已拷贝%1MB").arg(bytesWritten/(1024*1024)));
tempBuf.resize(0);
}
}
event->accept();
}else{
Dialog::timerEvent(event);
}
}
如果hasPendingEvents()返回"true",就停止处理并把控制权交给Qt,当Qt处理完它的所有事件,定时器
事件的处理将会继续进行。
//为了使hasPendingEvents()函数正常工作,需设置环境变量“QT_NO_GLIB=1”来避免使用GLib的事件处理函数
接收事件,event()函数自身并不处理事件,而是根据事件类型调用响应的事件处理器。例如,QWidget
类中的event()函数实现将鼠标、键盘、重绘等常见事件交给mousePressEvent()、keyPressEvent()、
paintEvent()这些特定的事件处理器进行处理。事件可以被传递。
Qt中处理事件的5中方式:
1、重新实现特定的事件处理器:如mousePressEvent()、keyPressEvent()、paintEvent()
2、重新实现QObject::event()函数
3、在QObject中注册事件过滤器:
如果对象使用installEventFilter()函数注册了事件过滤器,目标对象中的所有事件将首先发给这个
监视对象的eventFilter()函数。
4、在QApplication中注册事件过滤器
5、继承QApplication并重新实现notify()函数:可同时有多个事件过滤器,而notify()函数只有一个
若Qt没有为某个特定事件提供默认的事件处理器,或者提供的默认事件处理器无法满足用户需求,可以
通过重新实现QObject::event()函数来处理:
bool MyWidget::event(QEvent* event){
if(event->type() == QEvent::KeyPress){
QKeyEvent *k = static_cast<QKeyEvent*>(event);
if(i->key() == Qt::Key_Tab){
//处理Tab键缩进
return true;
}
}else if(event->type() == MyCustomEventType){
//同上
}
return QWidget::event(event); //交给父类处理
}
eg:
void DrawArea::resizeEvent(QResizeEvent* event){
if(width() > image.width() || height() > image.height()){
int newWidth = qMax(width()+128,image.width());
int newHeight = qMax(height()+128,image.height);
....
update();
}
QWidget::resizeEvent(event);
} //窗口大小改变时调用
void MainWindow::showEvent(QShowEvent* event){
timeId = startTimer(10000);
} //主窗口可见时被调用
void MainWindow::hideEvent(QHideEvent* event){
killTimer(timeId);
} //窗口不可见时调用
void MainWindow::timerEvent(QTimerEvent* event){
if(event->timerId() == timeId)
scribbleArea->clearImage();
} //定时器事件到来时调用
void MainWindow::closeEvent(QCloseEvent* event){
if(maybeSave()){
event->accept();
}else{
event->ignore();
}
} //主窗口关闭时调用
/**************************************************************************************************/
一个QObject实例可以监视另一个QObject实例中的事件,方法是在目标对象中安装事件过滤器。事件过滤器会在事件
到达目标对象之前获取该事件,从而起到监视目标对象事件的效果。
设置事件过滤器需要两步:
1、通过对目标对象调用installEventFilter()来安装事件过滤器
2、在监视对象的eventFilter()函数中处理目标对象的事件
eg:
display = new QLineEdit("");
display->installEventFilter(this); //构造函数中安装
bool Digital::eventFilter(QObject* target,QEvent* event){
if(target == display){
if(event->type() == QEvent::MouseButtonPress
|| event->type() == QEvent::MouseButtonDblClick
|| event->type() == QEvent::MouseButtonRelease
|| event->type() == QEvent::ContextMenu){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->buttons() & Qt::LeftButton){
QPalette newPalette = palette();
newPalette.setColor(QPalette::Base,
display->palette().color(QPalette::Text));
newPalette.setColor(QPalette::Text,
display->palette().color(QPalette::Bast));
display->setPalette(newPalette);
}else{
display->setPalette(palette());
}
return true;
}
}
return QDialog::eventFilter(target,event);
}
/**************************************************************************************************/
为了加快用户界面响应,防止界面冻结,Qt提供了三种方法:
1、使用多线程
2、在处理耗时事件时频繁调用QApplication::processEvents()
3、推迟耗时事件处理,直到应用程序空闲下来
eg:
//使用processEvents()函数
void Dialog::doCopy(){
while(bytesToWrite > 0){
if(isStop){
rFile->close();
wFile->close();
wFile->remove(currentFile);
progressBar->setMaximum(totalBytes);
progressBar->setValue(0);
statusLabel->setText("终止");
saveButton->setEnabled(false);
stopButton->setEnabled(false);
qApp->processEvents();
return ;
}else{
tempBuf = rFile->read(qMin(bytesToWrite,loadSize));
wFile->write(tempBuf);
bytesWritten += qMin(bytesToWrite,loadSize);
bytesToWrite -= qMin(bytesToWrite,loadSize);
progressBar->setMaximum(totalBytes);
progressBar->setValue(bytesWritten);
statusLabel->setText(tr("已拷贝%1MB").arg(bytesWritten/(1024*1024)));
tempBuf.resize(0);
qApp->processEvents();
}
}
rFile->close();
wFile->close();
}//qApp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput); //忽略鼠标键盘事件
//使用定时器:
如果处理可以被安全打断并且随后可以继续执行,这种方法可生效。通过一个特定的“0毫秒定时器”
来实现,只要没有未被处理的事件,这个定时器就会被触发:
void Dialog::timerEvent(QTimerEvent *event){
if(event->timerId() == timeId){
while((bytesToWrite > 0) && (!qApp->hasPendingEvents())){
if(isStop){
rFile->close();
wFile->close();
wFile->remove(currentFile);
progressBar->setMaximum(totalBytes);
progressBar->setValue(0);
statusLabel->setText("终止");
saveButton->setEnabled(false);
stopButton->setEnabled(false);
return ;
}else{
tempBuf = rFile->read(qMin(bytesToWrite,loadSize));
wFile->write(tempBuf);
bytesWritten += qMin(bytesToWrite,loadSize);
bytesToWrite -= qMin(bytesToWrite,loadSize);
progressBar->setMaximum(totalBytes);
progressBar->setValue(bytesWritten);
statusLabel->setText(tr("已拷贝%1MB").arg(bytesWritten/(1024*1024)));
tempBuf.resize(0);
}
}
event->accept();
}else{
Dialog::timerEvent(event);
}
}
如果hasPendingEvents()返回"true",就停止处理并把控制权交给Qt,当Qt处理完它的所有事件,定时器
事件的处理将会继续进行。
//为了使hasPendingEvents()函数正常工作,需设置环境变量“QT_NO_GLIB=1”来避免使用GLib的事件处理函数
0 0
- qt中的事件处理
- QT 事件处理
- Qt事件处理机制
- QT事件处理
- Qt事件处理机制
- Qt事件处理机制
- qt 双击事件处理
- Qt事件处理
- qt事件处理
- Qt:事件处理
- QT 事件处理
- Qt 事件处理
- Qt 事件处理 快捷键
- Qt事件处理机制
- Qt Focus 事件处理
- Qt事件处理
- qt事件处理机制
- Qt事件处理摘录
- ubuntu14.04安装openstack的Juno版环境--使用PPA源
- Javascript是单线程的深入分析
- 数据泵expdp导出数据备份,以及expdp命令的中断方法
- 求所有子数组的和的最大值。要求时间复杂度为O(n)
- Qt中不规则异形窗口的实现几点总结
- Qt:事件处理
- linux awk命令详解
- 诺奖,出版界的“双十一”
- Windows 不能在 本地计算机 启动 SQL Server 服务 错误代码126
- 数据结构之串14匹配算法
- Windows Driver Kit (WDK) 8.0 がリリースされました
- Volley框架核心源码分析
- 将View存成bitmap,去色,作为LinearLayout背景,选中时为蓝色背景,未选中为灰色背景
- Qt:数据库编程