如何正确使用gtkmm3中的方框或网格

How to properly use boxes or grid in gtkmm3

本文关键字:方框 网格 gtkmm3 何正确      更新时间:2023-10-16

我拼命想在树莓pi上使用gtkmm3创建一个简单的GUI,但我已经为此挣扎了太久。然而,当我运行程序时,我似乎遇到了分段错误,我不知道为什么。。如果我去掉网格上的最后一行,它就行了。是我做错了什么,还是采取了更好的方法?

这是头文件gui_ex.h:

#ifndef GTKMM_EX_GUI_H
#define GTKMM_EX_GUI_H
#include <gtkmm.h>
class Gui_Ex : public Gtk::Window
{
public:
    Gui_Ex();
    virtual ~Gui_Ex();
protected:
    // Signal handlers:
    void on_connect_click();  
    void on_quit();

    //child widgets
  Glib::RefPtr<Gtk::Adjustment> m_adjustment;
  Gtk::Box m_VBox;
  Gtk::Label m_label, m_label2, m_label3;
  Gtk::Grid m_grid;
  Gtk::SpinButton m_spin;
  Gtk::Button m_button3, m_button4;//, m_connect;

};
#endif // GTKMM_EX_GUI_H

gui_ex.cpp:

#include "gui_ex.h"
Gui_Ex::Gui_Ex()
:
   m_adjustment( Gtk::Adjustment::create(1.0, 1.0, 5.0, 1.0, 5.0, 0.0) ),
   m_VBox(Gtk::ORIENTATION_VERTICAL), 
   m_label2("label2"),
   m_label3("label3"),
   m_button3("Connect"),
   m_button4("Quit"),
   m_spin(m_adjustment),  
   m_label("Choose the number of clients")  
{
    set_title("Grid");
  set_border_width(16);
  add(m_VBox);

  m_VBox.pack_start(m_grid);
  m_grid.attach(m_label, 0,0,2,1); //column, row, width (# col span), height (# row span). starts at 0
  m_grid.attach(m_spin, 2,0,1,1);
  m_grid.attach(m_label2, 0,1,2,1);
  m_grid.attach(m_label3, 2,1,1,1);
  m_grid.attach(m_button3, 0,2,2,1);
  m_grid.attach(m_button4, 2,2,1,1);
  m_spin.set_wrap();
  m_spin.set_numeric(true);
  m_button3.set_sensitive(true);
  m_button4.set_sensitive(false);  
  m_button3.signal_clicked().connect(sigc::mem_fun(*this, &Gui_Ex::on_connect_click));
  m_button4.signal_clicked().connect(sigc::mem_fun(*this, &Gui_Ex::on_quit));  

  show_all_children();
}
Gui_Ex::~Gui_Ex()
{
}
void Gui_Ex::on_quit(){
  bool running = false;
  m_spin.set_sensitive(true);
 m_button3.set_sensitive(true);
}

void Gui_Ex::on_connect_click()
{
    int BACKLOG = m_spin.get_value_as_int();
    m_spin.set_sensitive(false);
    m_button4.set_sensitive(true);
}

main_gui_ex.cpp:

#include "gui_ex.h"
#include <gtkmm/application.h>
int main (int argc, char *argv[])
{
    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
    Gui_Ex gui_ex;
    return app ->run(gui_ex);
}  

我找到了一个变通的解决方案。由于我仍然不知道的原因,原始代码仍然无法工作。以下是GDB中的回溯。

(gdb) run
Starting program: /home/pi/cplus/gui_ex
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
** (gui_ex:741): WARNING **: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files
Program received signal SIGSEGV, Segmentation fault.
0xb6b4d7b4 in Gio::Application::signal_activate() ()
   from /usr/lib/arm-linux-gnueabihf/libgiomm-2.4.so.1
(gdb) backtrace
#0  0xb6b4d7b4 in Gio::Application::signal_activate() ()
   from /usr/lib/arm-linux-gnueabihf/libgiomm-2.4.so.1
#1  0xb6e189cc in Gtk::Application::run(Gtk::Window&) ()
   from /usr/lib/arm-linux-gnueabihf/libgtkmm-3.0.so.1
#2  0x00014504 in main ()
(gdb)

对于我的解决方案,我在Glade中创建了UI,并使用Gtk::Builder将其导入到我的程序中。

这是代码:

#include <gtkmm.h>
#include <iostream>
using namespace std;
Gtk::SpinButton *spinbutton1 = 0;
Gtk::RadioButton *m_rby, *m_rbn = 0;
Gtk::Button *button_stop, *button_start = 0;
void buttonstart_clicked()
{

  cout << spinbutton1->get_value_as_int() << endl;
  button_start->set_sensitive(false);
  button_stop->set_sensitive(true);
}
void buttonstop_clicked()
{

  button_start->set_sensitive(true);
  button_stop->set_sensitive(false);
}
int main(int argc, char **argv)
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
  //Load the GtkBuilder file and instantiate its widgets:
  Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
  try
  {
    refBuilder->add_from_file("simplegui.glade");
  }
  catch(const Glib::FileError& ex)
  {
    std::cerr << "FileError: " << ex.what() << std::endl;
    return 1;
  }
  catch(const Glib::MarkupError& ex)
  {
    std::cerr << "MarkupError: " << ex.what() << std::endl;
    return 1;
  }
  catch(const Gtk::BuilderError& ex)
  {
    std::cerr << "BuilderError: " << ex.what() << std::endl;
    return 1;
  }

  Gtk::Window *window1 = 0;
  refBuilder->get_widget("window1", window1); 
  refBuilder->get_widget("button_stop", button_stop);
  refBuilder->get_widget("button_start", button_start);
  refBuilder->get_widget("spinbutton1", spinbutton1);
  refBuilder->get_widget("radiobutton1", m_rby);
  refBuilder->get_widget("radiobutton2", m_rbn);
  Gtk::RadioButton::Group group = m_rby->get_group();
  m_rbn->set_group(group);
  m_rby->set_active();
  Glib::RefPtr<Gtk::Adjustment> m_adjustment = Gtk::Adjustment::create(1.0, 1.0, 5.0, 1.0, 5.0, 0.0);
  spinbutton1->set_adjustment(m_adjustment);
  // connect more signals
  button_start->signal_clicked().connect(sigc::ptr_fun(buttonstart_clicked));
  button_stop->signal_clicked().connect(sigc::ptr_fun(buttonstop_clicked));


  app->run(*window1);
  return 0;
}