Qt GUI 从另一个类访问 MainWindow 的最简单方法

Posted

技术标签:

【中文标题】Qt GUI 从另一个类访问 MainWindow 的最简单方法【英文标题】:Qt GUI Easiest way to access MainWindow from another class 【发布时间】:2017-02-18 00:44:55 【问题描述】:

我正在做一个二十一点程序,并且我在主窗口类之外的另一个类(“hand.h”)中跟踪玩家手中的牌。

在手牌类中,对于我收集的每张卡片,我还创建了一个 QLabel,它为卡片抓取正确的卡片图像,并设置卡片应出现在主窗口上的位置的坐标。

问题是我无法根据最初在 main 函数中创建的 MainWindows 对象创建 QLabel。有什么简单的方法可以让我很容易地获得这些信息吗?感谢您的帮助!

我曾尝试使用 QGuiApplication::topLevelWindows(),但使用它时运气不佳。这是我正在使用的函数。

    #include <QRect>
    #include <QApplication>
    #include <iostream>
    #include <QLabel>
    #include "mainwindow.h"
    #include <QMainWindow>
    #include <QWindowList>
    #include <QWidgetList>
    #include "ui_mainwindow.h"

    void Test() 

    QList<QWindow*> Main_Window = QGuiApplication::topLevelWindows();
     for (int i = 0; i < Main_Window.size(); ++i) 
        if(Main_Window.objectName() == "mainWindow") // name is OK
                break;
        
    QMainWindow* mainWindow = static_cast<QMainWindow*>(Main_Window);


    QLabel* temp;
    temp = new QLabel(Main_Window);
    temp->setPixmap(QString("Ten of Clubs.png"));
    temp->setGeometry(290, 300, 350, 390);
    temp->show();

    

这里是创建主窗口的 main.cpp 文件

    int main(int argc, char *argv[])
    
      srand(time(NULL));
      QApplication a(argc, argv);
      MainWindow w;

      w.show();
      return a.exec();
    

我在网上找到了迭代代码,但一直遇到问题。 我在尝试遍历列表时遇到问题,但我不知道如何识别列表并且错误表明没有 objectName() 函数。此外,在静态转换行中,有一个错误说我无法将 QList 转换为 QMainWindow 类型。任何帮助将不胜感激。

【问题讨论】:

你能解释一下如何使用 QLabel 来使用 topLevelWindows() 吗?我曾多次尝试使用它,但没有任何运气。除了 main 函数中的预制窗口之外,我没有创建任何窗口。 这应该进入你的问题(你应该编辑)。如果您的代码在 github 上,您可以在问题中提供指向它的链接。 你是对的。我很抱歉。我已经用我的代码更新了它并尝试解决它。再次感谢您的帮助! 我尝试迭代列表并没有成功。有什么建议吗? 这不是 Qt 特有的问题:像对待任何其他需要引用其他对象的 C++ 类一样处理它。 【参考方案1】:

一般来说不可能,因为某些应用程序可能有几个(***)QMainWindow-s(并且它们的列表可能会随着时间而改变)。因此,对于这种情况,您最好将指针(您要处理的特定QMainWindow)明确传递给它....

一种可能的方法是让您的特定子类QApplication(这是一个单例类,请参阅QCoreApplication::instance 以获取其唯一实例)并在您的应用程序子类中放置您想要的显式窗口作为字段处理(也许你甚至想在你的应用程序类中添加一些新的信号或槽)。

但是,您可以使用QGuiApplication::topLevelWindows() 或QGuiApplication::allWindows() 来获取所有此类窗口的列表。请注意,QWindowList 只是 QList&lt;QWindow *&gt;。因此,请参阅 QList 了解如何遍历或迭代该列表。

一旦你找到了你想要的QMainWindow,通常的做法是在其中添加QLabel(但同样,信号和插槽可能会有所帮助)。

顺便说一句,每个(显示的)小部件都有其窗口,请参阅QWidget::window()


关于您的代码:

你的Main_Window 的名字真的很糟糕(而且这个名字太混乱了,我不能用它)。它是一个列表,而不是一个窗口。所以先写代码:

QMainWindow* mainWindow = nullptr;

  QList<QWindow*> topwinlist = QGuiApplication::topLevelWindows();
  int nbtopwin = topwinlist.size();
  for (int ix=0; ix<nbtopwin; ix++) 
    QWindow*curwin = topwinlist.at(ix);
    if (curwin->objectName() == "mainWindow")
      mainWindow = dynamic_cast<QMainWindow*>(curwin);
  
 

我没有测试上面的代码,我不确定它是否正确甚至可以编译。但是你为什么不只是有一个指向你的主窗口的全局指针:

 MainWindow*mymainwinp = nullptr;

并在您的 main 正文中适当地初始化它:

int main(int argc, char *argv[]) 
  srand(time(NULL));
  QApplication a(argc, argv);
  MainWindow w;
  mymainwinp = &w;
  w.show();
  int r = a.exec();
  mymainwinp = nullptr;
  return r;

然后在其他地方使用mymainwinp(例如在您的Test 中)?如果您想要更优雅的代码,请定义您自己的 QApplication 子类并将 mymainwinp 作为其中的一个字段。

【讨论】:

以上是关于Qt GUI 从另一个类访问 MainWindow 的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

当 MainWindow 从另一个类(不在主函数中)启动时,QT ui 未显示

QT 在主类之外声明 Mainwindow

从另一个类访问 MainWindow 类成员

Qt:访问在构造函数之外使用 GUI 小部件的类的函数

来自另一个类的 Qt c++ GUI 调用

如何从另一个 QT 应用程序访问 Qt UI 的 QObject?