C++ GTKMM/C++;11:如何用其他小部件创建自定义复合小部件?
我想派生我自己的小部件类,并将标准小部件添加到这个类中,以创建一个复合小部件。有没有人有关于如何做到这一点的例子或建议?例如,假设我想创建由4个按钮组成的自定义组合小部件。我猜它与下面的代码类似:C++ GTKMM/C++;11:如何用其他小部件创建自定义复合小部件?,c++,c++11,widget,gtkmm,gtkmm3,C++,C++11,Widget,Gtkmm,Gtkmm3,我想派生我自己的小部件类,并将标准小部件添加到这个类中,以创建一个复合小部件。有没有人有关于如何做到这一点的例子或建议?例如,假设我想创建由4个按钮组成的自定义组合小部件。我猜它与下面的代码类似: //First Question: Is this the best way to create composite widget? (see below) //Second Question: How do you make a widget container expand in // t
//First Question: Is this the best way to create composite widget? (see below)
//Second Question: How do you make a widget container expand in
// the horizontal direction while at the same time shrink in
// the vertical direction? because i wanted the boxes to expand horizontally
// to fill the window, and at the same time shrink to minimum width in the vertical
// direction
#include <iostream>
using namespace std;
#include <gtkmm.h>
class MyWidget : public Gtk::Frame {
public:
MyWidget() {
add(m_hbox1);
m_hbox1.pack_start (m_vbox1, Gtk::PackOptions::PACK_SHRINK);
m_vbox1.pack_start (m_hbox2, Gtk::PackOptions::PACK_EXPAND_WIDGET);
m_hbox2.pack_start (m_btn_fwd, Gtk::PackOptions::PACK_EXPAND_WIDGET);
m_hbox2.pack_start (m_btn_play, Gtk::PackOptions::PACK_EXPAND_WIDGET);
m_hbox2.pack_start (m_btn_stop, Gtk::PackOptions::PACK_EXPAND_WIDGET);
m_hbox2.pack_start (m_btn_back, Gtk::PackOptions::PACK_EXPAND_WIDGET);
show_all_children();
}
~MyWidget() {
}
private:
Gtk::Box m_vbox1 {Gtk::ORIENTATION_VERTICAL};
Gtk::Box m_hbox1 {Gtk::ORIENTATION_HORIZONTAL};
Gtk::Box m_hbox2 {Gtk::ORIENTATION_HORIZONTAL};
Gtk::Button m_btn_fwd {"Fwd"};
Gtk::Button m_btn_back {"Back"};
Gtk::Button m_btn_play {"Play"};
Gtk::Button m_btn_stop {"Stop"};
};
class MyWindow : public Gtk::Window {
public:
MyWindow(string name) {
set_title(name);
add(m_vbox);
// Shrink in Vertical Direction
m_vbox.pack_start(m_mywidget, Gtk::PackOptions::PACK_SHRINK);
show_all_children();
}
private:
Gtk::Box m_vbox {Gtk::ORIENTATION_VERTICAL};
MyWidget m_mywidget;
};
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv,
"org.gtkmm.example.actionbar");
MyWindow window {"Testing Custom Composite Widget"};
// Shows the window and returns when it is closed.
return app->run(window);
}
//第一个问题:这是创建复合小部件的最佳方法吗?(见下文)
//第二个问题:如何使小部件容器在中展开
//水平方向,同时收缩
//垂直方向?因为我想让盒子水平扩展
//填充窗口,同时在垂直方向收缩到最小宽度
//方向
#包括
使用名称空间std;
#包括
类MyWidget:publicGTK::Frame{
公众:
MyWidget(){
添加(m_hbox1);
m_hbox1.pack_启动(m_vbox1,Gtk::PackOptions::pack_收缩);
m_vbox1.pack_start(m_hbox2,Gtk::PackOptions::pack_EXPAND_小部件);
m_hbox2.pack_start(m_btn_fwd,Gtk::PackOptions::pack_EXPAND_小部件);
m_hbox2.pack_start(m_btn_play,Gtk::PackOptions::pack_EXPAND_小部件);
m_hbox2.pack_start(m_btn_stop,Gtk::PackOptions::pack_EXPAND_小部件);
m_hbox2.pack_start(m_btn_back,Gtk::PackOptions::pack_EXPAND_小部件);
显示所有子项();
}
~MyWidget(){
}
私人:
Gtk::Box m_vbox1{Gtk::ORIENTATION_VERTICAL};
Gtk::Box m_hbox1{Gtk::ORIENTATION_HORIZONTAL};
Gtk::Box m_hbox2{Gtk::方向_水平};
Gtk::按钮m_btn_fwd{“fwd”};
Gtk::按钮m_btn_back{“back”};
Gtk::按钮m_btn_play{“play”};
Gtk::按钮m_btn_停止{“停止”};
};
类MyWindow:公共Gtk::Window{
公众:
MyWindow(字符串名称){
设置标题(名称);
添加(m_vbox);
//垂直收缩
m_vbox.pack_start(m_mywidget,Gtk::PackOptions::pack_SHRINK);
显示所有子项();
}
私人:
Gtk::Box m_vbox{Gtk::ORIENTATION_VERTICAL};
MyWidget m_MyWidget;
};
int main(int argc,char*argv[])
{
自动应用程序=Gtk::应用程序::创建(argc、argv、,
“org.gtkmm.example.actionbar”);
MyWindow窗口{“测试自定义组合小部件”};
//显示窗口并在关闭时返回。
返回应用程序->运行(窗口);
}
经过几周的实验,我的结论是,最好避免使用C++来从GTK::WIDGET继承,以便创建复合控件。相反,最好在gktmm中将复合小部件作为纯容器类生成,即不从任何类派生,并重载C++11函子操作符以返回一个Gtk::Box小部件,该小部件由对象的构造函数预打包,包含生成复合组件所需的所有小部件。例如:
using namespace std;
#include <gtkmm.h>
#include <iostream>
//======================================================
// SearchBar: An Example GTKMM Composite Widget / wmoore
//======================================================
class SearchBar {
public:
SearchBar();
Gtk::Widget& operator()();
public:
Gtk::Box box {Gtk::ORIENTATION_HORIZONTAL};
Gtk::Label label {"search: "};
Gtk::Entry entry;
Gtk::Button BtnOk{"find"};
Gtk::Button BtnNext{">"};
Gtk::Button BtnPrev{"<"};
};
inline SearchBar::SearchBar() {
box.pack_start(label);
box.pack_start(entry, Gtk::PACK_EXPAND_WIDGET);
box.pack_end(BtnNext);
box.pack_end(BtnPrev);
box.pack_end(BtnOk);
}
inline Gtk::Widget& SearchBar::operator()() {
return box;
}
class MyWindow : public Gtk::Window {
public:
MyWindow(string name) {
set_title(name);
add(m_vbox);
// Shrink in Vertical Direction
m_vbox.pack_start(m_searchbar(), Gtk::PackOptions::PACK_SHRINK);
// ^^^ NOTE use of C++11 functor operator "()"
// added to end of object name
// that makes it easy to tell difference between
// Gtk::Widget and Composite widget's built
// from many Gtk::Widget's
////Example Connecting of Signals to composite widget:
// m_searchbar.BtnOk.signal_clicked.connect([]() {
// cout << "clicked button!\n";})
show_all_children();
}
private:
Gtk::Box m_vbox {Gtk::ORIENTATION_VERTICAL};
SearchBar m_searchbar;
};
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv,
"org.gtkmm.example.actionbar");
MyWindow window {"Testing Custom Composite Widget"};
// Shows the window and returns when it is closed.
return app->run(window);
}
使用名称空间std;
#包括
#包括
//======================================================
//搜索栏:一个示例GTKMM复合小部件/wmoore
//======================================================
类搜索栏{
公众:
搜索栏();
Gtk::Widget和operator();
公众:
Gtk::长方体{Gtk::方向_水平};
标签标签{“搜索:”};
Gtk::入口;
Gtk::按钮BtnOk{“find”};
Gtk::按钮BtnNext{“>”};
GTK::Button BtnPrev {“p>”,实际上可以从GTK:GTKMM中的GTK::WIDGET派生自定义的C++部件,虽然库需要相当多的附加代码,不仅用于合成复合文件,而且还用于遵循GTK::WIDGET接口规范。
我指的是一组虚拟方法,它们应该在您的实现中被覆盖,特别是:
- 获取请求模式\u vfunc():(可选)返回什么Gtk::SizeRequestMode
是小部件的首选
- 获取首选宽度\u vfunc():计算最小宽度和自然宽度
小部件的名称
- 获取首选高度(vfunc():计算最小和自然高度
小部件的高度
- 为高度vfunc()获取首选宽度:计算最小值和
小部件的自然宽度,如果将其指定为
高度
- 获取宽度vfunc()的首选高度::计算最小值和
小部件的自然高度,如果将其指定为
宽度
- on\u size\u allocate():根据高度和位置定位小部件
实际给定的宽度
- on_realize():将Gdk::窗口与小部件关联
- on_unreaze():(可选)断开与
Gdk::窗口
- 在地图上():(可选)
- 取消映射()上的:(可选)
- on_draw():在提供的Cairo::Context上绘制
gtkmm文档在gtkmm教程部分有一个很好的例子。operator Gtk::Widget&
比operator()更合适。