GTK与Qt项目工程融合实例

代码如下:


#include <gtk/gtk.h>
#include <QApplication>
#include <QMainWindow>
#include <QLabel>

enum
{
    COL_NAME = 0,
    COL_AGE,
    NUM_COLS
} ;

static GtkTreeModel *create_and_fill_model (void){
    GtkListStore *store;
    GtkTreeIter iter;
    store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT);
    /* Append a row and fill in some data */
    gtk_list_store_append (store, &iter);
    gtk_list_store_set (store, &iter,COL_NAME, "Heinz El-Mann",COL_AGE, 51,-1);
    /* append another row and fill in some data */
    gtk_list_store_append (store, &iter);
    gtk_list_store_set (store, &iter,COL_NAME, "Jane Doe",COL_AGE, 23,-1);
    /* ... and a third row */
    gtk_list_store_append (store, &iter);
    gtk_list_store_set (store, &iter,COL_NAME, "Joe Bungop",COL_AGE, 91,-1);
    return GTK_TREE_MODEL (store);
}

static GtkWidget *create_view_and_model (void){
    GtkCellRenderer *renderer;
    GtkTreeModel *model;
    GtkWidget *view;
    view = gtk_tree_view_new();
    /* --- Column #1 --- */
    renderer = gtk_cell_renderer_text_new ();
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),-1,"Name",renderer,"text", COL_NAME,NULL);
    /* --- Column #2 --- */
    renderer = gtk_cell_renderer_text_new ();
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),-1,"Age",renderer,"text", COL_AGE,NULL);
    model = create_and_fill_model ();
    gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
    /* The tree view has acquired its own reference to the
* model, so we can drop ours. That way the model will
* be freed automatically when the tree view is destroyed */
    g_object_unref (model);
    return view;
}

void GTK_WidgetInitShow(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *view;
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    g_signal_connect (window, "delete_event", gtk_main_quit, NULL); /* dirty */
    view = create_view_and_model();
    gtk_container_add (GTK_CONTAINER (window), view);
    gtk_widget_show_all (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
}

运行结果:

退出结果:

 

关系的Qt ***.pro文件,“授人鱼不如授人渔”,我将会对Qt针对融合任意第三方库(无论是C还是C++的库)进行Pro开发配置详细的理解,希望能够帮助到大家。

1、理清关系

      我们首先要理解到我们要融入Qt库是怎样的一个结构树,因为大家都知道每一个大型的工程都会根据一些模块生成一些文件夹,而这些文件夹却分级呈现了不同的模块和功能,比如内核中init文件夹就是存放内核启动文件,在Linux文件系统这个大应用下/etc/ /dev/ /home/ 等等。每一个好的开源源码或者安装包通常层次分明,而我们需要理清其中的关系。

      source/Include,通常代表头文件。也就是函数,变量,宏的定义头文件,这个在IDe中肯定是有用的,方便代码补全,如果你用的记事本或者Vim那么这个就不用要了,基本上开源软件系统这么多,你不可能都能熟知。

      source/lib,库文件目录,这里涵盖编译好的库文件,在GCC编译器这个体系中,最开始学习的无非就是gcc -g -o这样的命令,其实这在实际的生产过程中并不受用,比如开发一个大型的工程文件。里面涵盖成千上万的代码,那么 gcc -o,改一行便宜半个小时,开发效率呢?而lib 打成库文件这种就可以解决这样的问题,相当于把做好的不需要改的大量代码先进行Gcc处理。而编译器的最后一步就是ld链接,把你的文件和库文件链接成最终的execture(可执行文件)

      source/bin,执行文件和相关可执行组件的存放位置,这里的东西一般都是源码所带的一系列的工具。这个在现在的不是重点。在linux下涵盖ls命令这种东西。

       source/example,所带的官方源码示例程序,也并不是关心的内容。在IDE 搭建完成后可以打开观摩一下。通常示例可能比较复杂,或者是我太菜,我一般都是先官方下载手册,然后看看手册,示例源码这种在官网实在是没有手册和国内CSDN的搬运工没有资源的时候才会去看。

      。。。。。。。省略一些其他的文件夹

2.库文件通过什么方式来的?

      1. 直接安装,那么你肯定知道安装到哪了,这种一般都是大家熟知的库文件,在linux 的体系下一般都是入到系统环境中去了,gcc一般是能够找到的,在Windows下要指定安装目录,那么这个文件夹就是你的库文件所在的目录。直接安装还有一种就是带有pkg-config这种库索引工具的,命令  pkg-config --libs   gtk+-3.0  这种可以查看库文件链接命令。(本文的GTK就是pkg-config),具体的作用我会在此工程的Pro中解释。一般带有pkg-config工具源码的依赖关系比较复杂。

      2.Make install,这种也不用说了 参数  --profix=/xxx/  ,编译目录和安装目录都可以自己指定,所以你也能找到 Include 和 lib的位置。最后要记得看 README。

3.怎么配置我的Pro文件让工程里的文件引用外部库?

   下面贴上我的Pro:

#-------------------------------------------------
#
# Project created by QtCreator 2019-01-29T15:32:05
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MyExp2GTK
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

# 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

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

#HEADERS += \
#        mainwindow.h

#FORMS += \
#        mainwindow.ui

## Default rules for deployment.
#qnx: target.path = /tmp/$${TARGET}/bin
#else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target

大家可以自行创建GUI的hello world实例对比一下Pro,你会发现其实就只是多了,INCLUDEPATH +=和LIBS += 这两个关键字。

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可以先不加,然后IDE自动就报错了,报错的头文件引用#include <xxx.h>这样的头文件人后对应库的名称文件夹下,比如没有导入头路径D:/msys64/mingw64/include/gtk-3.0 ,在源码Main.cpp中#include <gtk/gtk.h>会提示找不到头文件,以此类推,挨个导入,如果依赖文件不多的话以也可以把源码安装包的所有头文件的目录加入进来。

那么我是怎么知道我需要这些Lib呢

        -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

     上面说过pkg-config --libs gtk+-3.0 然后就出来了,如下

注:其中有 -Wl,这种,不要加到Pro文件中来,因为这里的 LIBS+= 其实是链接的规则文件,会调用gcc 的ld组件进行库连接,如果参数不对就会便宜失败。这一点是从Qt终端打印得知

GCC工具的参数功能我就不再累赘了。我跨平台开发用的环境是Msys2+Mingw64。

按照上面的方法,基本上适用于所有的工程融合,不局限于qtcreator这一个IDE和Qt这一个框架。

GTK是基于C的 Qt是C++的,两者的机制不同。开发问题上应该注意C函数和类方法调用的顺序问题。

提一个题外话Qt下的mingw-gcc并不支持WebEngine。要玩Echats的只有转战Linux下了,Good Lucky。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值