2011-03-24 46 views
5

經過多個月的嘗試,搜索,審查代碼等等,我無法找到一個解決方案來正確定位QT中的新窗口。在我最基本的情況下,我只想獲得最終的窗口大小,並將其置於鼠標下方。它將被移動以確保窗口的任何部分都不在屏幕之外。我不希望窗口出現,然後移動到位置,這會產生視覺震動,特別是打開桌面FX時。Qt在屏幕上正確放置新窗口,重點放在鼠標上,移動到屏幕

我遇到的,並不是所有的問題都妥善解決:

  1. frameGeometry並不總是填充窗口之前已經上映之前。

  2. frameGeometry有時只是完全錯誤的,特別是在Windows 7

  3. ,以顯示它是不可能知道sizeHint或大小是否將被應用,或者兩者之間的其他東西之前。也就是說,尺寸政策並不可預測。

請注意,我知道如何保存/恢復先前創建的窗口的幾何圖形。儘管QT缺陷,我也有一個工作解決方案。

另請注意,我無法使用窗口管理器的默認位置。對於多顯示器設置中的非MDI應用程序,它們的位置非常糟糕(通常甚至不在與鼠標相同的顯示器上)。

我也想避免將所有小部件和對話框分類來實現解決方案,因爲它不是通用的。如果這是唯一可能的方式,那麼我願意考慮它(如果事件過濾器也不是一種選擇)。

有沒有人有可行的解決方案?

+0

看到我最新的編輯。第一次編輯是不安全的。 – TonyK 2011-03-25 07:35:43

回答

6

編輯看起來更科學:我已經改變通話的任意數量 processEvents一個循環,檢查返回值。

再次編輯:看來新版本並不安全:它可能卡在循環中。所以我已經在迭代次數上設置了限制。

原創:
請告訴我這件事。如果我可以被允許從我自己的代碼來引用:

// BIG PAIN: We want to get the dialog box to caluclate its own size. But there is 
// no simple way to do this. The following seems to work, but only if processEvents 
// is called at least twice. God knows why: 
setAttribute (Qt::WA_DontShowOnScreen, true) ; // Prevent screen flicker 
show() ; 

QEventLoop EventLoop (this) ; 
for (int i = 0 ; i < 10 ; i++) 
    if (!EventLoop.processEvents()) break ; 

hide() ; 
setAttribute (Qt::WA_DontShowOnScreen, false) ; 

int x = 99 ; // whatever 
int y = 99 ; // whatever 

// Make sure it fits on the screen 
QRect ScreenRect = qApp -> desktop() -> availableGeometry (ApplicationData -> mainWindow) ; 

if (x + frameGeometry().width() > ScreenRect.right()) 
    x = ScreenRect.right() - frameGeometry().width() ; 
if (x < ScreenRect.x()) x = ScreenRect.x() ; 

if (y + frameGeometry().height() > ScreenRect.bottom()) 
    y = ScreenRect.bottom() - frameGeometry().height() ; 
if (y < ScreenRect.y()) y = ScreenRect.y() ; 

move (x, y) ; 

試試這個,有不同的呼叫號碼processEvents。 (在這些調用中,各種子小部件和子子小部件本身遞歸地大小。)

+0

謝謝,我之前沒有真正注意到「DontShowOnScreen」屬性。從我看過的代碼和Qt缺陷報告中,我知道爲什麼必須調用processEvents:有一個懶惰的大小評估,生成大小的代碼僅在響應某些事件(如show和resize)時被調用。我查看了代碼,儘管調整函數確實存在,但沒有*可能性直接調用它們。 – 2011-03-24 11:18:34

+0

所以試試這個。 – TonyK 2011-03-24 12:41:44

+0

是的,我肯定會實現並嘗試第一點:定位代碼的其餘部分與我現在的大致相同。 – 2011-03-24 13:00:24

-1

您是否嘗試過激活佈局。它迫使它來計算尺寸和這個電話後定位

QLayout ::激活()

,你的部件應該有自己正確的尺寸。

+2

我有,它沒有幫助。 – 2011-08-27 07:30:28

1

關於在顯示窗口之前無法查詢窗口大小的問題,有一個簡單的解決方法。在顯示之前,您可以將窗口移動到屏幕之外的某個位置。例如居中主屏幕上的主窗口無閃爍我做到以下幾點:

MainWindow mainWindow; 
QRect primaryScreenGeometry(QApplication::desktop()->screenGeometry()); 
mainWindow.move(-50000,-50000); 
mainWindow.show(); 
mainWindow.move((primaryScreenGeometry.width() - mainWindow.width())/2.0, 
       (primaryScreenGeometry.height() - mainWindow.height())/2.0); 

我只測試了這個代碼在Windows XP和Qt 4.8.x.希望它也可以在其他平臺上運行。

+0

當我這樣做時,我的日誌會被警告垃圾郵件:WindowsWindow :: setGeometryDp:無法設置幾何圖形450x394 + -50000 + -50000 – RvdK 2015-07-24 13:59:22

+0

嘗試更小或更好的東西,將其移動到正在運行的計算機的可見區域外,以確保它適用於任何顯示器配置。 – 2015-07-24 18:12:53

+0

我最終使用了這個解決方案:http://stackoverflow.com/a/16690448/47351 – RvdK 2015-07-26 13:10:37