導航:首頁 > 凈水問答 > qt事件過濾qapplication

qt事件過濾qapplication

發布時間:2022-05-30 15:01:25

A. QT的事件和信號的區別

signal由具體對象發出,然後會馬上交給由connect函數連接的slot進行處理;而對於事件,Qt使用一個事件隊列對所有發出的事件進行維護,當新的事件產生時,會被追加到事件隊列的尾部,前一個事件完成後,取出後面的事件進行處理。但是,必要的時候,Qt的事件也是可以不進入事件隊列,而是直接處理的。並且,事件還可以使用「事件過濾器」進行過濾。總的來說,如果我們使用組件,我們關心的是信號槽;如果我們自定義組件,我們關心的是事件。因為我們可以通過事件來改變組件的默認操作。比如,如果我們要自定義一個QPushButton,那麼我們就需要重寫它的滑鼠點擊事件和鍵盤處理事件,並且在恰當的時候發出clicked()信號。
還記得我們在main函數裡面創建了一個QApplication對象,然後調用了它的exec()函數嗎?其實,這個函數就是開始Qt的事件循環。在執行exec()函數之後,程序將進入事件循環來監聽應用程序的事件。當事件發生時,Qt將創建一個事件對象。Qt的所有事件都繼承於 QEvent類。在事件對象創建完畢後,Qt將這個事件對象傳遞給QObject的event()函數。event()函數並不直接處理事件,而是按照事件對象的類型分派給特定的事件處理函數(event handler)。
在所有組件的父類QWidget中,定義了很多事件處理函數,如keyPressEvent()、
keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent ()、mousePressEvent()、mouseReleaseEvent()等。這些函數都是protected virtual的,也就是說,我們應該在子類中重定義這些函數。

B. postevent能發送qt自身定義的事件嗎

看看Qt發明人怎麼定義的QEvent,看看他們怎麼用自己定義的QEvent,不就回答了文章開頭的倆問題了嘛!O(∩_∩)O~
我把整個過程總結為「長官定義事件」----->「信使傳遞事件」---->「軍隊接收並響應事件」。
我通過Qt Assistant查找那些與事件相關的類,總結如下:

1、Qt中定義事件的長官:QEvent

QEvent的任務就是定義一些事件類型Type,它們都定義在了一個enum里。這就是教程中告訴我們的要子類化QEvent,派生出MyEvent,然後在MyEvent中定義事件類型QEvent::Type。
我們子類化的時候模仿一個QEvent就好了,而且是繼承,好些都不用子類做了,看一下QEvent類中的成員變數和成員函數,就這些東西:

好了,我們通過子類化QEvent,把派生出來的MyEvent看做長官,它定義了具體某個事件。下面看誰是信使。

2、Qt中傳遞事件的信使:QCoreApplication(QApplication繼承自QCoreApplication)
我們看看QCoreApplication中定義的一些函數,這些函數就是我們經常遇到的那些與傳遞事件和過濾事件有關的函數,見下圖:
Public Functions:

Static Public Members:

