[GTK]界面输入框键盘

———————-.pro————————–
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport

INCLUDEPATH += /home/yue/openCV/install/include\
/home/yue/openCV/install/include/opencv4 \
/home/yue/openCV/install/include/opencv2

LIBS += /home/yue/openCV/install/lib/libopencv_highgui.so \
/home/yue/openCV/install/lib/libopencv_core.so \
/home/yue/openCV/install/lib/libopencv_imgproc.so \
/home/yue/openCV/install/lib/libopencv_imgcodecs.so

SOURCES += \
main.cpp

————————-main.cpp————————————-
#include

GtkWidget *inputA;
GtkWidget *inputC;
GtkWidget *stack; // 用于切换界面的 GtkStack

// 将字符添加到输入框C
void on_key_clicked(GtkWidget *widget, gpointer data) {
const gchar *text = gtk_button_get_label(GTK_BUTTON(widget));
const gchar *current_text = gtk_entry_get_text(GTK_ENTRY(data));
gchar *new_text = g_strconcat(current_text, text, NULL);
gtk_entry_set_text(GTK_ENTRY(data), new_text);
g_free(new_text); // 释放内存
}

// 删除字符
void on_backspace_clicked(GtkWidget *widget, gpointer data) {
const gchar *current_text = gtk_entry_get_text(GTK_ENTRY(data));
if (g_utf8_strlen(current_text, -1) > 0) {
gchar *new_text = g_utf8_substring(current_text, 0, g_utf8_strlen(current_text, -1) – 1);
gtk_entry_set_text(GTK_ENTRY(data), new_text);
g_free(new_text);
}
}

// 切换到界面B
void switch_to_B(GtkWidget *widget, gpointer data) {
gtk_stack_set_visible_child_name(GTK_STACK(stack), “界面B”);
}

// 切换回界面A
void switch_to_A(GtkWidget *widget, gpointer data) {
gtk_stack_set_visible_child_name(GTK_STACK(stack), “界面A”);
}

