問題描述
我是 C++ 和 Qt 的初學者,所以這可能是微不足道的.這當然感覺應該很簡單,但我一直在尋找答案幾個小時,但找不到解決方案.我正在制作一個簡單的棋盤游戲,其中 MainWindow 的 ui(在 QtDesigner 中制作)包含游戲棋盤的畫布(QGraphicsView).現在,main.cpp 非常簡單:
I'm a beginner to both C++ and Qt, so perhaps this is trivial. It certainly feels like it should be simple, but I've been searching for an answer for a few hours now and can't find the solution. I'm making a simple board game where the MainWindow's ui (made in QtDesigner) contains a canvas for the game board (a QGraphicsView). Now, the main.cpp is as simple as can be:
MainWindow Game;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Game.show();
return a.exec();
}
由于我需要從另一個完全不相關的類訪問和編輯 MainWindow 小部件,我認為最簡單的方法是將 MainWindow 設為全局變量.不過,這種方法似乎是非常錯誤的.嘗試在 QtDesigner 中運行項目時,我收到 Microsoft Visual C++ 運行時庫錯誤:應用程序已請求運行時以異常方式終止它.
Since I need to access and edit the MainWindow Widgets from another totally unrelated class, I thought the easiest way would be to just make MainWindow a global variable. It seems that this approach was very wrong, though. Upon trying to run the project in QtDesigner I get a Microsoft Visual C++ runtime library error: the application has requested runtime to terminate it in an unusual way.
那么做我需要的正確方法是什么?
So what is the correct way to do what I need?
除了 MainWindow 之外,我還有一個新游戲的對話框(QDialog,從 QtDesigner 生成),在 MainWindow 中單擊菜單項后會顯示該對話框.當用戶輸入游戲的所有參數并在對話框中單擊確定"時,我會實例化一個名為 GameState 的自定義非 Qt 類.這個類的目的是操作游戲本身,畫板,提示用戶等. 但是,由于這個類是在 QDialog 中創建的,它不知道 MainWindow 的存在,所以我不能對 MainWindow 做任何事情從這個班級.那么如何從不相關的類修改 MainWindow 呢?
Aside from the MainWindow I have a dialog for a new game (QDialog, generated from QtDesigner) that is displayed after clicking a menu item in MainWindow. When the user inputs all parameters for the game and clicks OK in the dialog, I instantiate a custom non-Qt class called GameState. This class is meant to operate the game itself, draw the board, prompt the user, etc. However, as this class is created in the QDialog, it does not know of the existence of a MainWindow and so I cannot do anything with the MainWindow from this class. How can I modify the MainWindow from an unrelated class, then?
另外,setEnabled() 函數是如何工作的?它似乎永遠不會做任何事情.我在 QtDesigner 中設置為禁用的任何小部件然后嘗試通過此功能啟用仍然在 GUI 中保持禁用狀態...
Also, jsut how does the setEnabled() function work? It never seems to do anything. Any widget I set as disabled in the QtDesigner and then try to enable through this function still stays disabled in the GUI...
推薦答案
首先,在創建 QApplication
對象之前創建 MainGame
是個壞主意.如果你想讓你的 MainGame
對象像這樣全局可用,它應該是一個指針:
First off it's a bad idea to create MainGame
before you create your QApplication
object.
If you want to have your MainGame
object globally available like this it should be a pointer:
MainWindow *Game;
int main (int argc, char **argv)
{
QApplication a (argc, argv);
Game = new MainWindow();
Game->show();
int result = a.exec();
delete Game;
Game = NULL;
return result;
}
然而,這種方法并不是最優雅的.有兩個更好的選擇.
This approach is however not the most elegant. There are two much better choices.
QApplication
對象實際上存儲了所有頂級窗口,例如您的MainGame
,這意味著您始終可以通過QApplication::topLevelWidgets()
這是一個靜態函數并返回一個包含所有頂級小部件的列表.由于您只有一個,因此第一個是您的MainGame
.缺點是你必須投射它,但使用 Qtsqobject_cast
是相當安全的.您必須檢查結果以確保它不是 NULL 指針.(...)
The
QApplication
object actually stores all top level windows like yourMainGame
which means you can allways aquire it throughQApplication::topLevelWidgets()
which is a static function and returns a list with all top level widgets. Since you only have one, the first one is yourMainGame
. The drawback is you'll have to cast it, but using Qtsqobject_cast<MainGame*>(...)
is fairly safe. You'll have to check the result though to make sure it isn't a NULL pointer.
使用單例設計模式.您應該將全局 Game 指針存儲在 Game 類本身(子類 QMainWindow
)的源 (cpp) 文件中,并且您的 Game 類應該實現一個返回此全局指針的靜態公共方法.因此,如果任何其他類需要 Game
指針,它只需調用:
Use the singelton design pattern. You should store the global Game pointer in the source (cpp) file of the Game class itself (subclass QMainWindow
) and your Game class should implement a static public method which returns this global pointer. So if any other class needs the Game
pointer, it simply calls:
MyGame *theGame = MyGame::getInstance();
例如.
關于您的 setEnabled()
問題.請貼出相關代碼.如果太多,請通過郵件向我發送 *.ui 文件和代碼段.
Regarding your setEnabled()
problem. Please post the relevant code. If it's too much feel free to send me the *.ui file and the piece of code via mail.
最好的問候
D
這篇關于QT/C++ - 從不同的類訪問 MainWindow UI的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!