所以,到這里我們就可以明確了,你要用QCoreApplication的static public類型的函數入sendEvent或postEvent函數來傳遞送信,要注意:當使用sendEvent時,你的事件要在棧上建立,sendEvent會直接調用notify把事件傳遞給士兵,不走事件隊列;而用postEvent時,你的事件要在堆上建立,即要用new來創建,postEvent會把你的事件追加進事件隊列(詳細過程請看http://blog.csdn.net/michealtx/article/details/6865891)。你還可以通過重載notify來影響送信過程。
3、Qt中接收響應事件的軍隊:QWidget(這是Qt中的widget之母,諸如QMainWindow、QPushBUtton等等都是繼承自QWidget)
我們看看QWidget中與事件有關的成員:

看到了嗎?這些就是event handler,即事件處理函數,這是幹活的那幫人。裡面有我們熟悉的mousePressEvent()、keyPressEvent()等常用的事件處理函數,它們都是protected virtual 類型的,可以重載。所以呀,我們可以子類化QWidget,從而繼承得到好些個event handler,當然也可以自己定義event handler!相當於自己創造士兵來響應事件。通過山寨QWidget,就可以創造自己的軍隊!
還有一點就是,當事件到達軍隊的時候,要先審查再分發,審查就是要經過事件過濾,分發就是通過對經過審查的事件進行判斷再把它分給那個相應的士兵這就又涉及到一個類QObject,這是Qt的萬類之母,這個類中有兩個函數一個是eventFilter(),另一個是event()。要先子類化QObject來創建一個監控者,這個監控者重載eventFilter(),來為軍隊過濾事件。然後還要在軍隊(QWidget)通過調用installEventFilter ( QObject * filterObj )來安裝過濾器,參數中的filterOb即為監控者。最後在軍隊(QWidget)中重載event()來分發事件,把事件分給對應會干這個活的士兵(event handler)。

好了,我理解的大體過程就是這樣,我是Qt新手,可能有錯的地方,希望路過的大牛能給與指正,我將不勝感激!

什麼話也不如來個常式給力!:
我建立的是Qt Console Application,工程叫MyEvent,下面是main.cpp中的代碼:

[cpp] view plain

[cpp] view plain
#include <QtGui/QApplication>
#include <QCoreApplication>
#include <QEvent>
#include <QObject>
#include <QDebug>

static const QEvent::Type MyEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User+100);

//長官
class MyEvent: public QEvent
{
public:
MyEvent(Type MyEventType):QEvent(MyEventType){}
};

//信使
class MySender: public QCoreApplication
{
public:
MySender(int argc,char *argv[]):QCoreApplication(argc,argv){}

public:
bool notify(QObject *receiver, QEvent *event);

};

bool MySender::notify(QObject *receiver, QEvent *event)
{
if(event->type() == MyEventType)
{
qDebug()<<"MyEventType is coming!";
//return true;
/*這里不能return true,因為重寫notify就是在事件被向下傳遞之前截住它,
隨便搞它,搞完了還得給QCoreApplication::notify向下傳遞,除非在mySender.notify
實現了事件向下傳遞的那一套。直接返回的話myArmy就收不到這個事件,因為執行完這個
mySender.notify的return true後,事件傳遞被人為的在半截終止了
(見Qt事件處理的五個層次http://blog.csdn.net/michealtx/article/details/6865891 )
,下面的myArmy的安裝的過濾器和它自己的event都不會收到這個事件,更甭提最後幹活
的myEventHandler了。所以在主函數中執行完mySender.sendEvent把myEvent
交給mySender.notify這個敗家子兒後,就執行mySender.exec進入其它事件的循環了。這就是
問題http://topic.csdn.net/u/20111012/19/78036d16-c163-40f9-a05c-3b7d6f4e9043.html
出現的原因。感謝1+1=2大牛!非常感謝!
*/
}
return QCoreApplication::notify(receiver,event);
}

//軍隊
class MyArmy: public QObject
{
public:
void MyEventHandler(QEvent *event);
bool event(QEvent *event);
};

void MyArmy::MyEventHandler(QEvent *event)
{
qDebug()<<"The event is being handled!";
event->accept();
}

bool MyArmy::event(QEvent *event)
{
if(event->type() == MyEventType)
{
qDebug()<<"event() is dispathing MyEvent";
MyEventHandler(event);//調用事件處理函數
if((MyEvent*)event->isAccepted())
{
qDebug()<<"The event has been handled!";
return true;
}
}
return QObject::event(event);
}

//監控者
class MyWatcher: public QObject
{
public:
bool eventFilter(QObject *watched, QEvent *event);
};

C. Qt怎樣使用事件過濾器

設置事件過濾器時用設置其viewport的事件過濾實例:#include #include QTextEdit* pEdit = new QTextEdit(this);pEdit->viewport()->installEventFilter(this);bool xxx::eventFilter(QObject* o, QEvent* e){ Q_UNUSED(o); if(e->type() == QEvent::MouseButtonPress){ QMouseEvent* pMe = static_cast(e); qDebug() pos(); } return false;}

