0

iI have a Qt application using QGLWidget for drawing (simply a Viewport for 3D drawing etc...)

There is two main classes in the application.

  • MainWindow Inherits from QWidget which holds many GUI widgets (menubar, toolbars, viewport, treeview...etc)
  • System Does every other operation from GUI (math, geometry, IO, data processing, etc and holds "Scene" object which has drawable components.) Also it has Singleton pattern to create one global Instance for itself.

I am using Qt signal-slot mechanism to communucate between MainWindow and System, actually MainWindow has the signals and System has the slots. My problem starts here, how can I signal from System to MainWindow slots? When I define MainWindow in System object it gives me lots of error. Normaly System references in MainWindow don't give error. But when I include MainWindow's header file in System.h, System references give error in MainWindow side "'System': the symbol to the left of a '::' must be a type".

Basically my structure is look like this.

// MainWindow.h
#include "System.h"
class MainWindow : public QWidget
{
    Q_OBJECT
public:
    QToolBar* MyToolBar; // etc...
    MainWindow()
    {
        ConnectSignals();
    }
    void ConnectSignals() { connect(my_action, SIGNAL(triggered()), System::GetInstance()->Actions, SLOT(action())); }
}
// System.h
#include "MainWindow.h" // if I wrote this, it gives me error in compile time.
class System
{
    static bool m_instance;
    static System* m_system;

    // private constructor
    System()
    {
        Actions = new MyActionList();
    }

public:

    MyActionList* Actions;

    System* GetInstance()
    {
        if (!m_instance)
        {
            m_system = new System();
            m_instance = true;
            return m_system;
        }
        else { return m_system; }
    }
}
// System.cpp
bool System::m_instance = false;
System* System::m_system = NULL;

Of course Actions has slot action() So how can I access MainWindow from System?

4

2 回答 2

2

您的方法中的问题是 MainWindow 和 System 之间的循环依赖关系 - MainWindow 包括 System,System 包括 MainWindow。

为了将信号从 System 传递到 MainWindow,您需要使 Sytem 的 MyActionList 发出任何接收器(在您的情况下为 MainWindow)都可以处理的信号。您绝对不需要将 MainWindow 的东西包含到系统中 - 让您的后端(系统)独立于任何 GUI 组件。只需将 System 封装到 MainWindow 类中,并将 MyActionList 信号连接到 MainWindow 插槽。你需要在你的 MainWindow 中有这样的东西:

connect(my_action, SIGNAL(triggered()), System::GetInstance()->Actions, SLOT(action()));
connect(System::GetInstance()->Actions, SIGNAL(systemSignal()), this, SLOT(handleSystemSignal()));

其中systemSignal()是从 System 或其 MyActionList 组件发出的信号。

于 2013-09-17T06:46:13.790 回答
1

正如@vahancho 所说,您应该将 GUI 和其他系统分开。另一种方法是引入一个委托对象来处理两者之间的通信。

此外,如果您在问题中显示内联代码,那么这将增加循环依赖的可能性。将实现移动到 .cpp 文件中,并尽可能使用前向声明,而不是在其他头文件中包含头文件。这还具有加快编译速度的好处,您会在大型项目中注意到这一点。

于 2013-09-17T07:52:43.167 回答