来自 澳门金莎娱乐手机版 2019-11-14 16:49 的文章
当前位置: 金沙澳门官网网址 > 澳门金莎娱乐手机版 > 正文

事件管理,Qt学习之路

图片 1void QWidget::mousePressEvent(QMouseEvent *event)
图片 2{
图片 3        event->ignore();
图片 4        if ((windowType() == Qt::Popup)) {
图片 5                event->accept();
图片 6                QWidget* w;
图片 7                while ((w = qApp->activePopupWidget()) && w != this){
图片 8                        w->close();
图片 9                        if (qApp->activePopupWidget() == w) // widget does not want to dissappear
图片 10                                w->hide(); // hide at least
图片 11                }
图片 12                if (!rect().contains(event->pos())){
图片 13                        close();
图片 14                }
图片 15        }
图片 16}

 

我们可以把Qt的事件传递看成链状:如果子类没有处理这个事件,就会继续向其他类传递。其实,Qt的事件对象都有一个accept()函数和ignore()函数。正如它们的名字,前者用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;后者则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递,寻找另外的接受者。在事件处理函数中,可以使用isAccepted()来查询这个事件是不是已经被接收了。

重写eventFilter的函数如下:

前面说到了事件的作用,下面来看看我们如何来接收事件。回忆一下前面的代码,我们在子类中重写了事件函数,以便让这些子类按照我们的需要完成某些功能,就像下面的代码:

一个例子:

事实上,我们很少使用accept()和ignore()函数,而是想上面的示例一样,如果希望忽略事件,只要调用父类的响应函数即可。记得我们曾经说过,Qt中的事件大部分是protected的,因此,重写的函数必定存在着其父类中的响应函数,这个方法是可行的。为什么要这么做呢?因为我们无法确认父类中的这个处理函数没有操作,如果我们在子类中直接忽略事件,Qt不会再去寻找其他的接受者,那么父类的操作也就不能进行,这可能会有潜在的危险。另外我们查看一下QWidget的mousePressEvent()函数的实现:

 

图片 17void MainWindow::closeEvent(QCloseEvent * event)
图片 18{
图片 19        if(continueToClose()) {
图片 20                event->accept();
图片 21        } else {
图片 22                event->ignore();
图片 23        }
图片 24}
图片 25
bool MainWindow::continueToClose()
图片 26{
图片 27        if(QMessageBox::question(this,
图片 28                                            tr("Quit"),
图片 29                                            tr("Are you sure to quit this application?"),
图片 30                                            QMessageBox::Yes | QMessageBox::No,
图片 31                                            QMessageBox::No)
图片 32                == QMessageBox::Yes) {
图片 33                return true;
图片 34        } else {
图片 35                return false;
图片 36        }
图片 37}

  1. #include "mainwindow.h"    
  2. #include <QKeyEvent>    
  3. #include <QMessageBox>    
  4. #include <QDebug>    
  5. #include <QShortcut>    
  6. #include <QPushButton>    
  7. #include <QHBoxLayout>    
  8. #include <QAction>    
  9.     
  10. MainWindow::MainWindow(QWidget *parent) :    
  11.     QMainWindow(parent)    
  12. {        
  13.     // 设置窗口布局    
  14.     QWidget *mainWidget = new QWidget(this);    
  15.     
  16.     QPushButton *button1 = new QPushButton("MessageBoxA", this);    
  17.     QPushButton *button2 = new QPushButton("MessageBoxB", this);    
  18.     
  19.     QHBoxLayout *layout = new QHBoxLayout(this);    
  20.     
  21.     layout->addWidget(button1);    
  22.     layout->addWidget(button2);    
  23.     
  24.     mainWidget->setLayout(layout);    
  25.     
  26.     this->setCentralWidget(mainWidget);    
  27.     this->resize(200, 100);    
  28.     this->setWindowTitle("Test");    
  29.     
  30.     // 创建QAction并设置快捷键    
  31.     QAction *actionA = new QAction(this);    
  32.     actionA->setShortcut(QKeySequence(tr("Ctrl+A")));    
  33.     // actionA->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_A));    
  34.     
  35.     QAction *actionB = new QAction(this);    
  36.     actionB->setShortcut(QKeySequence(tr("Ctrl+B")));    
  37.     // actionA->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));    
  38.     
  39.     // 给button添加快捷键    
  40.     // this->addAction(actionA);// 没用    
  41.     
  42.     button1->addAction(actionA);// 必须将快捷键添加到按钮上,同时使keyPressEvent失效,无法捕捉到Ctrl+A    
  43.     button2->addAction(actionB);    
  44.     
  45.     // 设置快捷键相应    
  46.     connect(actionA, &QAction::triggered, this, &MainWindow::button1_click);    
  47.     connect(actionB, &QAction::triggered, this, &MainWindow::button2_click);    
  48.     // 设置按钮点击事件相应    
  49.     connect(button1, &QPushButton::clicked, this, &MainWindow::button1_click);    
  50.     connect(button2, &QPushButton::clicked, this, &MainWindow::button2_click);    
  51.     
  52.     // 占用快捷键,使keyPressEvent函数失效    
  53.     QShortcut *shortCut1 = new QShortcut(QKeySequence(tr("Delete")), this);    
  54.     QShortcut *shortCut2 = new QShortcut(QKeySequence(tr("Return")), this);    
  55.     // QShortcut *shortCut2 = new QShortcut(tr("Return"), this);    
  56. }    
  57.     
  58. MainWindow::~MainWindow()    
  59. {    
  60.     
  61. }    
  62. // 如果快捷键被设置,keyPressevent就无法处理相应的按钮事件    
  63. void MainWindow::keyPressEvent(QKeyEvent *event)    
  64. {    
  65.     switch (event->key())    
  66.     {    
  67.         case Qt::Key_0:    
  68.         {    
  69.             qDebug() << Qt::Key_0;    
  70.             QMessageBox::about(NULL, "0", "0");    
  71.             break;    
  72.         }    
  73.         case Qt::Key_Return:// 被占用,失效    
  74.         {    
  75.             qDebug() << Qt::Key_Return;    
  76.             QMessageBox::about(NULL, "return", "return");    
  77.             break;    
  78.         }    
  79.         case Qt::Key_Delete:// 被占用,失效    
  80.         {    
  81.             qDebug() << Qt::Key_Delete;    
  82.             QMessageBox::about(NULL, "Delete", "Delete");    
  83.             break;    
  84.         }    
  85.         case QKeySequence::Delete:// 捕获不到,不能有这种方式处理    
  86.         {    
  87.             qDebug() << QKeySequence::Delete;    
  88.             QMessageBox::about(NULL, "QKeySequence::Delete", "QKeySequence::Delete");    
  89.             break;    
  90.         }    
  91.         case Qt::Key_F1:    
  92.         {    
  93.             qDebug() << Qt::Key_F1;    
  94.             QMessageBox::about(NULL, "F1", "F1");    
  95.             break;    
  96.         }    
  97.         case Qt::Key_O:// 处理组合快捷按钮    
  98.         {    
  99.             if (event->modifiers() & Qt::ControlModifier)    
  100.             {    
  101.                 QMessageBox::about(NULL, "Ctr+O", "Ctr+O");    
  102.             }    
  103.             break;    
  104.         }    
  105.         case Qt::Key_A:// 被窗口button占用,失效,不能处理    
  106.         {    
  107.             if (event->modifiers() & Qt::ControlModifier)    
  108.             {    
  109.                 QMessageBox::about(NULL, "Ctr+A", "Ctr+A");    
  110.             }    
  111.             break;    
  112.         }    
  113.         default:    
  114.         {    
  115.             qDebug() << event->key();    
  116.         }    
  117.     }    
  118. //    if (event->key() == Qt::Key_O)    
  119. //    {    
  120. //        if (event->modifiers() & Qt::ControlModifier)    
  121. //        {    
  122. //            QMessageBox::about(NULL, "Ctr+O", "Ctr+O");    
  123. //        }    
  124. //     }    
  125. }    
  126.     
  127. void MainWindow::keyReleaseEvent(QKeyEvent *event)    
  128. {    
  129.     
  130. }    
  131.     
  132. void MainWindow::button1_click()    
  133. {    
  134.     QMessageBox::about(NULL, "MessageBoxA", "MessageBoxA");    
  135. }    
  136.     
  137. void MainWindow::button2_click()    
  138. {    
  139.     QMessageBox::about(NULL, "MessageBoxB", "MessageBoxB");    
  140. }    

