2011-10-13 73 views
3

我有一個QWidget,當調整大小事件結束時,我需要執行一些操作(刷新小部件中的圖片)。我怎樣才能抓住這個動作? 我需要趕上當用戶通過釋放鼠標按鈕結束他所有的調整大小操作。在我的應用程序中調整每個像素的圖像刷新大小並不是一個好習慣。它應該只在鼠標釋放並調整行爲結束時纔會調用。Qt用戶調整大小事件結束(停止)

我只是試圖重新實現QMouseReleaseEvent來捕捉它,但它不起作用,當用戶按下小部件的邊框來調整它的大小。這意味着在我們的情況下不起作用。

然後我試圖創建我自己的QSizeGrip並將其插入到我的小部件的底部,但重新實現的事件QMouseReleaseEvent再次無法使用它。事件沒有產生任何時間用戶釋放鼠標。我不知道爲什麼。

有人可以幫我解決這個問題嗎?

在此先感謝。

回答

1

窗口裝飾上的鼠標事件由底層窗口系統管理,這就是爲什麼當你嘗試時你無法捕捉它們。 我有同樣的問題一次,我選擇的解決方案是(重新)啓動每個resize事件單射QTimer,並且只有在計時器間隔過去後處理更新。不是很性感,但我沒有找到任何其他的解決方法..

1

另一種方法是爲應用程序安裝事件過濾器,並獲取應用程序的所有事件,陷阱鼠標按下和鼠標釋放,並不更新窗口在之間。

「在QCoreApplication :: instance()上安裝一個事件過濾器,這樣的事件過濾器能夠處理所有小部件的所有事件,所以它和重新實現notify()一樣強大;而且,有可能超過一個應用程序全局事件過濾器全局事件過濾器甚至可以查看禁用的小部件的鼠標事件請注意,應用程序事件過濾器僅針對居住在主線程中的對象調用。

3

我已經做了這種方式:

  1. 從QWidget的繼承我的類
  2. 定義私有變量int的timerId = 0
  3. 超載的QWidget :: resizeEvent和的QObject :: timerEvent

void MapLoader::resizeEvent(QResizeEvent *){ 
    if (timerId){ 
     killTimer(timerId); 
     timerId = 0; 
    } 
    timerId = startTimer(5000/*delay beetween ends of resize and your action*/); 
} 

void MapLoader::timerEvent(QTimerEvent *te){ 
    /*your actions here*/ 
    killTimer(te->timerId()); 
    timerId = 0; 
} 
3

超時方法是一個體面的想法,但如果用戶調整大小,然後暫停超過定時器的時間間隔,那麼最終不會得到真正的「用戶完成調整窗口大小」事件。設置較長的時間間隔使得這種情況變得不太可能,但是通過這樣做,最終在用戶完成調整大小和調用函數的時間之間有很長的延遲。在我尋找解決方案時,我發現不少人使用定時器方法解決問題,所以顯然它對於某些用例足夠可靠,但我認爲這有點不方便。

我喜歡mhstnsc的想法,所以在實現它之後,我決定在這裏添加一些代碼,這些代碼可能對試圖做類似事情的人有用。 通過製作m_bUserIsMoving標誌並覆蓋「void MainWindow :: moveEvent(QMoveEvent * pEvent)」,您可以輕鬆地調整它以捕捉「用戶完成移動窗口」事件。當用戶完成調整大小或移動窗口時,我使用它來保存配置文件,以便即使應用程序以不潔的方式死亡,也會始終保存最後一個位置。

// constructor 
MainWindow::MainWindow(QWidget* pParent, Qt::WindowFlags flags) : QMainWindow(pParent, flags) 
{ 
    m_bUserIsResizing = false; 
    qApp->installEventFilter(this); 
} 

// this will be called when any event in the application occurs 
bool MainWindow::eventFilter(QObject* pObj, QEvent* pEvent) 
{ 
    // We need to check for both types of mouse release, because it can vary on which type happens when resizing. 
    if ((pEvent->type() == QEvent::MouseButtonRelease) || (pEvent->type() == QEvent::NonClientAreaMouseButtonRelease)) { 
     QMouseEvent* pMouseEvent = dynamic_cast<QMouseEvent*>(pEvent); 
     if ((pMouseEvent->button() == Qt::MouseButton::LeftButton) && m_bUserIsResizing) { 
      printf("Gotcha!\n"); 
      m_bUserIsResizing = false; // reset user resizing flag 
     } 
    } 
    return QObject::eventFilter(pObj, pEvent); // pass it on without eating it 
} 

// override from QWidget that triggers whenever the user resizes the window 
void MainWindow::resizeEvent(QResizeEvent* pEvent) { m_bUserIsResizing = true; } 

它比計時器稍微複雜一點,但更健壯。