C++语言桌面应用开发GTK3 Gtkmm3 Glade

news/2024/9/25 8:27:51/

文章目录

  • Gikmm 简介
  • 安装 Gtkmm
  • 安装 GTK
  • 安装 Glade
  • demo.glade 文件
  • 完整示例 demo.cpp
  • 编译运行
  • GTK 主题
    • 推荐主题

Gikmm 简介

Gtkmm 是一个用于创建图形用户界面(GUI)的 C++ 库,它是基于流行的 GTK+ 库的。GTK+ 是一个跨平台的 GUI 工具包,广泛用于 Linux 和其他类 Unix 操作系统上的图形界面开发。Gtkmm 提供了对 GTK+ 库的 C++ 接口,使得开发者可以使用现代 C++ 的特性来构建应用程序。

  • Github:https://gitlab.gnome.org/GNOME/gtkmm
  • Gtkmm 文档:https://gnome.pages.gitlab.gnome.org/gtkmm/

安装 Gtkmm

brew install glibmm gtkmm3
# 列出库版本
brew list --versions glibmm gtkmm3
  • 验证安装
pkg-config --modversion gtkmm-3.0

在这里插入图片描述

安装 GTK

注: 版本兼容问题,gtk4 目前暂不支持 Glade 推荐安装 gtk3 版本。
gtk3 对应 gtkmm3 版本
gtk4 对应 gtkmm4 版本

xcode-select --install
brew install pkg-config
# pkgconfig 路径
find / -name pkgconfig
# 是否支持GTK+
brew search gtk
brew install gtk+3
# 验证 gtk+3
pkg-config --cflags --libs gtk+-3.0
  • 配置环境变量
# 检查 pkgconfig 路径
find / -name pkgconfig
# 将以上路径添加到环境变量中(.bash_profile 或 .zshrc)
vim ~/.zshrc
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH
source ~/.zshrc

安装 Glade

Glade是一个用于创建GTK图形用户界面的用户界面构建器。它允许开发者通过可视化方式设计和布局GUI元素,而不必手动编写代码。Glade生成XML格式的描述文件,描述了用户界面的结构和属性。然后,这个XML文件可以由程序加载和解释,从而创建用户界面。

  • Glade Github

    • https://github.com/GNOME/glade
    • https://gitlab.gnome.org/GNOME/glade
  • Glade 教程

    • https://developer.gnome.org/
  • 安装 Glade

# 目前版本支持gtk+3
brew install glade
glade --version
# 启动glade
glade
  • Glade 操作界面

在这里插入图片描述

保存后会生成如下 demo.glade 文件

demo.glade 文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface><requires lib="gtk+" version="3.24"/><object class="GtkWindow" id="window"><property name="width-request">400</property><property name="height-request">200</property><property name="can-focus">False</property><property name="title" translatable="yes">demo</property><child><object class="GtkBox" id="box"><property name="visible">True</property><property name="can-focus">False</property><property name="orientation">vertical</property><child><object class="GtkButton" id="button"><property name="label" translatable="yes">button</property><property name="visible">True</property><property name="can-focus">True</property><property name="receives-default">True</property><property name="margin-start">10</property><property name="margin-end">10</property><property name="margin-top">10</property><property name="margin-bottom">10</property></object><packing><property name="expand">False</property><property name="fill">True</property><property name="position">0</property></packing></child><child><object class="GtkComboBoxText" id="combobox"><property name="visible">True</property><property name="can-focus">False</property><property name="margin-start">10</property><property name="margin-end">10</property><property name="margin-top">10</property><property name="margin-bottom">10</property><property name="active">0</property><property name="active-id">1</property><items><item id="1" translatable="yes">item1</item><item id="2" translatable="yes">item2</item><item id="3" translatable="yes">item3</item><item id="4" translatable="yes">item4</item></items></object><packing><property name="expand">False</property><property name="fill">True</property><property name="position">1</property></packing></child><child><object class="GtkEntry" id="entry"><property name="visible">True</property><property name="can-focus">True</property><property name="margin-start">10</property><property name="margin-end">10</property><property name="margin-top">10</property><property name="margin-bottom">10</property></object><packing><property name="expand">False</property><property name="fill">True</property><property name="position">2</property></packing></child></object></child></object>
</interface>

完整示例 demo.cpp

注: gtkmm3 支持 .glade 文件。