请注意第一条语句,如果所有子类都没有覆盖mousePressEvent函数,这个事件会在这里被忽略掉,这暗示着这个组件不关心这个事件,这个事件就可能被传递给其父组件。

 

这样,我们经过询问之后才能正常退出程序。

[cpp] view plain copy

前面说...

在现在的即时聊天程序中,一般都设置有快捷键来实现一些常用的功能,类似QQ可以用CTRL+Enter来实现信息的发送。

本章内容也是关于Qt事件。或许这一章不能有一个完整的例子,因为对于事件总是感觉很抽象,还是从底层上理解一下比较好的吧!

 

本文出自 “豆子空间” 博客,请务必保留此出处

  1. bool Window::eventFilter(QObject *obj, QEvent *e)  
  2. {  
  3.      Q_ASSERT(obj == ui.inputMsgEdit);  
  4.      if (e->type() == QEvent::KeyPress)  
  5.      {  
  6.          QKeyEvent *event = static_cast(e);  
  7.          if (event->key() == Qt::Key_Return && (event->modifiers() & Qt::ControlModifier))  
  8.          {  
  9.               sendMessage();  
  10.               return true;  
  11.           }  
  12.       }  
  13.       return false;  
  14. }  

图片 38void MyLabel::mousePressEvent(QMouseEvent * event)
图片 39{
图片 40        if(event->button() == Qt::LeftButton) {
图片 41                // do something
图片 42        } else {
图片 43                QLabel::mousePressEvent(event);
图片 44        }
图片 45}

 

不过,事情也不是绝对的。在一个情形下,我们必须使用accept()和ignore()函数,那就是在窗口关闭的时候。如果你在窗口关闭时需要有个询问对话框,那么就需要这么去写:

看了下QT文档对于这个函数的声明的解释,大概意思就是如果你要过滤某个事件就返回false,如果要使用某个事件就返回true。

上面的代码和前面类似,在鼠标按下的事件中检测,如果按下的是左键,做我们的处理工作,如果不是左键,则调用父类的函数。这在某种程度上说,是把事件向上传递给父类去响应,也就是说,我们在子类中“忽略”了这个事件。

我想在这个函数中加入对Enter键和Ctrl+Enter组合键的判断,具体查看QKeyEvent类的文档

在窗体中相应mousePressEvent事件函数在其中检测Ctrl键是否按住即可。

只要在窗体中相应keyPressEvent事件函数即可。

 

原文链接:

[cpp] view plain copy

CTRL+Enter发送信息的实现

首先在chat类定义一个eventFilter,该函数是一个虚函数,可以由子类进行更改。所以声明eventFilter如下:

 

 

本文由金沙澳门官网网址发布于澳门金莎娱乐手机版,转载请注明出处:事件管理,Qt学习之路

关键词: