QT/C++ - 从不同的类访问 MainWindow UI [英] QT/C++ - Accessing MainWindow UI from a different class

查看:35
本文介绍了QT/C++ - 从不同的类访问 MainWindow UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 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.

  1. QApplication 对象实际上存储了所有顶级窗口,例如您的 MainGame,这意味着您始终可以通过 QApplication::topLevelWidgets() 这是一个静态函数并返回一个包含所有顶级小部件的列表.由于您只有一个,因此第一个是您的 MainGame.缺点是你必须投射它,但使用 Qts qobject_cast(...) 是相当安全的.您必须检查结果以确保它不是 NULL 指针.

  1. The QApplication object actually stores all top level windows like your MainGame which means you can allways aquire it through QApplication::topLevelWidgets() which is a static function and returns a list with all top level widgets. Since you only have one, the first one is your MainGame. The drawback is you'll have to cast it, but using Qts qobject_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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