// 创建虚拟键盘
GtkWidget* create_keyboard(GtkWidget *input) {
GtkWidget *keyboard = gtk_grid_new();
gtk_grid_set_column_spacing(GTK_GRID(keyboard), 5);
gtk_grid_set_row_spacing(GTK_GRID(keyboard), 5);

// 定义键盘布局
const char *keys[4][10] = {
{“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “0”},
{“Q”, “W”, “E”, “R”, “T”, “Y”, “U”, “I”, “O”, “P”},
{“A”, “S”, “D”, “F”, “G”, “H”, “J”, “K”, “L”, “Backspace”},
{“Z”, “X”, “C”, “V”, “B”, “N”, “M”, “”, “”, “”}
};

// 添加按钮到键盘
for (int row = 0; row < 4; row++) { for (int col = 0; col < 10; col++) { if (keys[row][col][0] != '\0') { GtkWidget *key = gtk_button_new_with_label(keys[row][col]); // 根据按钮名称判断是否为 Backspace if (g_strcmp0(keys[row][col], "Backspace") == 0) { g_signal_connect(key, "clicked", G_CALLBACK(on_backspace_clicked), input); } else { g_signal_connect(key, "clicked", G_CALLBACK(on_key_clicked), input); } gtk_grid_attach(GTK_GRID(keyboard), key, col, row, 1, 1); } } } return keyboard; } // 主界面 int main(int argc, char *argv[]) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "合并界面"); gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); stack = gtk_stack_new(); // 界面A GtkWidget *boxA = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); inputA = gtk_entry_new(); gtk_widget_set_size_request(inputA, 100, 20); GtkWidget *buttonToB = gtk_button_new_with_label("切换到界面 B"); g_signal_connect(buttonToB, "clicked", G_CALLBACK(switch_to_B), NULL); gtk_box_pack_start(GTK_BOX(boxA), inputA, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(boxA), buttonToB, FALSE, FALSE, 0); gtk_stack_add_named(GTK_STACK(stack), boxA, "界面A"); // 界面B GtkWidget *boxB = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); inputC = gtk_entry_new(); gtk_widget_set_size_request(inputC, 100, 20); GtkWidget *keyboard = create_keyboard(inputC); gtk_box_pack_start(GTK_BOX(boxB), inputC, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(boxB), keyboard, TRUE, TRUE, 0); GtkWidget *buttonToA = gtk_button_new_with_label("切换到界面 A"); g_signal_connect(buttonToA, "clicked", G_CALLBACK(switch_to_A), NULL); gtk_box_pack_start(GTK_BOX(boxB), buttonToA, FALSE, FALSE, 0); gtk_stack_add_named(GTK_STACK(stack), boxB, "界面B"); // 添加 stack 到窗口 gtk_container_add(GTK_CONTAINER(window), stack); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }

[GTK]导入背景图片及图片,图片可拖动

——————————pro———————————-
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport

INCLUDEPATH += /home/yue/openCV/install/include\
/home/yue/openCV/install/include/opencv4 \
/home/yue/openCV/install/include/opencv2

LIBS += /home/yue/openCV/install/lib/libopencv_highgui.so \
/home/yue/openCV/install/lib/libopencv_core.so \
/home/yue/openCV/install/lib/libopencv_imgproc.so \
/home/yue/openCV/install/lib/libopencv_imgcodecs.so

SOURCES += \
main.cpp

—————————–main.cpp——————————
#include
#include
#include
#include // For std::min and std::max

using namespace cv;

// 窗口中的图片位置和缩放比例
static int img_x = 100;
static int img_y = 100;
static double scale = 1.0;
static int start_x = 0;
static int start_y = 0;
static bool dragging = false;
static bool in_image = false;
static Mat bg_img;
static Mat fg_img;

// 检查鼠标是否在图片范围内
bool is_mouse_in_image(int mouse_x, int mouse_y) {
return (mouse_x >= img_x && mouse_x <= (img_x + fg_img.cols * scale) && mouse_y >= img_y && mouse_y <= (img_y + fg_img.rows * scale)); } // 绘制图片到 GTK 窗口 static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr) { if (bg_img.empty() || fg_img.empty()) return FALSE; // 将背景图像转换为 Cairo 图像 GdkPixbuf *bg_pixbuf = gdk_pixbuf_new_from_data( (const guchar*)bg_img.data, GDK_COLORSPACE_RGB, false, 8, bg_img.cols, bg_img.rows, bg_img.step, NULL, NULL ); // 将前景图像转换为 Cairo 图像 GdkPixbuf *fg_pixbuf = gdk_pixbuf_new_from_data( (const guchar*)fg_img.data, GDK_COLORSPACE_RGB, false, 8, fg_img.cols, fg_img.rows, fg_img.step, NULL, NULL ); // 绘制背景图像 gdk_cairo_set_source_pixbuf(cr, bg_pixbuf, 0, 0); cairo_paint(cr); // 绘制前景图像,应用缩放比例 cairo_translate(cr, img_x, img_y); cairo_scale(cr, scale, scale); gdk_cairo_set_source_pixbuf(cr, fg_pixbuf, 0, 0); cairo_paint(cr); g_object_unref(bg_pixbuf); g_object_unref(fg_pixbuf); return FALSE; } // 处理鼠标按下事件 static gboolean on_button_press_event(GtkWidget *widget, GdkEventButton *event) { if (event->button == GDK_BUTTON_PRIMARY) {
if (in_image) {
dragging = true;
start_x = event->x – img_x;
start_y = event->y – img_y;
}
}
return FALSE;
}

// 处理鼠标释放事件
static gboolean on_button_release_event(GtkWidget *widget, GdkEventButton *event) {
if (event->button == GDK_BUTTON_PRIMARY) {
dragging = false;
}
return FALSE;
}

// 处理鼠标移动事件
static gboolean on_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
if (dragging) {
// 计算新的位置
int new_img_x = event->x – start_x;
int new_img_y = event->y – start_y;

// 限制图片B在背景图片A的范围内
new_img_x = std::max(0, std::min(new_img_x, bg_img.cols – static_cast(fg_img.cols * scale)));
new_img_y = std::max(0, std::min(new_img_y, bg_img.rows – static_cast(fg_img.rows * scale)));

img_x = new_img_x;
img_y = new_img_y;

gtk_widget_queue_draw(widget); // 触发重绘
} else {
in_image = is_mouse_in_image(event->x, event->y);
}
return FALSE;
}

// 缩放图片B
static void on_zoom_in(GtkWidget *widget, gpointer data) {
scale += 0.1;
gtk_widget_queue_draw(GTK_WIDGET(data));
}

static void on_zoom_out(GtkWidget *widget, gpointer data) {
scale = std::max(0.1, scale – 0.1);
gtk_widget_queue_draw(GTK_WIDGET(data));
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

// 加载背景图片
bg_img = imread(“/home/yue/xy.jpg”, IMREAD_COLOR);
if (bg_img.empty()) {
g_print(“Failed to load background image\n”);
return -1;
}

// 加载前景图片
fg_img = imread(“/home/yue/monkey.png”, IMREAD_COLOR);
if (fg_img.empty()) {
g_print(“Failed to load foreground image\n”);
return -1;
}

// 创建 GTK 窗口
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
GtkWidget *drawing_area = gtk_drawing_area_new();
GtkWidget *zoom_in_button = gtk_button_new_with_label(“Zoom In”);
GtkWidget *zoom_out_button = gtk_button_new_with_label(“Zoom Out”);

gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), zoom_in_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), zoom_out_button, FALSE, FALSE, 0);

