日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT中事件处理、事件过滤器、拖放事件分析

發布時間:2023/12/18 c/c++ 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QT中事件处理、事件过滤器、拖放事件分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Qt: 事件過濾器

obj->installEventFilter(filterObject);常常是obj->installEventFilter(this).

發送到obj的所有事件, 都會先發送到filterObject的eventFilter()方法, 即filterObject會過濾obj的事件, 這樣就不用為了實現一個事件而要去繼承, 再實現一個類, 完成如mouse event, key event等了, 只用在當前類中就可以通過事件過濾來完成.

bool QObject::eventFilter(QObject *watchedObject, QEvent *event) [virtual]

如果是安裝者的事件if (obj == watchedObject), 處理過此事件(event->type()), 返回true, 沒有處理就返回false.

如果不是安裝者的事件, 則把此事件拋給父類去處理:

if (obj == watchedObject) {

?? ? ? ? ?處理后返回true, 否則返回false.

} else {

?? ? ? ? ?return SuperClass::eventFilter(watchedObject, event);

}

Qt事件處理介紹

  • Qt平臺會將系統產生的消息轉換為Qt事件
  • Qt事件是一個QEvent的對象
  • Qt事件用來描述程序內部或外部發生的動作
  • 任意的QObject對象都具備事件處理的能力

如下圖所示,可以看到QEvent的子類非常之多:

?比如:

  • QInputEvent:用戶輸入事件
  • QDropEvent:用戶拖放事件
  • QPaintEvent:描述操作系統繪制GUI動作的事件
  • QCloseEvent:用戶關閉窗口事件
  • QTimerEvent:計時器事件

事件處理方式順序

1.Qt事件產生后立即被分發到QWidget對象

2.QWidget中的event(QEvent*)進行事件處理

3.event()根據事件類型調用不同的事件處理函數

4.在事件處理函數中發送Qt中預定義的信號

5.調用信號關聯的槽函數

以按鈕點擊為例:

1.當點擊按鈕后,將會觸發鼠標事件,調用event(QEvent*)成員函數

3.調用mouseReleaseEvent(QMouseEvent*)成員函數

4.調用click()成員函數

5.觸發信號SIGNAL(clicked());

同樣,當用戶點擊窗口的關閉按鈕時,也會觸發closeEvent()事件函數,該函數需要重寫,才能實現

參考示例:

