diff --git a/docs/gui.rst b/docs/gui.rst index 9f873dcf912c2..c2090b670fa2e 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -10,11 +10,12 @@ Create a window --------------- -.. function:: ti.GUI(title = 'Taichi', res = (512, 512), background_color = 0x000000) +.. function:: ti.GUI(title = 'Taichi', res = (512, 512), background_color = 0x000000, show_gui = True) :parameter title: (optional, string) the window title :parameter res: (optional, scalar or tuple) resolution / size of the window :parameter background_color: (optional, RGB hex) background color of the window + :parameter show_gui: (optional, bool) see the note below :return: (GUI) an object represents the window Create a window. @@ -22,10 +23,23 @@ Create a window The following code creates a window of resolution ``640x360``: - :: + .. code-block:: python gui = ti.GUI('Window Title', (640, 360)) + .. note:: + + If you are running Taichi on a machine without a GUI environment, consider + setting ``show_gui`` to ``False``: + + .. code-block:: python + + gui = ti.GUI('Window Title', (640, 360), show_gui=False) + + while gui.running: + ... + gui.show(f'{gui.frame:06d}.png') # save a series of screenshot + .. function:: gui.show(filename = None) diff --git a/taichi/gui/gui.h b/taichi/gui/gui.h index 0ff187dbf8199..7b90ff9624fbe 100644 --- a/taichi/gui/gui.h +++ b/taichi/gui/gui.h @@ -815,43 +815,41 @@ class GUI : public GUIBase { void update() { frame_id++; - taichi::Time::wait_until(last_frame_time + frame_delta_limit); - auto this_frame_time = taichi::Time::get_time(); - if (last_frame_time != 0) { - last_frame_interval.push_back(this_frame_time - last_frame_time); - } - last_frame_time = this_frame_time; - // Some old examples / users don't even provide a `break` statement for us - // to terminate loop. So we have to terminate the program with RuntimeError - // if ti.GUI.EXIT event is not processed. Pretty like SIGTERM, you can hook - // it, but you have to terminate after your handler is done. - if (should_close) { - if (++should_close > 5) { - // if the event is not processed in 5 frames, raise RuntimeError - throw std::string( - "Window close button clicked, exiting... (use `while gui.running` " - "to exit gracefully)"); - } - } if (show_gui) { + taichi::Time::wait_until(last_frame_time + frame_delta_limit); + auto this_frame_time = taichi::Time::get_time(); + if (last_frame_time != 0) { + last_frame_interval.push_back(this_frame_time - last_frame_time); + } + last_frame_time = this_frame_time; + // Some old examples / users don't even provide a `break` statement for us + // to terminate loop. So we have to terminate the program with + // RuntimeError if ti.GUI.EXIT event is not processed. Pretty like + // SIGTERM, you can hook it, but you have to terminate after your handler + // is done. + if (should_close) { + if (++should_close > 5) { + // if the event is not processed in 5 frames, raise RuntimeError + throw std::string( + "Window close button clicked, exiting... (use `while " + "gui.running` " + "to exit gracefully)"); + } + } while (last_frame_interval.size() > 30) { last_frame_interval.erase(last_frame_interval.begin()); } auto real_fps = last_frame_interval.size() / (std::accumulate(last_frame_interval.begin(), last_frame_interval.end(), 0.0_f)); - update_gui(real_fps); + redraw_widgets(); + redraw(); + process_event(); + if (frame_id % 10 == 0) + set_title(fmt::format("{} ({:.2f} FPS)", window_name, real_fps)); } } - void update_gui(float real_fps) { - redraw_widgets(); - redraw(); - process_event(); - if (frame_id % 10 == 0) - set_title(fmt::format("{} ({:.2f} FPS)", window_name, real_fps)); - } - bool has_key_event() { return !!key_events.size(); } diff --git a/taichi/gui/x11.cpp b/taichi/gui/x11.cpp index 475e42b94fe84..d9786b31c34df 100644 --- a/taichi/gui/x11.cpp +++ b/taichi/gui/x11.cpp @@ -136,7 +136,8 @@ void GUI::create_window() { TI_ASSERT_INFO(display, "Taichi fails to create a window." " This is probably due to the lack of an X11 GUI environment." - " If you are using ssh, try ssh -XY."); + " Consider using the `ti.GUI(show_gui=False)` option, see" + " https://taichi.readthedocs.io/en/stable/gui.html"); visual = DefaultVisual(display, 0); window = XCreateSimpleWindow((Display *)display, RootWindow((Display *)display, 0),