FLTK 1.3:如何确定fl_line()的“上下文”?

FLTK 1.3: how to determine the "context" of fl_line()?

提问人:pavelkolodin 提问时间:8/18/2023 最后编辑:pavelkolodin 更新时间:8/18/2023 访问量:31

问:

正在寻找一些适用于 linux 的简约 C++ GUI 框架,所以在这里我试图熟悉 FLTK 1.3 / Ubuntu。编写了一些工作代码,以 30 FPS 的速度将一些随机信号波状的随机颜色动画化。它有一些小问题:完全不知道波浪会画到哪里。在窗口、按钮或对话框中(当它出现时)。

似乎我不明白如何为类函数定义某种“上下文”。每次被调用时,都会在某个不可预测的位置画线。fl_line()fl_like()

当您将焦点放在按钮上时,线条开始在该按钮上绘制。当您调用对话框时,您会在那里获得行,此外,该对话框中的按钮也会被行覆盖!当您关闭对话框时,您看到这些行仅在“关闭”按钮上写入。

所以,我的问题是如何预测线条将被绘制的“视觉上下文”(FLTK 中有这样的术语吗)。

我的代码:

#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/fl_message.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <cstdlib>

namespace simulator {

class Graph : public Fl_Widget {
  unsigned char color_[3] = {0, 0, 0};

public:
  Graph(int X, int Y, int W, int H)
  : Fl_Widget(X, Y, W, H) {
  }

  void draw(void) {
    this->plot();
  }

  void plot() {
    // Pick some trash color in a trash way.
    color_[0] = rand() % 256;
    color_[1] = rand() % 256;
    color_[2] = rand() % 256;
    fl_color(color_[0], color_[1], color_[2]);

    // Draw some random "audio wave"-like thing
    // Dont care about cleaning the scene before drawing.
    int old[2] = {0, 0};
    for (int i = 0; i < 400; ++i) {
      auto x = i * 2;
      auto y = rand() % 400;
      fl_line(old[0], old[1], x, y);
      old[0] = x;
      old[1] = y;
    }
  }
};

class Main_Window : public Fl_Window {
  //public Fl_Double_Window {
  Fl_Button button_ {10, 10, 75, 25, "Close"};
  Graph graph_;

public:
  Main_Window()
  //: Fl_Double_Window(200, 100, 1200, 800, "Simulator")
  : Fl_Window(200, 100, 1200, 800, "Simulator")
  , graph_(10, 100, 500, 500) {

    begin();
    Fl::visual(FL_RGB); 
    button_.align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP | FL_ALIGN_WRAP);
    // Button will invoke dialog "Want to exit?" with "yes/no" buttons.
    button_.callback([](Fl_Widget* sender, void* window) {
      printf("callback called, sender %p, window %p\n", sender, window);
      reinterpret_cast<Main_Window*>(window)->hide();
    }, this);
    
    // Maybe this is some illegal/unneeded/not-perfect widget adding code, and maybe widget adding is not needed at all; Lets forget about this for now.
    add(&button_);
    add(&graph_);

    end();
    show();
    graph_.show();
  }

  void hide() override {
    fl_message_hotspot(false);
    fl_message_title("Close window");
    if (fl_choice("Are you sure you want exit?", "No", "Yes", nullptr) == 1) {
      Fl_Window::hide();
    }
  }

  void plot() {
    graph_.plot();
  }
};
} // namespace

// 30 FPS wave animation.
void winUpdate(void *_data) {
  auto *window = reinterpret_cast<simulator::Main_Window*>(_data);
  Fl::add_timeout(1.0 / 30.0, winUpdate, window);
  window->plot();
}

int main(int argc, char *argv[]) {
  simulator::Main_Window window;
  window.show(argc, argv);
  Fl::add_timeout(1.0 / 30.0, winUpdate, &window);
  return Fl::run();
}

构建命令:

/usr/bin/x86_64-linux-gnu-g++-12 test.cpp -o test -I/usr/include/c++/12 -std=c++20 -Wuninitialized -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-sign-compare -Wno-type-limits -Wunused-function -ggdb -fno-strict-aliasing -fwrapv -fno-stack-protector -fno-strict-overflow -Wfatal-errors `fltk-config --ldflags` -lfltk -lfltk_images -ljpeg -lstdc++ -lXfixes -lXext
C++ FLTK语言

评论


答:

1赞 pavelkolodin 8/18/2023 #1

找到了正确的方向。如果要重新绘制小部件,请不要直接调用或某些绘制函数。您宁愿致电,FLTK 将安排正确重新绘制该小部件。draw()fl_line()widget->redraw()

所以,在我的代码中,必须做而不是.Main_Window::plot()graph_.redraw();graph_.plot();