用 gtkmm 写 Hello World
目前我们已经可以自己所学的知识来写一个真正的程序了。根据计算机科学的传统,我们现在以 gtkmm 的方式来介绍 Hello World 程序:
File: helloworld.h (For use with gtkmm 3, not gtkmm 2)
#ifndef GTKMM_EXAMPLE_HELLOWORLD_H #define GTKMM_EXAMPLE_HELLOWORLD_H #include <gtkmm/button.h> #include <gtkmm/window.h> class HelloWorld : public Gtk::Window { public: HelloWorld(); virtual ~HelloWorld(); protected: //Signal handlers: void on_button_clicked(); //Member widgets: Gtk::Button m_button; }; #endif // GTKMM_EXAMPLE_HELLOWORLD_H
File: main.cc (For use with gtkmm 3, not gtkmm 2)
#include "helloworld.h" #include <gtkmm/application.h> int main (int argc, char *argv[]) { Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example"); HelloWorld helloworld; //Shows the window and returns when it is closed. return app->run(helloworld); }
File: helloworld.cc (For use with gtkmm 3, not gtkmm 2)
#include "helloworld.h" #include <iostream> HelloWorld::HelloWorld() : m_button("Hello World") // creates a new button with label "Hello World". { // Sets the border width of the window. set_border_width(10); // When the button receives the "clicked" signal, it will call the // on_button_clicked() method defined below. m_button.signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button_clicked)); // This packs the button into the Window (a container). add(m_button); // The final step is to display this newly created widget... m_button.show(); } HelloWorld::~HelloWorld() { } void HelloWorld::on_button_clicked() { std::cout << "Hello World" << std::endl; }
在继续讲解之前,可以尝试着编译并运行这个程序,你会看到这样的结果:
真让人激动,不是吗?让我们回过头来看一下代码。首先看一下 HelloWorld 类:
class HelloWorld : public Gtk::Window { public: HelloWorld(); virtual ~HelloWorld(); protected: //Signal handlers: virtual void on_button_clicked(); //Member widgets: Gtk::Button m_button; };
这个类实现了“Hello World”窗口。它由 Gtk::Window 派生,并且只有一个 Gtk::Button 成员。我们已经使用构造函数为该窗口完成了所有的初始化工作,包括挂接消息。在这,已经去掉注释的代码:
HelloWorld::HelloWorld() : m_button ("Hello World") { set_border_width(10); m_button.signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button_clicked)); add(m_button);. m_button.show(); }
注意,我们使用初始化列表的方式给 m_button 对象添加了一个“Hello World”的标签。
接下来调用 Windows 类的 set_border_width() 方法。设置窗口的边框和它所包含的组件之间的空白距离。
然后,把 m_button 的 clicked 消息挂接到信号处理函数上。这会向 stdout (标准输出) 打印出友好的问候语。
下一步,我们使用 Window 类的 add() 方法把 m_button 加到 Window 类中。(add() 方法由 Gtk::Container 类继承而来,我们将在容器组件这一章中具体介绍。) add() 方法仅仅将组件添加到窗口中,它并不负责显示这些组件。gtkmm 组件在创建以后都是不可见的。要显示它们,你必须调用 show() 方法,通常我们会在接下来的一行就调用它。
现在让我们来看看程序中没有注释过的 main() 函数:
int main(int argc, char** argv) { Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example"); HelloWorld helloworld; return app->run(helloworld); }
First we instantiate an object stored in a RefPtr smartpointer called app. This is of type Gtk::Application. Every gtkmm program must have one of these. We pass our command-line arguments to its create() method. It takes the arguments it wants, and leaves you the rest, as we described earlier.
Next we make an object of our HelloWorld class, whose constructor takes no arguments, but it isn't visible yet. When we callGtk::Application::run(), giving it the helloworld Window, it shows the Window and starts the gtkmm event loop. During the event loop gtkmm idles, waiting for actions from the user, and responding appropriately. When the user closes the Window, run() will return, causing the final line of our main() function be to executed. The application will then finish.