Идентификатор ответа диалоговой кнопки поля выделен серым цветом

#mingw #gtkmm #glade

#mingw #gtkmm #поляна

Вопрос:

У меня есть диалоговое окно настроек с кнопками «Ок» и «Отмена» в области обычных действий внизу. У меня также есть кнопка просмотра, которую я не хочу опускать в нижней части диалогового окна.

Итак, у меня есть кнопка просмотра вверху, но я не могу установить для нее идентификатор ответа. Поле идентификатора ответа в свойствах кнопки выделено серым цветом. Я попытался переместить все мои диалоговые виджеты в область действий, но это тоже не помогло.

Как мне заставить мою кнопку просмотра возвращать идентификатор ответа, не перемещая ее в нижнюю часть диалогового окна?

Редактировать:

Насколько я понимаю, диалоговые окна gtk не предназначены для работы с кнопками, если они не находятся внизу. Я решил отказаться от идеи диалога и вместо этого перейти к другому окну. Таким образом, я мог бы использовать существующий код для подключения событий кнопки…Я надеюсь.

Однако возникли проблемы с компиляцией следующего тестового приложения. Есть идеи, в чем проблема?

вывод на консоль:

 g   main.cpp examplewindow.cpp subwindow.cpp -o testsubwindow.exe -I . %GTKMM_INCLUDES% %GTKMM_LIBS%
