简单的应用程序

使用Gtk::Application时,main()函数可以非常简单。我们只是在应用程序类实例上调用Gtk::Application::run()

应用程序的所有逻辑都在应用程序类中,该类是Gtk::Application的子类。现在在我们的示例中还没有任何很有趣的功能。它要做的事就是在没有参数的情况下打开一个窗口,或在有参数的启动状态下打开给定的文件(准确的说我们的应用程序类尝试打开文件,但是应用程序的窗口子类并没有执行应执行的操作)。

为了处理这两种情况,我们覆写了signal_activate()signal_open()的默认处理函数,在没有命令行参数时前者的处理函数被调用,有命令行参数时后者的处理函数被调用。

Gio::Application参考

Gtk::Application参考

作为gtkmm应用程序支持的另一个重要的类是Gtk::ApplicationWindow。通常我们也会将其子类化。此时我们的子类还没有做任何事,所以我们只会得到一个空白的窗口。

作为应用程序初始设置的一部分,我们还为其创建了一个图标和桌面文件。请注意在使用这个桌面文件之前你还需要将文件中的@bindir@替换为应用程序二进制的实际路径。

到目前为止我们做到了:

Figure 29-1简单的应用程序

这看起来还无法让人印象深刻,但是我们的应用程序已经在会话总线上展示了自己。现在它具有单实例语义,并且接受命令行参数作为文件路径。

源代码

File: exampleapplication.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEAPPLICATION_H
#define GTKMM_EXAMPLEAPPLICATION_H

#include <gtkmm.h>

class ExampleAppWindow;

class ExampleApplication: public Gtk::Application
{
protected:
  ExampleApplication();

public:
  static Glib::RefPtr<ExampleApplication> create();

protected:
  // Override default signal handlers:
  void on_activate() override;
  void on_open(const Gio::Application::type_vec_files& files,
    const Glib::ustring& hint) override;

private:
  ExampleAppWindow* create_appwindow();
  void on_hide_window(Gtk::Window* window);
};

#endif /* GTKMM_EXAMPLEAPPLICATION_H */

File: exampleappwindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEAPPWINDOW_H_
#define GTKMM_EXAMPLEAPPWINDOW_H_

#include <gtkmm.h>

class ExampleAppWindow : public Gtk::ApplicationWindow
{
public:
  ExampleAppWindow();

  void open_file_view(const Glib::RefPtr<Gio::File>& file);
};

#endif /* GTKMM_EXAMPLEAPPWINDOW_H */

File: main.cc (For use with gtkmm 4)

#include "exampleapplication.h"

int main(int argc, char* argv[])
{
  auto application = ExampleApplication::create();

  // Start the application, showing the initial window,
  // and opening extra views for any files that it is asked to open,
  // for instance as a command-line parameter.
  // run() will return when the last window has been closed.
  return application->run(argc, argv);
}

File: exampleappwindow.cc (For use with gtkmm 4)

#include "exampleappwindow.h"

ExampleAppWindow::ExampleAppWindow()
: Gtk::ApplicationWindow()
{
}

void ExampleAppWindow::open_file_view(const Glib::RefPtr<Gio::File>& /* file */)
{
}

File: exampleapplication.cc (For use with gtkmm 4)

#include "exampleapplication.h"
#include "exampleappwindow.h"

ExampleApplication::ExampleApplication()
: Gtk::Application("org.gtkmm.examples.application", Gio::Application::Flags::HANDLES_OPEN)
{
}

Glib::RefPtr<ExampleApplication> ExampleApplication::create()
{
  return Glib::make_refptr_for_instance<ExampleApplication>(new ExampleApplication());
}

ExampleAppWindow* ExampleApplication::create_appwindow()
{
  auto appwindow = new ExampleAppWindow();

  // Make sure that the application runs for as long this window is still open.
  add_window(*appwindow);

  // A window can be added to an application with Gtk::Application::add_window()
  // or Gtk::Window::set_application(). When all added windows have been hidden
  // or removed, the application stops running (Gtk::Application::run() returns()),
  // unless Gio::Application::hold() has been called.

  // Delete the window when it is hidden.
  appwindow->signal_hide().connect(sigc::bind(sigc::mem_fun(*this,
    &ExampleApplication::on_hide_window), appwindow));

  return appwindow;
}

void ExampleApplication::on_activate()
{
  // The application has been started, so let's show a window.
  auto appwindow = create_appwindow();
  appwindow->present();
}

void ExampleApplication::on_open(const Gio::Application::type_vec_files& files,
  const Glib::ustring& /* hint */)
{
  // The application has been asked to open some files,
  // so let's open a new view for each one.
  ExampleAppWindow* appwindow = nullptr;
  auto windows = get_windows();
  if (windows.size() > 0)
    appwindow = dynamic_cast<ExampleAppWindow*>(windows[0]);

  if (!appwindow)
    appwindow = create_appwindow();

  for (const auto& file : files)
    appwindow->open_file_view(file);

  appwindow->present();
}

void ExampleApplication::on_hide_window(Gtk::Window* window)
{
  delete window;
}

File: exampleapp.desktop.in (For use with gtkmm 4)

[Desktop Entry]
Type=Application
Name=Gtkmm example
GenericName=Example
Comment=From the "Programming with gtkmm 4" tutorial
Icon=exampleapp
StartupNotify=true
Exec=@bindir@/exampleapp %U
Categories=GNOME;GTK;Utility