废话不多说,直接效果图先贴上:
用到的组件如下:
GtkLabel | 标签(同QLabel) |
GtkVBox | 横向布局(同QVboxLayout) |
GtkButtonBox | 按钮布局盒子 |
GtkFream | 边框修饰 |
GtkTable | 表格布局(同QGridLayout) |
GtkCheckButton | 点击按钮(同QCheckBox) |
GtkEntry | 文本编辑行(同QLineEdit) |
GtkButton | 按钮(同QPushButton) |
下面是源码程序(环境来自Qt5.11.2,我之前的博文提到过Qtcreator怎么配置Gtk的开发环境的)
#include <QApplication>
#include <gtk/gtk.h>
#include <QMainWindow>
#include <QLabel>
#include <QDebug>
#include <QList>
typedef struct
{
GtkWidget* G_lineedit;
GtkWidget* G_label;
}Transmit_Ds;
void clicked_OK(GtkWidget* _Sig_Instance,gpointer InstanceContainer)
{
const char* p=gtk_entry_get_text((GtkEntry*)((*((Transmit_Ds*)InstanceContainer)).G_lineedit));
gtk_label_set_label((GtkLabel*)((*((Transmit_Ds*)InstanceContainer)).G_label),p);
}
void GTK_WidgetInitShow(int argc, char *argv[])
{
gtk_init (&argc, &argv);
GdkColor color1;
color1.red = 0xffff;
color1.green = 0x0000;
color1.blue = 0x0000;
GdkColor color2;
color2.red = 0x0000;
color2.green = 0xffff;
color2.blue = 0x0000;
GtkWidget *G_f1label1 = gtk_label_new("Fream1Label");//布局范围测试Label1
GtkWidget *G_f1label2 = gtk_label_new("Fream2Label");//布局范围测试Label2
GtkWidget *G_f1vbox = gtk_vbox_new(TRUE,2);//测试Label布局容器
gtk_widget_modify_bg(G_f1label1,GTK_STATE_NORMAL, &color2);//设置G_f1label1组件颜色
gtk_widget_modify_bg(G_f1label2,GTK_STATE_NORMAL, &color1);//设置G_f1label2组件颜色
gtk_container_add(GTK_CONTAINER(G_f1vbox) ,G_f1label1);//纵向布局添加元素
gtk_container_add(GTK_CONTAINER(G_f1vbox) ,G_f1label2);//纵向布局添加元素
GtkWidget *G_frameInType = gtk_frame_new("freamIn");//边框修饰1
GtkWidget *G_frameOutType = gtk_frame_new("freamOut");//边框修饰2
GtkWidget *G_tabel = gtk_table_new(2,1,TRUE);//tabelLayout
GtkWidget *G_ButtonBox =gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);//按钮布局控件
GtkWidget *G_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);//Widget承载界面
GtkWidget *G_label = gtk_label_new("请输入内容");//输入显示label
GtkWidget *G_okbutton = gtk_button_new_with_label("Ok");//确认按钮
GtkWidget *G_closebutton = gtk_button_new_with_label("Close");//取消按钮
GtkWidget *G_vbox = gtk_vbox_new(TRUE,10);//纵向布局
GtkWidget *G_lineedit = gtk_entry_new();//编辑文本框
GtkWidget *G_checkbutton = gtk_check_button_new_with_label("check_button");//点击按钮
gtk_frame_set_shadow_type(GTK_FRAME(G_frameInType),GTK_SHADOW_IN);//边框修饰下效果内部阴影
gtk_frame_set_shadow_type(GTK_FRAME(G_frameOutType),GTK_SHADOW_ETCHED_OUT);//边框修饰下效果外部淡入阴影
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_frameInType,0,1,0,3);//空间添加布局
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_frameOutType,1,2,3,8);
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_f1vbox,0,1,1,3);
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_label,0,1,3,4);
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_lineedit,0,1,4,5);
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_checkbutton,0,1,5,6);
gtk_table_attach_defaults(GTK_TABLE(G_tabel),G_ButtonBox,0,1,6,7);
gtk_container_add(GTK_CONTAINER(G_ButtonBox) ,G_okbutton);//容器box布局
gtk_container_add(GTK_CONTAINER(G_ButtonBox) ,G_closebutton);
gtk_container_add(GTK_CONTAINER(G_vbox) ,G_tabel);//容器box布局
gtk_container_add(GTK_CONTAINER(G_window) ,G_vbox);//贴到承载类上
static Transmit_Ds TSDS;//参数结构体
TSDS.G_label=G_label;//地址赋值
TSDS.G_lineedit=G_lineedit;//地址赋值
qDebug()<<TSDS.G_label<<TSDS.G_lineedit<<&TSDS;
g_signal_connect(G_okbutton,"clicked",G_CALLBACK(clicked_OK),(gpointer)&TSDS);//OkbuttonClicked信号槽链接
g_signal_connect(G_window, "delete_event", gtk_main_quit, NULL);//删除事件信号槽链接
gtk_widget_show_all(G_window); //gtk_loop function
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv); //Qt-Gui入口函数
GTK_WidgetInitShow(argc,argv);//GTK-GUI入口函数
// QMainWindow w;
// QLabel* label=new QLabel("this Qt Label Widget",&w);
// w.show();
gtk_main(); //GTK return void
return a.exec(); //QT return int
}
在本文的实例中布局为如下关系:
有四个布局的控件(从外到内)分别是:
GtkVBox1和GtkVBox2同级,在源码中变量名称为(G_f1vbox、G_vbox)
在GtkVBox2(G_vbox)中存在控件GtkTable(G_tabel)
在GtkTable(G_tabel)中存在GtkButtonBox(G_ButtonBox)
GtkFream 控件只是修饰作用,并没有什么关乎任何控件的作用。
函数解析
gtk_widget_modify_bg() //设置控件的颜色
gtk_container_add() //设置子组件到布局容器内
gtk_frame_set_shadow_type()//设置GtkFream的边线样式
gtk_table_attach_defaults()//设置子组件到GtkTable中
g_signal_connect() //回调槽函数绑定
clicked_OK() //自定义槽函数
具体的函数用法可以直接百度出来。学过QtGui的读友可能学起GTK轻车熟路。
包括GTK里面尽量指针加上const和Static这种修饰符,避免程序在运行过程中自动更改。源码中槽函数传递到Clicked_OK()的参数
static Transmit_Ds TSDS;//参数结构体
TSDS.G_label=G_label;//地址赋值
TSDS.G_lineedit=G_lineedit;//地址赋值
qDebug()<<TSDS.G_label<<TSDS.G_lineedit<<&TSDS;
大家可以自行尝试把static去掉看看出现什么问题,我这边这个结构体的地址正确,而通过结构体地址解析里面组件的地址就会发生地址错乱,我也不太清楚这是什么问题,如果大家知道的评论一下,相互学习。
还有本人的代码写的比较烂,凑合着看吧,别骂街,手动[/滑稽]。
差点忘了一件事我的**.Pro文件:
#-------------------------------------------------
#
# Project created by QtCreator 2019-01-30T16:05:36
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Example3GW
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DEPRECATED_ERRORS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11 no_keywords
SOURCES += \
main.cpp
INCLUDEPATH +=\
D:/msys64/mingw64/include \
D:/msys64/mingw64/include/gtk-3.0 \
D:/msys64/mingw64/include/glib-2.0 \
D:/msys64/mingw64/lib/glib-2.0/include \
D:/msys64/mingw64/include/pango-1.0 \
D:/msys64/mingw64/include/cairo \
D:/msys64/mingw64/include/gdk-pixbuf-2.0 \
D:/msys64/mingw64/include/atk-1.0
LIBS +=\
-LD:/msys64/mingw64/lib \
-lgtk-3 -lgdk-3 -lgdi32 \
-limm32 -lshell32 -lole32 \
-luuid -lwinmm -ldwmapi \
-lsetupapi -lcfgmgr32 \
-lz -lpangowin32-1.0 \
-lpangocairo-1.0 -lpango-1.0 \
-latk-1.0 -lcairo-gobject -lcairo \
-lgdk_pixbuf-2.0 -lgio-2.0 \
-lgobject-2.0 -lglib-2.0 -lintl
## Default rules for deployment.
#qnx: target.path = /tmp/$${TARGET}/bin
#else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target