gtk_widget_set_size_request(drawing_area, bg_img.cols, bg_img.rows);

// 连接绘制事件
g_signal_connect(G_OBJECT(drawing_area), “draw”, G_CALLBACK(on_draw_event), NULL);

// 连接鼠标事件
g_signal_connect(G_OBJECT(drawing_area), “button-press-event”, G_CALLBACK(on_button_press_event), NULL);
g_signal_connect(G_OBJECT(drawing_area), “button-release-event”, G_CALLBACK(on_button_release_event), NULL);
g_signal_connect(G_OBJECT(drawing_area), “motion-notify-event”, G_CALLBACK(on_motion_notify_event), NULL);

gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);

// 连接缩放按钮事件
g_signal_connect(G_OBJECT(zoom_in_button), “clicked”, G_CALLBACK(on_zoom_in), drawing_area);
g_signal_connect(G_OBJECT(zoom_out_button), “clicked”, G_CALLBACK(on_zoom_out), drawing_area);

g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);

gtk_widget_show_all(window);
gtk_main();

return 0;
}

[GTK]openCV导入图片,并且鼠标可拖动

——————————pro————————————-
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport

INCLUDEPATH += /home/yue/openCV/install/include\
/home/yue/openCV/install/include/opencv4 \
/home/yue/openCV/install/include/opencv2

LIBS += /home/yue/openCV/install/lib/libopencv_highgui.so \
/home/yue/openCV/install/lib/libopencv_core.so \
/home/yue/openCV/install/lib/libopencv_imgproc.so \
/home/yue/openCV/install/lib/libopencv_imgcodecs.so

SOURCES += \
main.cpp

—————–main.cpp——————————————
#include
#include
#include

using namespace cv;

// 窗口中的图片位置
static int img_x = 0;
static int img_y = 0;
static int start_x = 0;
static int start_y = 0;
static bool dragging = false;
static bool in_image = false;
static Mat img;

