c - 用 C 语言设计一个简单的 GUI 框架

标签 c user-interface design-patterns

我需要为一个学校项目设计一个一个非常简单的 GUI 框架,它需要支持以下控件/小部件:窗口、面板、图像、标签和按钮。

  • 我想到的第一个问题是是否 Window应该是一个控件。我想应该是这样。
  • 我们有WindowPanel其中可以包含其他控件。 Button , LabelImage , 不能。所以我们需要两种基本类型的控件;一个是容器,另一个不是(我在 Gtk 实现中看到后者也是一个容器,但只能包含一个子容器。它被称为 GtkBin 。我认为这对我的简单项目来说是一种开销。
  • 我遇到的第三个问题是:我需要遍历 UI 树(用于绘图),但由于 C 中没有多态性机制,因此它变得有些问题。

我考虑了以下解决方案,利用 union 。基本上我需要一些函数来转换通用 Control其实际类型。

typedef struct button {
    char *image_path;
} Button;

typedef struct control_node {
    Control *node;
    struct control_node *next;
} ControlNode;

typedef struct panel {
    ControlNode *children;
} Panel;

typedef union control_data {
    Panel panel;
    Button button;
} ControlData;

typedef struct control {
    int x;
    int y;
    int type;
    ControlData *data;
} Control;

因此,我想了解您对我提出的问题的看法以及对我当前策略的看法(我不是在寻找实现方案,而是在寻找想法/想法等)

谢谢。

最佳答案

您应该在每个“GUI 类”的布局中首先放置一个 void * ,它将指向每种类型手动实现的 v-table。每个类型的 v 表中的第一个函数可以是一个,为每个类型返回一个唯一的整数(或者只是一个唯一的整数),因此您可以分辨什么是什么并实现一些类型安全。虽然没有必要,但您可以使用 v-table 指针值来确定类型(因为它将是唯一的),这将节省内存,但会不太明显。在对象销毁中具有虚拟性也很重要,因此用于处理每个唯一类型的内部结构并使其在 v 表中的位置保持一致的析构函数也是必须的。虽然对于您的任务来说这实际上是可以避免的,但对于生产来说这是必须的。

对于实际的树来说,这应该建立在一个简单的父子关系上,围绕着叶子和节点接口(interface),叶子只保存一个指向父节点的指针,节点还包括一个动态列表类型,你还必须实现。那么遍历这棵树就相当简单了。

您可以通过使用“接口(interface)”结构和聚合来代替继承来进行一些模块化,但与单独实现每种类型相比,它不会为您节省太多精力,只要您将 v-table 指针保留在类型布局中的第一个对象,以便您知道您正在使用什么以及如何使用它。其余部分的布局对于遵循任何准则来说并不那么重要,只要您知道类型并将指针转换为适当的结构类型即可。但是由于每个对象都会有一个父对象,甚至是根,可以通过其父对象为 0 来识别它,因此您确实应该将父对象放在 v-table 指针之后,这样您就可以在需要访问的所有内容时避免强制转换父级。

您可以受益的另一件事是使用信号,就像每个按钮中都有另一个指针一样,因此您可以将其分配给“单击”按钮时要执行的函数。

关于c - 用 C 语言设计一个简单的 GUI 框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31920133/

相关文章:

java - 实现椭圆之间的折线连接

Java 使组件能够相互通信

java - 为什么学习基类能力不好

c++ - QTreeView 策略子类。这是理智的吗?

c++ - 使用 Visual Studio 2008 从 x86 编译 x64 dll

C 编程语法

滚动期间的 Flutter- Listview 落后于小部件上方

java - 如何处理服务器之间的时间不同步

c - 在 C 中,释放结构体时是否需要手动释放结构体中的指针?

从 X11 应用程序干净退出?