使用按钮助记符不会更新第二个旋转按钮值
Using button mnemonic doesn't update second spinbutton value
我制作了一个示例 Gtk::Spinbutton
对话框程序,用户可以在其中修改 Width/Height 值并查看主 Gtk::Window
上输出的更改(文本)
我添加了两个按钮; 取消和确定,助记符开启set_use_underline()
出于测试目的,我假设用户正在修改这两个值。当我使用鼠标单击“确定”按钮时,程序运行良好。两个值都已更新。但是,当使用确定按钮助记符 (Alt + O
) 接受更改时,高度或宽度值无法正确更新。例如,在宽度字段中我输入 1366
,在高度字段中输入 768
,然后我点击 Alt + O
以激活确定按钮操作,更新宽度但不更新高度。相反,保留先前的高度值,在程序开始时为 1
.
核心class
- 声明
#ifndef WIDTHHEIGHT_H
#define WIDTHHEIGHT_H
class WidthHeight
{
int width, height;
public:
void set_width_core(int width = 1);
int get_width_core();
void set_height_core(int height = 1);
int get_height_core();
};
#endif // WIDTHHEIGHT_H
- 定义
#include "widthheight.h"
void WidthHeight::set_width_core(int width)
{
this->width = width;
}
int WidthHeight::get_width_core()
{
return width;
}
void WidthHeight::set_height_core(int height)
{
this->height = height;
}
int WidthHeight::get_height_core()
{
return height;
}
对话框class
- 声明
#ifndef WIDTHHEIGHTDIALOG_H
#define WIDTHHEIGHTDIALOG_H
#include <gtkmm/adjustment.h>
#include <gtkmm/dialog.h>
#include <gtkmm/label.h>
#include <gtkmm/spinbutton.h>
class WidthHeight;
class ExampleWindow;
class WidthHeightDialog : public Gtk::Dialog
{
WidthHeight &core;
ExampleWindow &window;
Gtk::Label width, height;
Glib::RefPtr<Gtk::Adjustment> w_adjustment, h_adjustment;
Gtk::SpinButton *w_entry, *h_entry;
enum response_id {
REJECT,
ACCEPT
};
void on_action_signal_response(int);
public:
WidthHeightDialog(WidthHeight &, ExampleWindow &);
};
#endif // WIDTHHEIGHTDIALOG_H
- 定义
#include <iostream>
#include "widthheightdialog.h"
#include "widthheight.h"
#include "examplewindow.h"
void WidthHeightDialog::on_action_signal_response(int id)
{
switch (id)
{
case Gtk::RESPONSE_CLOSE:
case response_id::REJECT:
std::cout << "Canceled\n";
break;
case response_id::ACCEPT:
std::cout << "OKayed\n";
break;
}
core.set_width_core(w_entry->get_value_as_int());
core.set_height_core(h_entry->get_value_as_int());
window.refresh_label();
std::cout << "Width: " << w_entry->get_value_as_int() << std::endl;
std::cout << "Height: " << h_entry->get_value_as_int() << std::endl;
hide();
}
WidthHeightDialog::WidthHeightDialog(WidthHeight &core, ExampleWindow &window)
: Dialog("Change Width/Height value")
, core(core)
, window(window)
, width("Width:")
, height("Height:")
, w_adjustment(Gtk::Adjustment::create(1, 1, 100000))
, h_adjustment(Gtk::Adjustment::create(1, 1, 100000))
, w_entry(manage(new Gtk::SpinButton(w_adjustment, 1, 0)))
, h_entry(manage(new Gtk::SpinButton(h_adjustment, 1, 0)))
{
auto box = get_content_area();
box->add(width);
box->add(*w_entry);
box->add(height);
box->add(*h_entry);
box->show_all();
add_button("_Cancel", response_id::REJECT)->set_use_underline();
add_button("_OK" , response_id::ACCEPT)->set_use_underline();
signal_response().connect(sigc::mem_fun(*this, &WidthHeightDialog::on_action_signal_response));
}
Window class
- 声明
#ifndef EXAMPLEWINDOW_H
#define EXAMPLEWINDOW_H
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <gtkmm/window.h>
#include "widthheight.h"
#include "widthheightdialog.h"
class ExampleWindow : public Gtk::Window
{
Gtk::Box vbox;
Gtk::Label label;
Gtk::Button button;
WidthHeight core;
WidthHeightDialog dialog;
void on_button_clicked();
public:
ExampleWindow();
void refresh_label();
};
#endif // EXAMPLEWINDOW_H
- 定义
#include "examplewindow.h"
void ExampleWindow::on_button_clicked()
{
dialog.show();
dialog.present();
}
ExampleWindow::ExampleWindow()
: vbox(Gtk::ORIENTATION_VERTICAL)
, label("\n\tOutput printed on console...\t\n")
, button("Change Width/Height value")
, dialog(core, *this)
{
set_title("Example");
add(vbox);
core.set_width_core();
core.set_height_core();
refresh_label();
vbox.pack_start(label);
label.set_line_wrap(true);
label.set_selectable(true);
vbox.pack_start(button);
button.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_button_clicked));
dialog.set_transient_for(*this);
show_all_children();
button.grab_focus();
}
void ExampleWindow::refresh_label()
{
std::string width = "\n Width: " + std::to_string(core.get_width_core()) + "\n";
std::string height = "Height: " + std::to_string(core.get_height_core()) + "\n";
label.set_text(width + height);
}
主要
#include <gtkmm/application.h>
#include "examplewindow.h"
int main()
{
auto app = Gtk::Application::create("org.gtkmm.example");
ExampleWindow window;
return app->run(window);
}
旋转框似乎有更新问题。例如,尝试以下操作:
- 启动应用程序。
- 修改宽度,然后修改高度。
- 在宽度编辑框内单击。
- 命中
Alt+O
。
在这种情况下,您会看到两个值都已更新(就像单击时一样)。我相信当你点击时,同样的事情会发生,但按钮。单击它相当于第 3 步(即将焦点放在另一个小部件上),这似乎会自动更新旋转框。
要解决此问题,您可以使用 Gtk::SpinButton::update()
方法强制更新旋转框。在您的情况下,您将拥有:
void WidthHeightDialog::on_action_signal_response(int id)
{
switch (id)
{
case Gtk::RESPONSE_CLOSE:
case response_id::REJECT:
std::cout << "Canceled\n";
break;
case response_id::ACCEPT:
std::cout << "OKayed\n";
break;
}
w_entry->update(); // Forces an update
h_entry->update(); // Forces an update
core.set_width_core(w_entry->get_value_as_int());
core.set_height_core(h_entry->get_value_as_int());
window.refresh_label();
std::cout << "Width: " << w_entry->get_value_as_int() << std::endl;
std::cout << "Height: " << h_entry->get_value_as_int() << std::endl;
hide();
}
这将确保对于两个旋转框,即使用户没有将焦点放在另一个小部件上(并因此触发对最后修改的旋转框的自动更新),更新仍然发生。
我制作了一个示例 Gtk::Spinbutton
对话框程序,用户可以在其中修改 Width/Height 值并查看主 Gtk::Window
我添加了两个按钮; 取消和确定,助记符开启set_use_underline()
出于测试目的,我假设用户正在修改这两个值。当我使用鼠标单击“确定”按钮时,程序运行良好。两个值都已更新。但是,当使用确定按钮助记符 (Alt + O
) 接受更改时,高度或宽度值无法正确更新。例如,在宽度字段中我输入 1366
,在高度字段中输入 768
,然后我点击 Alt + O
以激活确定按钮操作,更新宽度但不更新高度。相反,保留先前的高度值,在程序开始时为 1
.
核心class
- 声明
#ifndef WIDTHHEIGHT_H
#define WIDTHHEIGHT_H
class WidthHeight
{
int width, height;
public:
void set_width_core(int width = 1);
int get_width_core();
void set_height_core(int height = 1);
int get_height_core();
};
#endif // WIDTHHEIGHT_H
- 定义
#include "widthheight.h"
void WidthHeight::set_width_core(int width)
{
this->width = width;
}
int WidthHeight::get_width_core()
{
return width;
}
void WidthHeight::set_height_core(int height)
{
this->height = height;
}
int WidthHeight::get_height_core()
{
return height;
}
对话框class
- 声明
#ifndef WIDTHHEIGHTDIALOG_H
#define WIDTHHEIGHTDIALOG_H
#include <gtkmm/adjustment.h>
#include <gtkmm/dialog.h>
#include <gtkmm/label.h>
#include <gtkmm/spinbutton.h>
class WidthHeight;
class ExampleWindow;
class WidthHeightDialog : public Gtk::Dialog
{
WidthHeight &core;
ExampleWindow &window;
Gtk::Label width, height;
Glib::RefPtr<Gtk::Adjustment> w_adjustment, h_adjustment;
Gtk::SpinButton *w_entry, *h_entry;
enum response_id {
REJECT,
ACCEPT
};
void on_action_signal_response(int);
public:
WidthHeightDialog(WidthHeight &, ExampleWindow &);
};
#endif // WIDTHHEIGHTDIALOG_H
- 定义
#include <iostream>
#include "widthheightdialog.h"
#include "widthheight.h"
#include "examplewindow.h"
void WidthHeightDialog::on_action_signal_response(int id)
{
switch (id)
{
case Gtk::RESPONSE_CLOSE:
case response_id::REJECT:
std::cout << "Canceled\n";
break;
case response_id::ACCEPT:
std::cout << "OKayed\n";
break;
}
core.set_width_core(w_entry->get_value_as_int());
core.set_height_core(h_entry->get_value_as_int());
window.refresh_label();
std::cout << "Width: " << w_entry->get_value_as_int() << std::endl;
std::cout << "Height: " << h_entry->get_value_as_int() << std::endl;
hide();
}
WidthHeightDialog::WidthHeightDialog(WidthHeight &core, ExampleWindow &window)
: Dialog("Change Width/Height value")
, core(core)
, window(window)
, width("Width:")
, height("Height:")
, w_adjustment(Gtk::Adjustment::create(1, 1, 100000))
, h_adjustment(Gtk::Adjustment::create(1, 1, 100000))
, w_entry(manage(new Gtk::SpinButton(w_adjustment, 1, 0)))
, h_entry(manage(new Gtk::SpinButton(h_adjustment, 1, 0)))
{
auto box = get_content_area();
box->add(width);
box->add(*w_entry);
box->add(height);
box->add(*h_entry);
box->show_all();
add_button("_Cancel", response_id::REJECT)->set_use_underline();
add_button("_OK" , response_id::ACCEPT)->set_use_underline();
signal_response().connect(sigc::mem_fun(*this, &WidthHeightDialog::on_action_signal_response));
}
Window class
- 声明
#ifndef EXAMPLEWINDOW_H
#define EXAMPLEWINDOW_H
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <gtkmm/window.h>
#include "widthheight.h"
#include "widthheightdialog.h"
class ExampleWindow : public Gtk::Window
{
Gtk::Box vbox;
Gtk::Label label;
Gtk::Button button;
WidthHeight core;
WidthHeightDialog dialog;
void on_button_clicked();
public:
ExampleWindow();
void refresh_label();
};
#endif // EXAMPLEWINDOW_H
- 定义
#include "examplewindow.h"
void ExampleWindow::on_button_clicked()
{
dialog.show();
dialog.present();
}
ExampleWindow::ExampleWindow()
: vbox(Gtk::ORIENTATION_VERTICAL)
, label("\n\tOutput printed on console...\t\n")
, button("Change Width/Height value")
, dialog(core, *this)
{
set_title("Example");
add(vbox);
core.set_width_core();
core.set_height_core();
refresh_label();
vbox.pack_start(label);
label.set_line_wrap(true);
label.set_selectable(true);
vbox.pack_start(button);
button.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_button_clicked));
dialog.set_transient_for(*this);
show_all_children();
button.grab_focus();
}
void ExampleWindow::refresh_label()
{
std::string width = "\n Width: " + std::to_string(core.get_width_core()) + "\n";
std::string height = "Height: " + std::to_string(core.get_height_core()) + "\n";
label.set_text(width + height);
}
主要
#include <gtkmm/application.h>
#include "examplewindow.h"
int main()
{
auto app = Gtk::Application::create("org.gtkmm.example");
ExampleWindow window;
return app->run(window);
}
旋转框似乎有更新问题。例如,尝试以下操作:
- 启动应用程序。
- 修改宽度,然后修改高度。
- 在宽度编辑框内单击。
- 命中
Alt+O
。
在这种情况下,您会看到两个值都已更新(就像单击时一样)。我相信当你点击时,同样的事情会发生,但按钮。单击它相当于第 3 步(即将焦点放在另一个小部件上),这似乎会自动更新旋转框。
要解决此问题,您可以使用 Gtk::SpinButton::update()
方法强制更新旋转框。在您的情况下,您将拥有:
void WidthHeightDialog::on_action_signal_response(int id)
{
switch (id)
{
case Gtk::RESPONSE_CLOSE:
case response_id::REJECT:
std::cout << "Canceled\n";
break;
case response_id::ACCEPT:
std::cout << "OKayed\n";
break;
}
w_entry->update(); // Forces an update
h_entry->update(); // Forces an update
core.set_width_core(w_entry->get_value_as_int());
core.set_height_core(h_entry->get_value_as_int());
window.refresh_label();
std::cout << "Width: " << w_entry->get_value_as_int() << std::endl;
std::cout << "Height: " << h_entry->get_value_as_int() << std::endl;
hide();
}
这将确保对于两个旋转框,即使用户没有将焦点放在另一个小部件上(并因此触发对最后修改的旋转框的自动更新),更新仍然发生。