// 检查鼠标是否在图片范围内
bool is_mouse_in_image(int mouse_x, int mouse_y) {
return (mouse_x >= img_x && mouse_x <= (img_x + img.cols) && mouse_y >= img_y && mouse_y <= (img_y + img.rows)); } // 绘制图片到 GTK 窗口 static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr) { if (img.empty()) return FALSE; // 将 OpenCV Mat 转换为 Cairo 图像 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)img.data, GDK_COLORSPACE_RGB, false, 8, img.cols, img.rows, img.step, NULL, NULL ); // 在指定位置绘制图像 gdk_cairo_set_source_pixbuf(cr, pixbuf, img_x, img_y); cairo_paint(cr); g_object_unref(pixbuf); return FALSE; } // 处理鼠标按下事件 static gboolean on_button_press_event(GtkWidget *widget, GdkEventButton *event) { if (event->button == GDK_BUTTON_PRIMARY) {
if (in_image) {
// 记录开始拖动的位置
dragging = true;
start_x = event->x – img_x;
start_y = event->y – img_y;
}
}
return FALSE;
}

// 处理鼠标释放事件
static gboolean on_button_release_event(GtkWidget *widget, GdkEventButton *event) {
if (event->button == GDK_BUTTON_PRIMARY) {
dragging = false;
}
return FALSE;
}

// 处理鼠标移动事件
static gboolean on_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
if (dragging) {
// 计算新的位置
img_x = event->x – start_x;
img_y = event->y – start_y;
gtk_widget_queue_draw(widget); // 触发重绘
} else {
// 更新鼠标是否在图像上
in_image = is_mouse_in_image(event->x, event->y);
}
return FALSE;
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

// 加载图片
img = imread(“/home/yue/monkey.png”, IMREAD_COLOR);
if (img.empty()) {
g_print(“Failed to load image\n”);
return -1;
}

// 创建 GTK 窗口
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *drawing_area = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawing_area);
gtk_widget_set_size_request(drawing_area, 800, 600); // 设置绘图区的大小

// 连接绘制事件
g_signal_connect(G_OBJECT(drawing_area), “draw”, G_CALLBACK(on_draw_event), NULL);

// 连接鼠标事件
g_signal_connect(G_OBJECT(drawing_area), “button-press-event”, G_CALLBACK(on_button_press_event), NULL);
g_signal_connect(G_OBJECT(drawing_area), “button-release-event”, G_CALLBACK(on_button_release_event), NULL);
g_signal_connect(G_OBJECT(drawing_area), “motion-notify-event”, G_CALLBACK(on_motion_notify_event), NULL);

gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);

g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);

gtk_widget_show_all(window);
gtk_main();

return 0;
}

[GTK]openCV显示图片

————————–pro——————————————-
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport

INCLUDEPATH += /home/yue/openCV/install/include\
/home/yue/openCV/install/include/opencv4 \
/home/yue/openCV/install/include/opencv2

LIBS += /home/yue/openCV/install/lib/libopencv_highgui.so \
/home/yue/openCV/install/lib/libopencv_core.so \
/home/yue/openCV/install/lib/libopencv_imgproc.so \
/home/yue/openCV/install/lib/libopencv_imgcodecs.so

SOURCES += \
main.cpp

—————————main.cpp————————————
#include
#include
#include

// Function to convert OpenCV Mat to GdkPixbuf
GdkPixbuf* mat_to_pixbuf(const cv::Mat& mat) {
int width = mat.cols;
int height = mat.rows;
int stride = width * 3; // Assuming 3 channels (RGB)

// Create a GdkPixbuf with the same size as the OpenCV Mat
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(
mat.data,
GDK_COLORSPACE_RGB,
false,
8,
width,
height,
stride,
NULL,
NULL
);

return pixbuf;
}

// Callback function to load and display an image
void on_load_image(GtkButton *button, gpointer user_data) {
GtkWidget *image_widget = GTK_WIDGET(user_data);

// Load image using OpenCV
cv::Mat img = cv::imread(“/home/yue/monkey.png”); // Change to your image file

if (img.empty()) {
g_print(“Failed to load image.\n”);
return;
}

// Convert OpenCV Mat to GdkPixbuf
GdkPixbuf *pixbuf = mat_to_pixbuf(img);

// Set the image in the GTK image widget
gtk_image_set_from_pixbuf(GTK_IMAGE(image_widget), pixbuf);

// Unreference the GdkPixbuf when done
g_object_unref(pixbuf);
}

