Search code examples
c++ubuntugtkgtkmm

gtk image suddenly do not refresh without any errors or warnings


I develop a tool to capture image from a camera and show the captured image in a window. The GUI window is based on GTK 2.4. At begin, the tool is running correctedly, and the image is captured from camera and showed on the window in real-time. After a while, the image suddenly do not refresh any more on the window, but it's still captured from the camera. There is no errors or warnings. Anyone has ever encountered such a case? Thank you.

Ubuntu 18.04, GTK 2.4

  // loop to call the following code to refresh the image on the window
  pixbuf_ = Gdk::Pixbuf::create_from_data(
      final_img_buf_.data, Gdk::COLORSPACE_RGB, false, 8, final_img_buf_.cols,
      final_img_buf_.rows, static_cast<int>(final_img_buf_.step));
  gtk_image_.set(pixbuf_);

Edit at 2019-02-27 Thanks for all your replies. I have upgraded GTK to GTK+ 3, but this still appears.

  // loop to call the following code to refresh the image on the window
  pixbuf_ = Gdk::Pixbuf::create_from_data(
      final_img_buf_.data, Gdk::COLORSPACE_RGB, false, 8, final_img_buf_.cols,
      final_img_buf_.rows, static_cast<int>(final_img_buf_.step));
  // ensure the image is normally updating
  //std::this_thread::sleep_for (std::chrono::milliseconds(30));
  gtk_image_.set(pixbuf_);
  Glib::RefPtr<Gdk::Pixbuf> pixbuf = gtk_image_.get_pixbuf();
  std::string filename = std::string("./debug/") + std::to_string(CurTimestampMicrosecond()) + std::string(".jpg");
  pixbuf->save(filename, "jpeg");

Afther running a while, the window does not refresh image any more, but the image is still saved correctedly.

Edit at 2019-02-28

// The initialization code
gtk_main_.reset(new Gtk::Main(argc, argv));
ctrl_window_.reset(new CtrlWindow(screen, ctrl_rect)); // inherited from Gtk::Window
thread_ = std::thread([this]() {
  Gtk::Main::run(*ctrl_window_);
}

Solution

  • Looks like both g_timeout_add and possibly g_idle_add can be delayed due to the processing of other event sources, so is not optimal in contexts requiring precise timing, like drawing an image to a screen before the frame updates. I've noticed using g_timeout_add in a 2D graphics context completely freezes the application if it can't load a frame at the fps specified.

    gtk_widget_add_callback() might be more suited to your needs as it will draw the buffer as quickly as the application can, without hangs, basically doing the messy synchronization for you.