1、介紹
Halcon中的執行繪圖算子draw_circlr或draw_rectangle1等算子在繪制圖形時,單擊鼠標左鍵進行繪圖,點擊右鍵確認圖形,點擊右鍵之前就進行等待動作,但是在MFC/Qt等開發環境下,無法通過操作退出Halcon的進程。如果想在繪圖的中途取消,目前沒有比較直接的方法。
Halcon介紹文檔里只是提到通過鼠標右鍵結束繪圖動作,在MacOS上可以使用escape鍵進行退出。
2、方法分析
由Halcon的幫助文檔可知,點擊鼠標右鍵才能結束繪圖動作,那我們可以結合Qt的鍵盤事件,Esc觸發后模擬右鍵后再將繪圖的操作和顯示恢復到繪圖前狀態,這樣就大概能實現取消繪圖的效果。
其中鍵盤事件可以這樣來定義:
//聲明鍵盤事件
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
然后在鍵盤事件實現中對鍵盤輸入進行判斷:
if(event->key() == Qt::Key_Escape)
{
if(isQuitDraw == 0){
isQuitDraw = 1;
//獲取控件的鼠標位置
int btnPosX = ui->PicShow->mapToGlobal(QPoint(0, 0)).x();
int btnPosY = ui->PicShow->mapToGlobal(QPoint(0, 0)).y();
qDebug()<<"控件坐標"<<btnPosX<<btnPosY;
//將鼠標移動到指定位置
SetCursorPos(btnPosX+100,btnPosY+100);
//模擬鼠標的按下和放松動作
mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
Sleep(2);
mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
//刷新圖像窗口,恢復繪圖變量
UpdateWindowImg();
ui->PicShow->m_IsDraw = false;
SetMaskWidget(maskSignal);
}
}
else if(event->key() == Qt::Key_Space)
{
qDebug()<<"按下空格"<<endl;
return;
}
else QWidget::keyPressEvent(event);
這里碰到兩個問題點:
1.在繪圖動作外按下Esc鍵觸發鍵盤事件
因為繪圖動作取消會有界面的重置等一系列動作,所以在不繪圖時如果點擊了Esc按鍵可能會出現無操作,這里設定了一個isQuitDraw 的bool判斷量,在每次繪圖前開啟,這樣就可以保證只能在繪圖的時候點擊Esc按鍵才能觸發取消繪圖動作的代碼。
2.系統自帶的鍵盤事件會干擾到鍵盤事件的執行
在不設定鍵盤事件時,系統有默認的鍵盤事件,比如Esc是返回,Enter是確認,Tab是下一個等等,因為系統設定的是默認過濾事件event過濾事件進行分發,所以我們在設定了鍵盤事件后,系統的event依然會有對應響應動作,這里有兩種解決方法,一種是重寫事件過濾器 bool eventFilter(QObject* obj, QEvent* e),然后給圖像顯示的控件安裝事件過濾器。另一種方法就是重寫reject。
重寫事件過濾器
#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;
}
};
完成對事件過濾器的重寫后,需要在需要攔截的頁面進行安裝,如果是在子頁面(子進程)中進行安裝,那么它只在當前頁面生效,并不會影響到別的頁面,如果想在全局使用,那么就需要在第一個基頁面中安裝。安裝是調用QObject類中的一個方法。
全局過濾這個鍵盤事件:
QApplication a(argc, argv);
a.installEventFilter(new MyEventFilter);
全局過濾后點擊Space鍵就不會有其他動作,也不會進入重寫的鍵盤事件中,實現了屏蔽鍵盤按鍵的功能。