// Main function
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *image;
GtkWidget *button;

// Initialize GTK
gtk_init(&argc, &argv);

// Create a new GTK window
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), “GTK + OpenCV Example”);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);

// Set up a signal handler to exit the program when the window is closed
g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);

// Create a vertical box to hold widgets
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(window), vbox);

// Create an image widget
image = gtk_image_new();
gtk_box_pack_start(GTK_BOX(vbox), image, TRUE, TRUE, 0);

// Create a button to load the image
button = gtk_button_new_with_label(“Load Image”);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);

// Connect the button click signal to the callback function
g_signal_connect(button, “clicked”, G_CALLBACK(on_load_image), image);

// Show all widgets in the window
gtk_widget_show_all(window);

// Enter the GTK main loop
gtk_main();

return 0;
}

[GTK]简单下拉菜单程序

——————–pro——————————-
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport
SOURCES += \
main.cpp

———————–main.cpp————————————–
#include

// Callback function for when the selected item in the combo box changes
void on_combobox_changed(GtkComboBox *combobox, gpointer user_data) {
gchar *selected_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combobox));
if (selected_text) {
g_print(“Selected item: %s\n”, selected_text);
g_free(selected_text); // Free the string after use
}
}

// Main function
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *combobox;
GtkWidget *label;

// Initialize GTK
gtk_init(&argc, &argv);

// Create a new GTK window
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), “GTK ComboBox Example”);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);

// Set up a signal handler to exit the program when the window is closed
g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);

// Create a vertical box to hold widgets
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(window), vbox);

// Create a label
label = gtk_label_new(“Select an item from the combo box:”);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);

// Create a combo box with text items
combobox = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), “Option 1”);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), “Option 2”);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), “Option 3”);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), “Option 4”);
gtk_box_pack_start(GTK_BOX(vbox), combobox, FALSE, FALSE, 5);

// Connect the “changed” signal to the callback function
g_signal_connect(combobox, “changed”, G_CALLBACK(on_combobox_changed), NULL);

// Show all widgets in the window
gtk_widget_show_all(window);

// Enter the GTK main loop
gtk_main();

return 0;
}

[GTK]切换界面

——————————pro—————————————–
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport
SOURCES += \
main.cpp
———————————main.cpp——————————–
#include

// 函数声明
void on_button1_clicked(GtkButton *button, GtkStack *stack);
void on_button2_clicked(GtkButton *button, GtkStack *stack);

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

// 创建主窗口
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), “GTK 切换界面示例”);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);

// 创建主容器
GtkWidget *main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(window), main_box);

// 创建一个 GtkStack
GtkWidget *stack = gtk_stack_new();
gtk_box_pack_start(GTK_BOX(main_box), stack, TRUE, TRUE, 0);

// 创建界面1
GtkWidget *page1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
GtkWidget *button1 = gtk_button_new_with_label(“切换到界面2”);
g_signal_connect(button1, “clicked”, G_CALLBACK(on_button1_clicked), stack);
gtk_box_pack_start(GTK_BOX(page1), button1, TRUE, TRUE, 0);
gtk_stack_add_named(GTK_STACK(stack), page1, “page1”);

// 创建界面2
GtkWidget *page2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
GtkWidget *button2 = gtk_button_new_with_label(“切换到界面1”);
g_signal_connect(button2, “clicked”, G_CALLBACK(on_button2_clicked), stack);
gtk_box_pack_start(GTK_BOX(page2), button2, TRUE, TRUE, 0);
gtk_stack_add_named(GTK_STACK(stack), page2, “page2”);

// 创建 GtkStackSwitcher
GtkWidget *stack_switcher = gtk_stack_switcher_new();
gtk_box_pack_start(GTK_BOX(main_box), stack_switcher, FALSE, FALSE, 0);