void MainWindow::closeEvent(QCloseEvent *event) {if (maybeSave()) //如果還有需要保存的數據{writeSettings();event->accept();} else //取消關閉窗口{event->ignore();}}

類似的還有keyEvent()獲取鍵盤事件函數, keyReleaseEvent()鍵盤按下事件函數,enterEvent光標進入組件事件函數, leaveEvent光標離開組件事件函數等等。

其中QCloseEvent繼承與QEvent,在QEvent中常用成員函數有

void accept (); //接收者處理當前事件void ignore (); //接收者忽略當前事件,忽略后,事件可能傳遞給父組件bool isAccepted(); //判斷當前事件是否被處理過

當使用ignore()處理事件時,該事件可能會傳遞給其父組件對象繼續處理

步驟如下:

  • 寫兩個類:?QMyWidget、QMyLineEdit(QMyLineEdit是QMyWidget的類成員)
  • 通過QMyLineEdit來重寫LineEdit的keyReleaseEvent()鍵盤按下事件函數
  • 通過QMyWidget來重寫QWidget的keyReleaseEvent()鍵盤按下事件函數
  • 然后通過ignore()處理QMyLineEdit的keyReleaseEvent()事件函數
  • 判斷是否會繼續執行QMyWidget父組件的keyReleaseEvent()事件函數

QLineEdit.h如下所示:

#ifndef QMYLINEEDIT_H #define QMYLINEEDIT_H#include <QLineEdit> #include <QtGui>class QMyLineEdit : public QLineEdit {Q_OBJECTpublic:explicit QMyLineEdit(QWidget *parent = 0);void keyReleaseEvent( QKeyEvent * event ); };#endif // QMYLINEEDIT_H

QLineEdit.cpp如下所示:

#include "QMyLineEdit.h"QMyLineEdit::QMyLineEdit(QWidget *parent) :QLineEdit(parent) {}void QMyLineEdit::keyReleaseEvent( QKeyEvent * event ) {qDebug()<<"QMyLineEdit::keyReleaseEvent";qDebug()<<"key value:"<< event->key(); event->ignore(); //忽略當前事件 }

QMyWidget.h如下所示:

#ifndef QMYWIDGET_H #define QMYWIDGET_H#include "QMyLineEdit.h" #include <QWidget>class QMyWidget : public QWidget {Q_OBJECTQMyLineEdit line;public:explicit QMyWidget(QWidget *parent = 0);void keyReleaseEvent( QKeyEvent * event );};#endif // QMYWIDGET_H

QMyWidget.cpp如下所示:

#include "QMyWidget.h"QMyWidget::QMyWidget(QWidget *parent) :QWidget(parent),line(this) { }void QMyWidget::keyReleaseEvent( QKeyEvent * event ) {qDebug()<<"QMyWidget::keyReleaseEvent";qDebug()<<"key value:"<< event->key();QWidget::keyPressEvent(event); }

main()函數如下所示:

int main(int argc, char *argv[]) {QApplication a(argc, argv);QMyWidget w;w.show();return a.exec(); }

效果如下:

可以看到成員調用了event->ignore()函數忽略事件后,同樣也會繼續進入QMyWidget類處理事件?

Qt中的事件過濾器

  • 事件過濾器可以對需要的組件接收到的事件進行過濾,以及監控
  • 任意的QObject對象都可以作為事件過濾器使用
  • 事件過濾器的實現,需要重寫eventFilter()函數
  • 組件要想被監控,則需要通過installEventFilter()安裝事件過濾器
  • 事件過濾器能夠決定是否將事件轉發給組件對象,如下圖所示:

eventFilter函數體如下所示:

bool QObject::eventFilter ( QObject * watched, QEvent * event );// watched:代表被監控的組件 event:代表要轉發的事件//返回true,表示該事件也被過濾掉(處理),無需再轉發了//返回false,則正常轉發給watched

參考示例-實現文本框只允許輸入數字:

class MainWindow : public QMainWindow{public:MainWindow();protected:bool eventFilter(QObject *obj, QEvent *ev);private:QTextEdit *textEdit;};MainWindow::MainWindow(){textEdit = new QTextEdit;setCentralWidget(textEdit);textEdit->setAttribute(Qt::WA_InputMethodEnabled, false); //禁止中文輸入法textEdit->installEventFilter(this);}bool MainWindow::eventFilter(QObject *obj, QEvent *event){if (obj == textEdit){if (event->type() == QEvent::KeyPress){QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);qDebug() << "Ate key press" << keyEvent->key();switch(keyEvent->key()) //只接受0~9數字{case Qt::Key_0:case Qt::Key_1:case Qt::Key_2:case Qt::Key_3:case Qt::Key_4:case Qt::Key_5:case Qt::Key_6:case Qt::Key_7:case Qt::Key_8:case Qt::Key_9:return false;default:return true;}}else{return false;}}else{return QMainWindow::eventFilter(obj, event);}}

用戶拖放事件

每個QWidget對象都能處理拖放事件

常用的拖放事件相關函數有:

void dragEnterEvent ( QDragEnterEvent * event ); //拖事件處理函數 void dropEvent ( QDropEvent * event ) ; //放事件處理函數

拖放事件所處理的數據是QMimeData類

  • QMimeData類可以通過QDragEnterEvent?或者?QDropEvent?的成員函數QDropEvent()獲取
  • QMimeData支持多種不同類型的文件數據

MIME類型常用處理函數如下所示:

拖放事件的步驟如下:

1.在構造函數里通過setAcceptDrops(true)函數,讓該組件能接受拖放事件

2.重寫dragEnterEvent(QDragEnterEvent*?event)函數并判斷MIME類型

? 如果是期待的類型,則調用event?->acceptProposedAction();

? 否則調用 : event ->ignore();

3.重寫dropEvent()函數并判斷MIME類型

? 如果是期待的類型,則獲取MIME數據并處理.

? 否則調用 : event ->ignore();

示例:

頭文件:

#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTextEdit> #include <QDragEnterEvent> #include <QDropEvent> #include <QMimeData>class MainWindow : public QMainWindow{ private:QTextEdit *textEdit;void dragEnterEvent(QDragEnterEvent *event);void dropEvent(QDropEvent *event);public:MainWindow();}; #endif // MAINWINDOW_H

源文件:

#include "mainwindow.h"MainWindow::MainWindow() {textEdit = new QTextEdit;setCentralWidget(textEdit);textEdit->setAttribute(Qt::WA_InputMethodEnabled, false) ;textEdit->setAcceptDrops(false);setAcceptDrops(true); }void MainWindow::dragEnterEvent(QDragEnterEvent *event) {if(event->mimeData()->hasUrls()) //判斷拖的類型{event->acceptProposedAction();}else{event->ignore();} }void MainWindow::dropEvent(QDropEvent *event) {if(event->mimeData()->hasUrls()) //判斷放的類型{textEdit->clear();QList<QUrl> List = event->mimeData()->urls();for(int i=0;i<List.length();i++){textEdit->insertPlainText(List[i].toLocalFile()+"\n");}}else{event->ignore();} }

由于我們是在MainWindow上處理拖放事件,所以需要設置textEdit->setAcceptDrops()函數為 false,把MainWindow的setAcceptDrops()置為 true,這樣我們就能夠讓MainWindow截獲拖放事件,而不是交給QTextEdit處理。

效果:

總結

以上是生活随笔為你收集整理的QT中事件处理、事件过滤器、拖放事件分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。