清理一个GTKmm应用程序的代码

3

大约六个月前,我开始了一个GTKMM应用程序,现在已经达到了一切正常运行,我每天都在使用它的地步。它本质上是一个数据库应用程序,可以从另一个应用程序读取数据文件,生成图表并让您轻松地对数据进行排序和查看。我很喜欢它。

然而,我认为我的代码很混乱,当我今天要实现另一个功能时,我意识到我可能走错了方向。

我的主窗口GUI在一个glade文件中定义,除了我的绘图小部件(一个基于Gtk :: DrawingArea的自定义小部件)以外,所有GUI都在一个单独的文件中。它充满了对部件和树形存储器的指针,在构造函数中设置,在析构函数中删除。

整个GUI是一个主窗口,分成不同的面板,所以将所有内容放在1个文件中是有意义的。此外,不同的面板需要与其他面板“通信”。

我应该如何更好地组织我的代码,使其可维护?我是否应该创建一个新类,作为部件集合,然后将该“超级部件”放置在我的主窗口中(例如,每个面板都是一个超级部件)?

GTKMM教程通常都非常简约,所以我无法从中获得太多见解。

2个回答

3

我目前在开发一个大型的GTKMM应用程序。代码库中遵循的一般规则是,每个Frame(包含一组小部件)都是其自己的类,在自己的cpp文件中编写。然后在主函数中实例化这些类作为单例类,每个类都公开一个getFrame方法。

// Single instance of this class.
SomeGUIComponent* SomeGUIComponent::m_instance = NULL;

SomeGUIComponent& SomeGUIComponent::getInstance()
{
  if (m_instance == NULL)
  {
    m_instance = new SomeGUIComponent();
  }
  return *m_instance;
}

Gtk::Frame& SomeGUIComponent::getFrame()
{
  return m_myMasterFrame;
}

因此,可以通过以下方式将其添加到较大的应用程序中:

SomeGUIComponent::getInstance().getFrame()

好的,这很有道理。那么,当框架需要彼此通信时怎么办呢?例如,如果您在SomeGUIComponentA中按下按钮并且需要刷新SomeGUIComponentB中的标签怎么办?现在由于按钮和标签都在我的大型GUI类中,所以这很简单,但是每个框架是否需要指向其他每个框架的点呢? - Brandon
@baubie,在这种情况下,我们将在组件B中公开一个公共方法来更新私有标签,并从组件A调用:SomeGUIComponentB.getInstance().updateLabel(valueToUpdateWith); - Mark
谢谢,这很有道理。自从发布问题以来,我一直在阅读关于这个的许多文章。你的答案肯定是有效的,所以我已经标记了它。唯一的缺点是单例似乎因为与全局变量相同的原因而受到高度反对。相反,我想可能会将指向父窗口的指针传递给每个组件,并通过父窗口调用组件。 - Brandon

3
我最终采取的解决办法是将每个逻辑组件集合分开成各自的类。然后创建信号在我的主GUI类中捕获并在那里处理。需要传递的任何内容都在主GUI类代码中完成,现在一切都变得清晰明了。例如,我不关心筛选器框架中特定组合框的值是否更改。相反,我只关心筛选器什么时候更改。因此,我的筛选器类(包含所有筛选器小部件)触发自定义changed()信号,我有设置器和获取器来更新该筛选器中的变量以适当地更新小部件。

我认为这种方式非常干净,避免使用单例模式,将我的UI分隔开来,使整个工作变得更加愉快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接