FLTK:Fl_Group::add 何时以及如何生效?

问题描述 投票:0回答:1

下面的代码,这两行按此顺序

tab1.add(glWindow2);
window->show();

产生这个图像:

enter image description here

但是如果我将添加调用放在 window->show 之后:

window->show();
tab1.add(glWindow2);

它会产生这个:

enter image description here

并且任何用户挑衅(切换选项卡、最小化和取消最小化窗口)都不会导致看到第二个球体。然而,在调试器中检查这一行的输出:

Fl_Widget * const *kids = tab1.array();

显示 tab1 确实有两个孩子。

那么add什么时候起作用,它是如何起作用的,以及可能还需要哪些其他操作才能使其真正生效?这到底是怎么回事,我正在恢复一些 20 年前的代码,这些代码曾经可以工作,但大约 10 年前它恰恰在这一点上崩溃了。我很想知道发生了什么变化。

节目:

#include <FL/Fl.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/gl.h>
#include <OpenGL/glu.h>

void glutWireSphere (GLdouble radius, GLint slices, GLint stacks);

class MyGlWindow : public Fl_Gl_Window {
private:
    float blue;
public:
    MyGlWindow(int x, int y, int w, int h, float bblue = 0.0f, 
                const char* l = 0) : Fl_Gl_Window(x, y, w, h, l) {
        blue = bblue;
    }

    void draw() override {
        if (!valid()) {
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glViewport(0, 0, w(), h());
            glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 5.0);
            glEnable(GL_DEPTH_TEST);
            valid(1);
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        // Set up the camera
        gluLookAt(0.0, 0.0, 4.5,  // eye position
                  0.0, 0.0, 0.0,  // look-at position
                  0.0, 1.0, 0.0); // up direction

        // Draw a sphere
        glColor3f(0.5, 1.0, blue);
        glutWireSphere(0.8, 20, 20);

        glFlush();
    }
};

int main() {
    Fl_Window* window = new Fl_Window(400, 800, "FLTK Sphere Example");
    Fl_Tabs mainTabs(0,5,window->w(),window->h()-32);
        Fl_Group tab1(0,20,window->w(),window->h()-32, "Tab 1");
            MyGlWindow* glWindow = new MyGlWindow(10, 60, window->w() - 20, 400 - 20, 0.0);
        tab1.end();
            MyGlWindow* glWindow2 = new MyGlWindow(10, 450, window->w() - 20, 400 - 20, 1.0);
        Fl_Group tab2(0,64,window->w(),window->h()-32, "Tab2");
            MyGlWindow* glWindow3 = new MyGlWindow(10, 100, window->w() - 20, 400 - 20, 0.5);
        tab2.end();
    mainTabs.end();
    window->resizable(window);
    window->end();
    tab1.add(glWindow2);
    window->show();
    Fl_Widget * const *kids = tab1.array();
    return Fl::run();
}
c++ opengl fltk
1个回答
0
投票

问:“添加什么时候起作用”? 答:基本上/总是/。 A->add(B) 将小部件 B 添加到小部件 A 的子项列表中。如果 B 已经是某个组(包括 A)的子项,则首先将其从该组中删除,然后添加到 A 组中。

问:“它是如何工作的”? 答:上面已经部分回答了。 FLTK 有一个“当前组”

Fl_Group::current()
,每当
Fl_Group
小部件的构造函数被调用时,就会通过组构造函数中的隐式
begin()
进行设置。除非当前组为 NULL,否则所有新小部件都会成为当前组的子级。调用 end() 使当前组的父窗口小部件成为新的当前组,该组可能为 NULL,例如用于主窗口。

示例程序的问题只是与这些问题间接相关。目前,

glWindow2
成为
mainTabs
的直接子级,因为
tab1.end()
在构造之前被调用。
Fl_Tabs
的子代受到特殊对待:任何时候都只能看到一个直系子代。因此
glWindow2
在程序开始时被隐藏 - 至少在 FLTK 1.4(开发)中。

该问题有两种(甚至更多)解决方案:

  1. MyGlWindow* glWindow2 = new MyGlWindow(...)
    移到
    tab1.end()
    之前。 2a.在
    glWindow2->set_visible();
    之后添加
    tab1.add(glWindow2);
    或 2b.在
    glWindow2->show()
    之后添加
    window->show();

我很想知道发生了什么变化。

这个很难说清楚。请注意,处理子窗口部分取决于平台(根据您在 macOS 上的屏幕截图)。 FLTK 开发仍在继续,您的旧程序可能使用了一种“未定义”行为。在任何人都能说出“发生了什么变化”之前,我们需要知道涉及哪些 FLTK 版本。 “一些 20 年前的代码”和“一些 10 年前”并不是很精确。 ;-)

我建议现在专注于 FLTK 1.4,因为这是当前的开发。如果您还有其他问题,我建议您在官方 FLTK“论坛”(Google 群组)fltk.general 中提问。 HTH

© www.soinside.com 2019 - 2024. All rights reserved.