// 将 GtkStackSwitcher 与 GtkStack 关联
gtk_stack_switcher_set_stack(GTK_STACK_SWITCHER(stack_switcher), GTK_STACK(stack));

// 显示所有组件
gtk_widget_show_all(window);

// 运行 GTK 主循环
gtk_main();

return 0;
}

// 切换到界面2的回调函数
void on_button1_clicked(GtkButton *button, GtkStack *stack) {
gtk_stack_set_visible_child_name(GTK_STACK(stack), “page2”);
}

// 切换到界面1的回调函数
void on_button2_clicked(GtkButton *button, GtkStack *stack) {
gtk_stack_set_visible_child_name(GTK_STACK(stack), “page1”);
}

[GTK]创建线程,点击按键后开启线程,显示进程ID号和运行的核

—————–pro————————————
INCLUDEPATH += /usr/include/gtk-3.0 \
/usr/include/at-spi2-atk/2.0 \
/usr/include/at-spi-2.0 \
/usr/include/dbus-1.0 \
/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
/usr/include/gtk-3.0 /usr/include/gio-unix-2.0 \
/usr/include/cairo /usr/include/pango-1.0 \
/usr/include/harfbuzz \
/usr/include/pango-1.0 \
/usr/include/fribidi \
/usr/include/harfbuzz \
/usr/include/atk-1.0 \
/usr/include/cairo \
/usr/include/pixman-1 \
/usr/include/uuid \
/usr/include/freetype2 \
/usr/include/gdk-pixbuf-2.0 \
/usr/include/libpng16 \
/usr/include/x86_64-linux-gnu \
/usr/include/libmount \
/usr/include/blkid \
/usr/include/glib-2.0 \
/usr/lib/x86_64-linux-gnu/glib-2.0/include\
/usr/include/

LIBS += -pthread \
-pthread \
-lgtk-3 \
-lgdk-3 \
-lpangocairo-1.0 \
-lpango-1.0 \
-lharfbuzz \
-latk-1.0 \
-lcairo-gobject \
-lcairo \
-lgdk_pixbuf-2.0 \
-lgio-2.0 \
-lgobject-2.0 \
-lglib-2.0 \
-lserialport
SOURCES += \
main.cpp

————————–main.cpp——————————–
#define _GNU_SOURCE
#include
#include
#include // 用于sched_getcpu()

// 更新主界面标签的函数(在主线程中调用)
gboolean update_label(gpointer user_data) {
GtkWidget *label = (GtkWidget *)user_data;

// 获取当前 CPU 核编号
int cpu = sched_getcpu();
gchar *text = g_strdup_printf(“线程在 CPU 核 %d 上运行”, cpu);

gtk_label_set_text(GTK_LABEL(label), text);
g_free(text);

return FALSE; // 返回 FALSE 表示不重复调用
}

// 后台线程函数
gpointer thread_function(gpointer user_data) {
GtkWidget *label = (GtkWidget *)user_data;
while (1)
{
g_print(“后台线程 ID: %p\n”, g_thread_self());

// 模拟耗时任务
g_usleep(2000000); // 休眠2秒

// 任务完成后,使用 g_idle_add 将更新操作发送到主线程
g_idle_add(update_label, label);
}

return NULL;
}

// “开始任务”按钮点击事件的处理函数
void on_button_clicked(GtkButton *button, gpointer user_data) {
GtkWidget *label = (GtkWidget *)user_data;

// 创建一个后台线程来执行任务
g_thread_new(“worker-thread”, thread_function, label);
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

// 初始化 GTK 界面
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), “GTK 多线程示例”);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
g_signal_connect(window, “destroy”, G_CALLBACK(gtk_main_quit), NULL);

GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(window), vbox);

GtkWidget *label = gtk_label_new(“等待任务…”);
gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);

GtkWidget *button = gtk_button_new_with_label(“开始任务”);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
g_signal_connect(button, “clicked”, G_CALLBACK(on_button_clicked), label);

gtk_widget_show_all(window);
gtk_main();

return 0;
}