D. Qt如何捕獲鍵盤事件

您好,Qt鍵盤事件屬於Qt事件系統,所以事件系統中所有規則對按鍵事件都有效。下面關注點在按鍵特有的部分:
focus

一個擁有焦點(focus)的QWidget才可以接受鍵盤事件。有輸入焦點的窗口是活動窗口或活動窗口子窗口或子子窗口等。

焦點移動的方式有以下幾種:

按下Tab或Shift+Tab

注意:文本編譯器(一般需要插入Tab),或者WebView(需要Tab來移動超鏈接焦點) 等
Qt中,需要輸入Tab的地方可以用 Ctrl+Tab 或 Ctrl+Shift+Tab 替代。
點擊一個QWidget
建議:只對接受文本輸入的Widget啟用該功能
按下鍵盤的快捷鍵
QLabel::setBuddy(), QGroupBox,以及 QTabBar 支持
使用滑鼠滾輪
用戶移動焦點
程序將決定被設置focus的Widget的哪一個子Widget獲得焦點

注意:如果一個 Widget 已經 grabKeyboard,所有鍵盤事件將發送到該Widget而不是獲得焦點的Widget
focusPolicy

一個QWidget獲得焦點的方式受 focusPolicy 控制

Qt::TabFocus
通過Tab鍵獲得焦點
Qt::ClickFocus
通過被單擊獲得焦點
Qt::StrongFocus
可通過上面兩種方式獲得焦點
Qt::NoFocus
不能通過上兩種方式獲得焦點(默認值),setFocus仍可使其獲得焦點

keypress和keyrelease

首先,我們要是Widget獲得焦點,一般設置focusPolicy。

然後要對按鍵進行響應,我們只需要直接重載:

keyPressEvent
keyReleaseEvent

注意:

對我們不處理的事件,要調用父類的相應事件處理函數。
如果widget當前沒有焦點,考慮到事件轉發:如果其子widget有焦點,那麼該widget未處理的鍵盤事件將被轉發過來。
有時輸入焦點不在任何窗口中。這種情況發生在所有程序都是最小化的時候。這時,Windows將繼續向活動窗口發送鍵盤消息,但是這些消息與發送給非最小化的活動窗口的鍵盤消息有不同的形式。

QKeyEvent

在windows下,與鍵盤事件有關的有8個消息:

對產生可顯示字元的按鍵組合,Windows不僅給程序發送按鍵消息,而且還發送字元消息
有些鍵不產生字元,這些鍵包括shift鍵、功能鍵、游標移動鍵和特殊字元鍵如Insert和Delete。對於這些鍵,Windows只產生按鍵消息。

這些消息在Qt中只體現在QKeyEvent中。

對字元,可通過 QKeyEvent::text() 獲得
其他鍵,QKeyEvent::key() 獲得一個鍵值

event函數

由於 Tab 鍵被用來切換焦點,這使得它與眾不同。

這是qwidget.cpp的event函數中的代碼片段:

case QEvent::KeyPress:
{
QKeyEvent *k = (QKeyEvent *)event;
bool res = false;
if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier)))
{ //### Add MetaModifier?
if (k->key() == Qt::Key_Backtab || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
res = focusNextPrevChild(false);
else if (k->key() == Qt::Key_Tab)
res = focusNextPrevChild(true);
if (res)
break;
}
keyPressEvent(k);
}

如果我們需要處理Tab鍵,需要重載 event 函數。

E. qt編程時提示:variable 'QApplication app 'has initializer but incomplate type

字面的意思是 main函數里免得QApplication類雖然聲明了,但是不完整。
看一下你main函數裡面QApplication的對象,在QT中main函數的第一句就要是'QApplication app ;而最後一句必須是 return app.exec;