AppDataLocalTempccekbJuk.o:examplewindow.cpp:(.text 0x1b0d):
undefined reference to `ExampleSubWindow::~ExampleSubWindow()'
AppDataLocalTempccekbJuk.o:examplewindow.cpp:(.text 0x1b1e):
undefined reference to `ExampleSubWindow::~ExampleSubWindow()'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:
LocalTempccekbJuk.o: bad reloc address 0xf in section `.text$_ZN
4sigc8internal8slot_repC2EPFPvS2_ES4_S4_[__ZN4sigc8internal8slot_repC2EPFPvS2_ES4_S4_]'
collect2.exe: error: ld returned 1 exit status
 

main.cpp:

 #include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv,     "org.gtkmm.example");

  ExampleWindow window;

  //Shows the window and returns when it is closed.
  return app->run(window);
}
 

examplewindow.h:

 #ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  void on_button_clicked();
  void on_button2_clicked();
  void on_about_dialog_response(int response_id);

  //Child widgets:
  Gtk::Box m_VBox;
  Gtk::Label m_Label;
  Gtk::ButtonBox m_ButtonBox;
  Gtk::ButtonBox m_ButtonBox2;
  Gtk::Button m_Button;
  Gtk::Button m_Button2;
  Gtk::Window m_SubWindow;
  Gtk::AboutDialog m_Dialog;
};

class ExampleSubWindow : public Gtk::Window
{
    public:
        ExampleSubWindow();
        virtual ~ExampleSubWindow();

    protected:
        void on_button3_clicked();

        Gtk::Box s_VBox;
        Gtk::ButtonBox s_ButtonBox3;
        Gtk::Button s_Button3;
};

#endif //GTKMM_EXAMPLEWINDOW_H
 

examplewindow.cpp:

 #include "examplewindow.h"
#include <iostream>

ExampleWindow::ExampleWindow()
: m_VBox(Gtk::ORIENTATION_VERTICAL),
  m_Label("The AboutDialog is non-modal. "
    "You can select parts of this text while the AboutDialog is shown."),
  m_ButtonBox(Gtk::ORIENTATION_VERTICAL),
  m_ButtonBox2(Gtk::ORIENTATION_VERTICAL),
  m_Button("Show AboutDialog"),
  m_Button2("Show SubWindow")
{
  set_title("Gtk::AboutDialog example");

  add(m_VBox);

  m_VBox.pack_start(m_Label);
  m_Label.set_line_wrap(true);
  m_Label.set_selectable(true);

  m_VBox.pack_start(m_ButtonBox);
  m_ButtonBox.pack_start(m_Button);
  m_Button.signal_clicked().connect(sigc::mem_fun(*this,
              amp;ExampleWindow::on_button_clicked) );

    m_VBox.pack_start(m_ButtonBox2);
    m_ButtonBox2.pack_start(m_Button2);
    m_Button2.signal_clicked().connect(sigc::mem_fun(*this,         amp;ExampleWindow::on_button2_clicked));

  m_Dialog.set_transient_for(*this);

  m_Dialog.set_program_name("Example application");
  m_Dialog.set_version("1.0.0");
  m_Dialog.set_copyright("Murray Cumming");
  m_Dialog.set_comments("This is just an example application.");
  m_Dialog.set_license("LGPL");

  m_Dialog.set_website("http://www.gtkmm.org");
  m_Dialog.set_website_label("gtkmm website");

  std::vector<Glib::ustring> list_authors;
  list_authors.push_back("Murray Cumming");
  list_authors.push_back("Somebody Else");
  list_authors.push_back("AN Other");
  m_Dialog.set_authors(list_authors);

  m_Dialog.signal_response().connect(
    sigc::mem_fun(*this, amp;ExampleWindow::on_about_dialog_response) );

  show_all_children();

  // The widget must be realized and mapped before grab_focus() is called.
  // That's why it's called after show_all_children().
  m_Button.grab_focus();
}

ExampleWindow::~ExampleWindow()
{

}

void ExampleWindow::on_about_dialog_response(int response_id)
{
  std::cout << response_id
    << ", close=" << Gtk::RESPONSE_CLOSE
    << ", cancel=" << Gtk::RESPONSE_CANCEL
    << ", delete_event=" << Gtk::RESPONSE_DELETE_EVENT
    << std::endl;

  if((response_id == Gtk::RESPONSE_CLOSE) ||
     (response_id == Gtk::RESPONSE_CANCEL) )
  {
    m_Dialog.hide();
  }
}

void ExampleWindow::on_button_clicked()
{
  m_Dialog.show();

  //Bring it to the front, in case it was already shown:
  m_Dialog.present();
}

void ExampleWindow::on_button2_clicked()
{
    ExampleSubWindow subWindow;
    subWindow.show();
}
 

subwindow.cpp

 #include "examplewindow.h"
#include <iostream>

ExampleSubWindow::ExampleSubWindow()
: s_VBox(Gtk::ORIENTATION_VERTICAL),
    s_ButtonBox3(Gtk::ORIENTATION_VERTICAL),
    s_Button3("Test activation")
{
    add(s_VBox);

    s_VBox.pack_start(s_ButtonBox3);

    s_ButtonBox3.pack_start(s_Button3);

    s_Button3.signal_clicked().connect(sigc::mem_fun(*this,
              amp;ExampleSubWindow::on_button3_clicked) );
}

void ExampleSubWindow::on_button3_clicked()
{
    std::cout << "Working yet?" << std::endl;
}
 

Редактировать: Неважно, я понял, что не так с моим маленьким проектом. Все еще не знаю, что не так с примером, но главное для меня — это то, что подокно необходимо создать с помощью «new», иначе оно будет немедленно удалено.

 ExampleSubWindow *subWindow = new ExampleSubWindow();
 

Ответ №1:

Неважно, я понял, что не так с моим маленьким проектом. Все еще не знаю, что не так с примером, но главное для меня — это то, что подокно должно быть создано с помощью «new», иначе оно будет немедленно удалено.

 ExampleSubWindow *subWindow = new ExampleSubWindow();
 

Комментарии:

1. ДА. И, конечно, вам нужно удалить его в какой-то момент. Возможно, было бы проще просто использовать его в качестве переменной-члена, как и другие виджеты.

Ответ №2:

Я думаю, что это ошибка в Glade. Gtk::Dialog в Glade имеет дочерний Gtk::Box, который, в свою очередь, имеет дочерний Gtk::ButtonBox. Если вы добавите Gtk::Button в поле ButtonBox, они позволят включить и установить идентификатор ответа. Если вы добавите Gtk ::Button в поле любым другим способом (напрямую или косвенно, например, добавив Gtk ::Grid в поле, а затем кнопки в эту сетку), Glade не позволит вам включить идентификатор ответа или задать значение.

Но, если вы сделаете это в XML, он будет функционировать должным образом. Например, я добавил кнопку в поле кнопок и установил ее идентификатор ответа. Я также добавил сетку в диалоговое окно, а затем кнопки в эту сетку (и, как уже отмечалось, не удалось включить идентификатор ответа). Я сохранил файл .glade, затем отредактировал его с помощью текстового редактора. Я перешел к свойству «action-widgets» диалогового окна и добавил дочерние элементы «action-widget», представляющие кнопки, которые я добавил в сетку. И это диалоговое окно работало нормально: (1) нажатие кнопки в поле кнопок работало так, как ожидалось, и (2) нажатие кнопок в сетке также работало так, как хотелось (диалоговое окно выдало сигнал «ответ», и был возвращен идентификатор ответа, который я вручную установил в файле .gladeиз Dialog.run()).