#include <gtkmm-3.0/gtkmm/application.h>
#include <gtkmm-3.0/gtkmm/builder.h>
#include <gtkmm-3.0/gtkmm/button.h>
#include <gtkmm-3.0/gtkmm/combobox.h>
#include <gtkmm-3.0/gtkmm/entry.h>
#include <gtkmm-3.0/gtkmm/window.h>#include <iostream>namespace
{class MainWindow : public Gtk::Window{public:MainWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &builder);virtual ~MainWindow();private:Glib::RefPtr<Gtk::Builder> m_builder;Gtk::Button *button;Gtk::ComboBox *combobox;Gtk::Entry *entry;protected:void on_button_clicked(const Glib::ustring &id, const Glib::ustring &view);void on_combobox_changed(const Glib::ustring &id, const Glib::ustring &view);void on_entry_changed(const Glib::ustring &id, const Glib::ustring &view);void on_entry_activate(const Glib::ustring &id, const Glib::ustring &view);};MainWindow::MainWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &builder) : Gtk::Window(cobject), m_builder(builder){builder->get_widget("button", button);if (button){button->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_button_clicked), "button-clicked", ""));}builder->get_widget("combobox", combobox);if (combobox){combobox->signal_changed().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_combobox_changed), "combobox-changed", ""));}builder->get_widget("entry", entry);if (entry){entry->signal_changed().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_entry_changed), "entry-changed", ""));entry->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_entry_activate), "entry-activate", ""));}}void MainWindow::on_button_clicked(const Glib::ustring &id, const Glib::ustring &view){std::cout << id << " Hello World " << view << std::endl;}void MainWindow::on_combobox_changed(const Glib::ustring &id, const Glib::ustring &view){auto activeId = combobox->get_active_id();std::cout << id << " Selected item:" << ", active_id: " << activeId << std::endl;}void MainWindow::on_entry_changed(const Glib::ustring &id, const Glib::ustring &view){auto text = entry->get_buffer()->get_text();std::cout << id << " Entry Changed Text: " << text << std::endl;}void MainWindow::on_entry_activate(const Glib::ustring &id, const Glib::ustring &view){auto text = entry->get_buffer()->get_text();std::cout << id << " Entry Activate Text: " << text << std::endl;}MainWindow::~MainWindow(){}Gtk::Window *do_builder(){Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("demo.glade");MainWindow *main_win = nullptr;builder->get_widget_derived("window", main_win);// 设置窗口居中main_win->set_position(Gtk::WIN_POS_CENTER);// main_win->set_default_size(600, 400);// main_win->set_title("Hello World");// 设置窗口边框宽度// main_win->set_border_width(10);return main_win;}
}int main(int argc, char *argv[])
{Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv);Gtk::Window *main_win = do_builder();return app->run(*main_win);
}

编译运行

# 编译
g++ -o demo demo.cpp `pkg-config --cflags --libs gtkmm-3.0` -std=c++20
# 执行
./demo

在这里插入图片描述

GTK 主题

  • https://www.gnome-look.org/browse?cat=135&ord=latest

推荐主题

  • https://www.gnome-look.org/p/1403328

  • https://github.com/vinceliuice/WhiteSur-gtk-theme

  • https://www.gnome-look.org/p/1357889

  • https://github.com/vinceliuice/Orchis-theme

  • https://github.com/vinceliuice/Mojave-gtk-theme

  • https://github.com/paullinuxthemer/Prof-Gnome


http://www.ppmy.cn/news/1530208.html

相关文章

洛谷P2571.传送带

洛谷P2571.传送带 三分模板题 用于单峰函数求极值 一定可以将答案路径分成三段即AE - EF - FD (E和A可能重复&#xff0c;F和D可能重合) E在线段AB上&#xff0c;F在线段CD上 因为有两个不定点EF&#xff0c;因此假设E为参数&#xff0c;三分求F的位置再外层三分求E的位置 …

240924-Windows映射网络驱动器的方法

在Windows上加载网络盘&#xff08;映射网络驱动器&#xff09;可以通过以下步骤完成&#xff1a; 方法一&#xff1a;通过文件资源管理器 打开文件资源管理器&#xff1a; 可以按 Win E 打开&#xff0c;或者直接点击任务栏上的文件资源管理器图标。 点击“此电脑”&#x…

Java服务端服务发现:Nacos与Eureka的高级特性

Java服务端服务发现&#xff1a;Nacos与Eureka的高级特性 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在微服务架构中&#xff0c;服务发现是实现服务间通信的关键机制。Nacos和Eureka是两种…

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL18

实现3-8译码器① 描述 下表是74HC138译码器的功能表. E3 E2_n E1_n A2 A1 A0 Y0_n Y1_n Y2_n Y3_n Y4_n Y5_n Y6_n Y7_n x 1 x x x x 1 1 1 1 1 1 1 1 x x 1 x x x 1 1 1 1 1 1 1 1 0 x x x x x 1 1 1 1 1 1 1 1 1 …

鸿蒙OpenHarmony【小型系统内核(用户态启动)】子系统开发

用户态启动 用户态根进程启动 根进程是系统第一个用户态进程&#xff0c;进程ID为1&#xff0c;它是所有用户态进程的祖先。 图1 进程树示意图 根进程的启动过程 使用链接脚本将如下init启动代码放置到系统镜像指定位置。 #define LITE_USER_SEC_ENTRY __attribute__((s…

Ansible部署与应用基础

由于互联网的快速发展导致产品更新换代速度逐步增长&#xff0c;运维人员每天都要进行大量的维护操作&#xff0c;按照传统方式进行维护使得工作效率低下。这时部署自动化运维就 可以尽可能安全、高效的完成这些工作。 一、Ansible概述 1.什么是Ansible Ansible 是基于 Pytho…

Windows环境下Node.js多版本切换的实用指南

Web开发和全栈开发中&#xff0c;Node.js已成为不可或缺的工具之一。然而&#xff0c;随着项目的多样化和技术栈的更新迭代&#xff0c;我们可能需要同时管理多个Node.js版本以满足不同项目的需求。在Windows环境下&#xff0c;如何高效地切换这些版本成为了一个关键问题。简单…

React UI组件库推荐

Next UI&#xff1a;Vite | NextUI - Beautiful, fast and modern React UI Library Ant Design&#xff1a;Ant Design - 一套企业级 UI 设计语言和 React 组件库