F. qt4 tableWidget 怎麼給每個單元格加上時間過濾器installEventFilter分數沒用我送幾個Q幣好了

Qt的事件模型一個強大的功能是一個QObject對象能夠監視發送其他QObject對象的事件,在事件到達之前對其進行處理。
假設我們有一個CustomerInfoDialog控制項,由一些QLineEdit控制項組成。我們希望使用Space鍵得到下一個QLineEdit的輸入焦點。一個最直接的方法是繼承QLineEdit重寫keyPressEvent()函數,當點擊了Space鍵時,調用focusNextChild():
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Space) {
focusNextChild();
} else {
QLineEdit::keyPressEvent(event);
}
}
這個方法有一個最大的缺點:如果我們在窗體中使用了很多不同類型的控制項(QComboBox,QSpinBox等等),我們也要繼承這些控制項,重寫它們的keyPressEvent()。一個更好的解決方法是讓CustomerInfoDialog監視其子控制項的鍵盤事件,在監視代碼處實現以上功能。這就是事件過濾的方法。實現一個事件過濾包括兩個步驟:
1. 在目標對象上調用installEventFilter(),注冊監視對象。
2. 在監視對象的eventFilter()函數中處理目標對象的事件。
注冊監視對象的位置是在CustomerInfoDialog的構造函數中:
CustomerInfoDialog::CustomerInfoDialog(QWidget *parent)
: QDialog(parent)
{
...
firstNameEdit->installEventFilter(this);
lastNameEdit->installEventFilter(this);
cityEdit->installEventFilter(this);
phoneNumberEdit->installEventFilter(this);
}
事件過濾器注冊後,發送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit控制項的事件首先到達CustomerInfoDialog::eventFilter()函數,然後在到達最終的目的地。
下面是eventFilter()函數的代碼:
bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event)
{
if (target == firstNameEdit || target == lastNameEdit
|| target == cityEdit || target == phoneNumberEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast(event);
if (keyEvent->key() == Qt::Key_Space) {
focusNextChild();
return true;
}
}
}
return QDialog::eventFilter(target, event);
}
首先,我們看是目標控制項是否為QLineEdit,如果事件為鍵盤事件,把QEvent轉換為QKeyEvent,確定被敲擊的鍵。如果為Space鍵,調用focusNextChild(),把焦點交給下一個控制項,返回true通知Qt已經處理了這個事件,如果返回false,Qt將會把事件傳遞給目標控制項,把一個空格字元插入到QLineEdit中。
如果目標控制項不是QLineEdit,或者事件不是Space敲擊事件,把控制權交給基類QDialog的eventFilter()。目標控制項也可以是基類QDialog正在監視的控制項。(在Qt4.1中,QDialog沒有監視的控制項,但是Qt的其他控制項類,如QScrollArea,監視一些它們的子控制項)

Qt的事件處理有5中級別:
1. 重寫控制項的事件處理函數:如重寫keyPressEvent(),mousePressEvent()和paintEvent(),這是最常用的事件處理方法,我們已經看到過很多這樣的例子了。
2. 重寫QObject::event(),在事件到達事件處理函數時處理它。在需要改變Tab鍵的慣用法時這樣做。也可以處理那些沒有特定事件處理函數的比較少見的事件類型(例如,QEvent::HoverEnter)。我們重寫event()時,必須要調用基類的event(),由基類處理我們不需要處理的那些情況。
3. 給QObject對象安裝事件過濾器:對象用installEventFilter()後,所有達到目標控制項的事件都首先到達監視對象的eventFilter()函數。如果一個對象有多個事件過濾器,過濾器按順序激活,先到達最近安裝的監視對象,最後到達最先安裝的監視對象。
4. 給QApplication安裝事件過濾器,如果qApp(唯一的QApplication對象)安裝了事件過濾器,程序中所有對象的事件都要送到eventFilter()函數中。這個方法在調試的時候非常有用,在處理非活動狀態控制項的滑鼠事件時這個方法也很常用。
5. 繼承QApplication,重寫notify()。Qt調用QApplication::nofity()來發送事件。重寫這個函數是在其他事件過濾器處理事件前得到所有事件的唯一方法。通常事件過濾器是最有用的,因為在同一時間,可以有任意數量的事件過濾器,但是notify()函數只有一個。
許多事件類型,包括滑鼠,鍵盤事件,是能夠傳播的。如果事件在到達目標對象的途中或者由目標對象處理掉,事件處理的過程會重新開始,不同的是這時的目標對象是原目標對象的父控制項。這樣從父控制項再到父控制項,知道有控制項處理這個事件或者到達了最頂級的那個控制項。
圖7.2顯示了一個鍵盤事件在一個對話框中從子控制項到父控制項的傳播過程。當用戶敲擊一個鍵盤,時間首先發送到有焦點的控制項上(這個例子中是QCheckBox)。如果QCheckBox沒有處理這個事件,Qt把事件發送到QGroupBox中,如果仍然沒有處理,則最後發送到QDialog中。

