【问题标题】:Must construct a QApplication before a QWidget必须在 QWidget 之前构造 QApplication
【发布时间】:2014-03-02 15:52:35
【问题描述】:

到处都只是“在 QPaintDevice 之前”的问题,而且我的错误无处不在。所以,我们开始吧。

我需要一个 extern QWidget 才能从外部访问它(因为我不知道有任何其他方法可以做到这一点)。基本上,我需要这个:从 1 个窗口创建 2 个 QWidget,转到第一个窗口,然后从那里隐藏主窗口并显示由主窗口创建的第二个窗口(虽然主窗口不是 main(),但它也是 QWidget)。

我加了

extern QWidget *widget = new QWidget

以可能的方式无处不在,但我仍然收到此消息。我想,这意味着我需要创建我的 QApplication(在 main.cpp 中),然后才声明任何 QWidget。但是我怎样才能从另一个 QWidgets 访问那些 QWidgets?

代码在这里: https://github.com/ewancoder/game/tree/QWidget_before_QApp_problem

附:最终目标是能够在 Battle.cpp 中显示和隐藏 gamewindow.cpp 和 world.cpp(只是普通类)

顺便说一句,添加 Q_OBJECT 和 #include 都不起作用。

无论如何,如果我不能从一个窗口到另一个窗口使用函数,那又有什么意义呢?我可以在另一个窗口中有一个窗口,然后在那个窗口中有另一个窗口,然后在另一个窗口中有一个窗口……但是从最后一个到上一个,我什么都做不了。在 Delphi 工作多年后,这对我来说似乎很奇怪。

【问题讨论】:

  • 我从未在 C++/Qt 程序中遇到过有效的“extern”用例。正确的方法是让主窗口进行管理并让孩子通过信号/插槽连接发送对另一个小部件的隐藏/显示请求,或者将指向要管理的小部件的指针传递给想要管理的小部件隐藏它们。 (即将指针作为成员存储在管理小部件中)
  • 孩子不能使用他们的父母功能(如隐藏或显示),我已经尝试过这样做。所以,唯一的方法就是信号/插槽连接,对吧?当我探索 QT 世界时,它们对我来说看起来很奇怪,我也无法让它们工作。无论如何,谢谢你的指导,我会在谷歌上搜索更多关于连接的信息。
  • 您还可以将父级作为指向子级的指针传递并调用例如从那里显示/隐藏。虽然它通常是不好的样式并导致循环依赖让子窗口/小部件知道主窗口。
  • 哦,对了。得试试这个。再次感谢,可以作为快速修复的 gr8 选项。但从长远来看,我想编写有效的良好风格的 c++。 UPD:我可以将指针存储在全局变量中,以便能够从任何类进行连接。
  • 好吧,我遇到了同样的错误。在应用程序实际运行 . 之前,我不能使用 QWidget 类型的任何变量、指针等

标签: c++ qt widget qwidget


【解决方案1】:

在 main 中创建 QApplication 之前,不要使用导致创建小部件的外部或其他静态变量。在QWidget的构造函数执行之前,QApplication必须存在。

不是通过外部共享变量,而是使其他窗口成为主窗口的成员,然后通过传递指针使窗口彼此知道,或者在 MainWindow 中保持它们的私有并从子窗口请求操作,例如通过信号/插槽。作为一般规则,不要使用全局变量,而是使用类成员。

在下面的 FirstWindow(应该隐藏主窗口和 secondWindow)中,通过指针获取主窗口和第二个窗口,然后直接在它们上调用 show/hide。

int main(int argc, char **argv) {
    QApplication app(argc, argv);

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

在主窗口中,其他两个窗口有两个成员,比如 FirstWindow 和 SecondWindow: 类主窗口:公共 QMainWindow { ... 私人的: 第一个窗口 *m_firstWindow; 第二窗口 *m_secondWindow; };

MainWindow::MainWindow(QWidget *parent) {
     m_firstWindow = new FirstWindow; //not pass this as parent as you want to hide the main window while the others are visible)
     m_secondWindow = new SecondWindow;
     m_firstWindow->setMainWindow(this);
     m_firstWindow->setSecond(m_secondWindow);
     m_firstWindow->show(); //Show first window immediately, leave second window hidden
}

MainWindow::~MainWindow() {
     //Manual deletion is necessary as no parent is passed. Alternatively, use QScopedPointer
     delete m_firstWindow;
     delete m_secondWindow;
}

FirstWindow,为了简洁,内联:

class FirstWindow : public QWidget {
    Q_OBJECT
public:
    explicit FirstWindow(QWidget *parent = 0) : QWidget(parent) {}

    void setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow); }
    void setSecondWindow(SecondWindow *secondWindow) { m_secondWindow = secondWindow; }

private Q_SLOTS:
     void somethingHappened() { //e.g. some button was clicked
         m_mainWindow->hide();
         m_secondWindow->show();
     }
private: 
     MainWindow* m_mainWindow;
     SecondWindow* m_secondWindow;  
};

【讨论】:

    【解决方案2】:

    也许没有帮助前作者,但其他人面临问题。 我只是将调试库误认为是发行版而得到了这个错误。因此,请检查您的链接器设置,如果您确定实现正确(首先实例化应用程序,然后使用小部件)。

    【讨论】:

    • 你是怎么做到的?
    • 自动回答:检查您是否正在编译发布版本而不是调试版本。
    猜你喜欢
    • 2023-03-12
    • 2016-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多