1、介紹
Halcon中的執(zhí)行繪圖算子draw_circlr或draw_rectangle1等算子在繪制圖形時(shí)营密,單擊鼠標(biāo)左鍵進(jìn)行繪圖划址,點(diǎn)擊右鍵確認(rèn)圖形劲妙,點(diǎn)擊右鍵之前就進(jìn)行等待動(dòng)作呢岗,但是在MFC/Qt等開(kāi)發(fā)環(huán)境下冕香,無(wú)法通過(guò)操作退出Halcon的進(jìn)程。如果想在繪圖的中途取消后豫,目前沒(méi)有比較直接的方法悉尾。
Halcon介紹文檔里只是提到通過(guò)鼠標(biāo)右鍵結(jié)束繪圖動(dòng)作,在MacOS上可以使用escape鍵進(jìn)行退出挫酿。
2构眯、方法分析
由Halcon的幫助文檔可知,點(diǎn)擊鼠標(biāo)右鍵才能結(jié)束繪圖動(dòng)作早龟,那我們可以結(jié)合Qt的鍵盤(pán)事件鸵赖,Esc觸發(fā)后模擬右鍵后再將繪圖的操作和顯示恢復(fù)到繪圖前狀態(tài),這樣就大概能實(shí)現(xiàn)取消繪圖的效果拄衰。
其中鍵盤(pán)事件可以這樣來(lái)定義:
//聲明鍵盤(pán)事件
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
然后在鍵盤(pán)事件實(shí)現(xiàn)中對(duì)鍵盤(pán)輸入進(jìn)行判斷:
if(event->key() == Qt::Key_Escape)
{
if(isQuitDraw == 0){
isQuitDraw = 1;
//獲取控件的鼠標(biāo)位置
int btnPosX = ui->PicShow->mapToGlobal(QPoint(0, 0)).x();
int btnPosY = ui->PicShow->mapToGlobal(QPoint(0, 0)).y();
qDebug()<<"控件坐標(biāo)"<<btnPosX<<btnPosY;
//將鼠標(biāo)移動(dòng)到指定位置
SetCursorPos(btnPosX+100,btnPosY+100);
//模擬鼠標(biāo)的按下和放松動(dòng)作
mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
Sleep(2);
mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
//刷新圖像窗口,恢復(fù)繪圖變量
UpdateWindowImg();
ui->PicShow->m_IsDraw = false;
SetMaskWidget(maskSignal);
}
}
else if(event->key() == Qt::Key_Space)
{
qDebug()<<"按下空格"<<endl;
return;
}
else QWidget::keyPressEvent(event);
這里碰到兩個(gè)問(wèn)題點(diǎn):
1.在繪圖動(dòng)作外按下Esc鍵觸發(fā)鍵盤(pán)事件
因?yàn)槔L圖動(dòng)作取消會(huì)有界面的重置等一系列動(dòng)作饵骨,所以在不繪圖時(shí)如果點(diǎn)擊了Esc按鍵可能會(huì)出現(xiàn)無(wú)操作翘悉,這里設(shè)定了一個(gè)isQuitDraw 的bool判斷量,在每次繪圖前開(kāi)啟居触,這樣就可以保證只能在繪圖的時(shí)候點(diǎn)擊Esc按鍵才能觸發(fā)取消繪圖動(dòng)作的代碼妖混。
2.系統(tǒng)自帶的鍵盤(pán)事件會(huì)干擾到鍵盤(pán)事件的執(zhí)行
在不設(shè)定鍵盤(pán)事件時(shí),系統(tǒng)有默認(rèn)的鍵盤(pán)事件轮洋,比如Esc是返回制市,Enter是確認(rèn),Tab是下一個(gè)等等弊予,因?yàn)橄到y(tǒng)設(shè)定的是默認(rèn)過(guò)濾事件event過(guò)濾事件進(jìn)行分發(fā)祥楣,所以我們?cè)谠O(shè)定了鍵盤(pán)事件后,系統(tǒng)的event依然會(huì)有對(duì)應(yīng)響應(yīng)動(dòng)作,這里有兩種解決方法误褪,一種是重寫(xiě)事件過(guò)濾器 bool eventFilter(QObject* obj, QEvent* e)责鳍,然后給圖像顯示的控件安裝事件過(guò)濾器。另一種方法就是重寫(xiě)reject兽间。
重寫(xiě)事件過(guò)濾器
#include <QKeyEvent>
class MyEventFilter : public QObject {
public:
bool eventFilter( QObject *obj, QEvent *event ) override {
if ( event->type() == QEvent::KeyPress ||
event->type() == QEvent::KeyRelease ) {
if ( ( (QKeyEvent *) event )->key() == Qt::Key_Space ) {
qDebug("Space press!");
return true;
}
}
return false;
}
};
完成對(duì)事件過(guò)濾器的重寫(xiě)后历葛,需要在需要攔截的頁(yè)面進(jìn)行安裝,如果是在子頁(yè)面(子進(jìn)程)中進(jìn)行安裝嘀略,那么它只在當(dāng)前頁(yè)面生效恤溶,并不會(huì)影響到別的頁(yè)面,如果想在全局使用帜羊,那么就需要在第一個(gè)基頁(yè)面中安裝咒程。安裝是調(diào)用QObject類(lèi)中的一個(gè)方法。
全局過(guò)濾這個(gè)鍵盤(pán)事件:
QApplication a(argc, argv);
a.installEventFilter(new MyEventFilter);
全局過(guò)濾后點(diǎn)擊Space鍵就不會(huì)有其他動(dòng)作逮壁,也不會(huì)進(jìn)入重寫(xiě)的鍵盤(pán)事件中孵坚,實(shí)現(xiàn)了屏蔽鍵盤(pán)按鍵的功能。