G. C++的Qt項目,QApplication a(argc,argv);這行語句啥意思如下

Argc和argv是從命令行傳入的參數。

例如,如果輸入命令CP文件,C在Linux中,argc=3 argv是上述行中的字元串數組。

a.Exec()是程序進程的開始,命令:CP file。C file1。參數argc=3表示有三個命令。字元串數組指針argv指向整個命令「CP file」.C file1.C」。

QApplication只能通過輸入命令激活和使用。也可以單擊該命令或進行其他操作。

(7)qt事件過濾qapplication擴展閱讀:

Qt的優勢

1、良的跨平台特性:

Qt支持下列操作系統: Microsoft Windows 95/98, Microsoft Windows NT, Linux, Solaris, SunOS, HP-UX, Digital UNIX (OSF/1, Tru64), Irix, FreeBSD, BSD/OS, SCO, AIX, OS390,QNX 等等。

2、面向對象

Qt 的良好封裝機制使得 Qt 的模塊化程度非常高,可重用性較好,對於用戶開發來說是非常 方便的。 Qt 提供了一種稱為 signals/slots 的安全類型來替代 callback,這使得各個元件 之間的協同工作變得十分簡單。

3、豐富的 API

Qt 包括多達 250 個以上的 C++ 類,還提供基於模板的 collections, serialization, file, I/O device, directory management, date/time 類。甚至還包括正則表達式的處理功能。

H. qt事件過濾器中為什麼同一個鍵盤事件連續觸發多次

添加個標記int flag = 0。每次接收到事件時判斷是否falg == 1,如果是就不做任何處理直接返回,否則將flag設為1並進行處理。在接收到按鍵彈起消息時再將falg重置為0.

閱讀全文

與qt事件過濾qapplication相關的資料

熱點內容
加蒸餾水還要放電嗎 瀏覽:745
水處理作業類別准操項目 瀏覽:92
污水處理cod氧化劑 瀏覽:850
手機指環能裝在樹脂殼上嗎 瀏覽:445
水垢清潔劑 瀏覽:931
污水管屬於什麼級別 瀏覽:798
污水處理廠用的什麼化學葯品有毒 瀏覽:881
美的空氣凈化器上面數字代表什麼 瀏覽:35
飯店油煙凈化器壞了怎麼辦 瀏覽:552
日本為什麼會排核污水 瀏覽:155
連暖通和凈水器哪個好 瀏覽:477
水垢用食醋還是食鹽 瀏覽:769
超濾膜包A流道 瀏覽:163
k3空氣濾芯在什麼位置 瀏覽:625
大同樹脂瓦批發 瀏覽:109
鹽酸離子交換樹脂原理 瀏覽:655
凈水器磁化水的原理為什麼沒磁鐵 瀏覽:352
外地突發疾病回當地醫保怎麼用 瀏覽:868
污水處理站鹽酸和無機鹽的作用 瀏覽:695
大眾朗逸空氣濾芯怎麼樣 瀏覽:102