Windows下GTK+3.X开发应用实例及打包发布

xingyun86 2020-1-21 2103

1.搭建开发环境

见http://www.ppsbbs.tech/thread-504.htm

安装环境目录为: D:\software\msys64

2.编写示例代码

test.c

#include <stdlib.h>
#include <gtk/gtk.h>
#include <math.h>

#define BACKGROUND_NAME "/pixbufs/background.jpg"

static const char *image_names[] = {
  "/pixbufs/apple-red.png",
  "/pixbufs/gnome-applets.png",
  "/pixbufs/gnome-calendar.png",
  "/pixbufs/gnome-foot.png",
  "/pixbufs/gnome-gmush.png",
  "/pixbufs/gnome-gimp.png",
  "/pixbufs/gnome-gsame.png",
  "/pixbufs/gnu-keys.png"
};

#define N_IMAGES G_N_ELEMENTS (image_names)

/* demo window */
static GtkWidget *window = NULL;

/* Current frame */
static GdkPixbuf *frame;

/* Background image */
static GdkPixbuf *background;
static gint back_width, back_height;

/* Images */
static GdkPixbuf *images[N_IMAGES];

/* Widgets */
static GtkWidget *da;

/* Loads the images for the demo and returns whether the operation succeeded */
static gboolean
load_pixbufs (GError **error)
{
  gint i;

  if (background)
    return TRUE; /* already loaded earlier */

  background = gdk_pixbuf_new_from_resource (BACKGROUND_NAME, error);
  if (!background)
    return FALSE; /* Note that "error" was filled with a GError */

  back_width = gdk_pixbuf_get_width (background);
  back_height = gdk_pixbuf_get_height (background);

  for (i = 0; i < N_IMAGES; i++)
    {
      images[i] = gdk_pixbuf_new_from_resource (image_names[i], error);

      if (!images[i])
        return FALSE; /* Note that "error" was filled with a GError */
    }

  return TRUE;
}

/* Expose callback for the drawing area */
static gint
draw_cb (GtkWidget *widget,
         cairo_t   *cr,
         gpointer   data)
{
  gdk_cairo_set_source_pixbuf (cr, frame, 0, 0);
  cairo_paint (cr);

  return TRUE;
}

#define CYCLE_TIME 3000000 /* 3 seconds */

static gint64 start_time;

/* Handler to regenerate the frame */
static gboolean
on_tick (GtkWidget     *widget,
         GdkFrameClock *frame_clock,
         gpointer       data)
{
  gint64 current_time;
  double f;
  int i;
  double xmid, ymid;
  double radius;

  gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height,
                        frame, 0, 0);

  if (start_time == 0)
    start_time = gdk_frame_clock_get_frame_time (frame_clock);

  current_time = gdk_frame_clock_get_frame_time (frame_clock);
  f = ((current_time - start_time) % CYCLE_TIME) / (double)CYCLE_TIME;

  xmid = back_width / 2.0;
  ymid = back_height / 2.0;

  radius = MIN (xmid, ymid) / 2.0;

  for (i = 0; i < N_IMAGES; i++)
    {
      double ang;
      int xpos, ypos;
      int iw, ih;
      double r;
      GdkRectangle r1, r2, dest;
      double k;

      ang = 2.0 * G_PI * (double) i / N_IMAGES - f * 2.0 * G_PI;

      iw = gdk_pixbuf_get_width (images[i]);
      ih = gdk_pixbuf_get_height (images[i]);

      r = radius + (radius / 3.0) * sin (f * 2.0 * G_PI);

      xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5);
      ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5);

      k = (i & 1) ? sin (f * 2.0 * G_PI) : cos (f * 2.0 * G_PI);
      k = 2.0 * k * k;
      k = MAX (0.25, k);

      r1.x = xpos;
      r1.y = ypos;
      r1.width = iw * k;
      r1.height = ih * k;

      r2.x = 0;
      r2.y = 0;
      r2.width = back_width;
      r2.height = back_height;

      if (gdk_rectangle_intersect (&r1, &r2, &dest))
        gdk_pixbuf_composite (images[i],
                              frame,
                              dest.x, dest.y,
                              dest.width, dest.height,
                              xpos, ypos,
                              k, k,
                              GDK_INTERP_NEAREST,
                              ((i & 1)
                               ? MAX (127, fabs (255 * sin (f * 2.0 * G_PI)))
                               : MAX (127, fabs (255 * cos (f * 2.0 * G_PI)))));
    }

  gtk_widget_queue_draw (da);

  return G_SOURCE_CONTINUE;
}

GtkWidget *
do_pixbufs (GtkWidget *do_widget)
{
  if (!window)
    {
      GError *error;

      window = gtk_window_new (GTK_WINDOW_TOPLEVEL)
      gtk_window_set_title (GTK_WINDOW (window), "Pixbufs");
      gtk_window_set_resizable (GTK_WINDOW (window), FALSE)
      //当窗口即将被销毁,停止主GTK+循环  
      g_signal_connect(window, "destroy",G_CALLBACK (gtk_main_quit), NULL);  

      error = NULL;
      if (!load_pixbufs (&error))
        {
          GtkWidget *dialog;

          dialog = gtk_message_dialog_new (GTK_WINDOW (window),
                                           GTK_DIALOG_DESTROY_WITH_PARENT,
                                           GTK_MESSAGE_ERROR,
                                           GTK_BUTTONS_CLOSE,
                                           "Failed to load an image: %s",
                                           error->message);

          g_error_free (error);

          g_signal_connect (dialog, "response",
                            G_CALLBACK (gtk_widget_destroy), NULL);

          gtk_widget_show (dialog);
        }
      else
        {
          gtk_widget_set_size_request (window, back_width, back_height);

          frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);

          da = gtk_drawing_area_new ();

          g_signal_connect (da, "draw",
                            G_CALLBACK (draw_cb), NULL);

          gtk_container_add (GTK_CONTAINER (window), da);

          gtk_widget_add_tick_callback (da, on_tick, NULL, NULL);
        }
    }

  gtk_widget_show_all (window)

  return window;
}

int main(int argc, char ** argv)
{  
    putenv("XDG_DATA_DIRS=share");//此处环境变量设置非常重要,同编译脚本相呼应
    putenv("GDK_PIXBUF_MODULEDIR=lib/gdk-pixbuf-2.0/2.10.0/loaders");//此处环境变量设置非常重要,同编译脚本相呼应
    putenv("GDK_PIXBUF_MODULE_FILE=lib/gdk-pixbuf-2.0/2.10.0/loaders.cache");//此处环境变量设置非常重要,同编译脚本相呼应
    //初始化GTK+库  
    gtk_init(&argc, &argv);  
    do_pixbufs(NULL);    
    //开始主循环,让它在那里休息,直到应用程序关闭  
    gtk_main();  
return 0;
}

3.编译脚本

build.sh

#!/bin/sh
export app=gtkgui
export outdir=${app}.out
export bin=${app}.exe
export res=${app}-gresource
export res_c=${res}.c
export res_h=${res}.h
export res_x=${app}.gresource.xml
mkdir -p ${outdir}
rm -rf  ${res_c}
rm -rf  ${res_h}
echo "clean up ${res_c} ${res_h}"
rm -rf  ${bin}
echo "clean up ${bin}"
echo "compiling ${res_c}"
glib-compile-resources --target=${res_c} --generate-source ${res_x}
mv ${res_c} ${outdir}/${res_c}
echo "compile ${res_c} ok"
echo "compiling ${res_h}"
glib-compile-resources --target=${res_h} --generate-header ${res_x}
mv ${res_h} ${outdir}/${res_h}
echo "compile ${res_h} ok"
echo "compiling ${bin}"
gcc ${app}.c ${outdir}/${res_c} -s -o2 -Wl,-subsystem,windows -o ${bin} `pkg-config --cflags --libs gtk+-3.0 glib-2.0 gio-2.0` 
#gcc ${app}.c ${outdir}/${res_c} -o ${bin} `pkg-config --cflags --libs gtk+-3.0 glib-2.0 gio-2.0` 
echo "compile ${bin} ok"
echo "packagling ${app}"
mv ${bin} ${outdir}
cp /mingw64/bin/libasprintf*.dll ${outdir} -f
cp /mingw64/bin/libatk*.dll ${outdir} -f
cp /mingw64/bin/libbz2*.dll ${outdir} -f
cp /mingw64/bin/libcairo*.dll ${outdir} -f
cp /mingw64/bin/libcharset*.dll ${outdir} -f
cp /mingw64/bin/libcroco*.dll ${outdir} -f
cp /mingw64/bin/libcrypto*.dll ${outdir} -f
cp /mingw64/bin/libdatrie*.dll ${outdir} -f
cp /mingw64/bin/libepoxy*.dll ${outdir} -f
cp /mingw64/bin/libexpat*.dll ${outdir} -f
cp /mingw64/bin/libffi*.dll ${outdir} -f
cp /mingw64/bin/libfontconfig*.dll ${outdir} -f
cp /mingw64/bin/libfreeglut*.dll ${outdir} -f
cp /mingw64/bin/libfreetype*.dll ${outdir} -f
cp /mingw64/bin/libfribidi*.dll ${outdir} -f
cp /mingw64/bin/libgailutil*.dll ${outdir} -f
cp /mingw64/bin/libgcc*.dll ${outdir} -f
cp /mingw64/bin/libgdk*.dll ${outdir} -f
cp /mingw64/bin/libgettext*.dll ${outdir} -f
cp /mingw64/bin/libgio*.dll ${outdir} -f
cp /mingw64/bin/libglib*.dll ${outdir} -f
cp /mingw64/bin/libgmodule*.dll ${outdir} -f
cp /mingw64/bin/libgobject*.dll ${outdir} -f
cp /mingw64/bin/libgraphite*.dll ${outdir} -f
cp /mingw64/bin/libgthread*.dll ${outdir} -f
cp /mingw64/bin/libgtk*.dll ${outdir} -f
cp /mingw64/bin/libharfbuzz*.dll ${outdir} -f
cp /mingw64/bin/libiconv*.dll ${outdir} -f
cp /mingw64/bin/libintl*.dll ${outdir} -f
cp /mingw64/bin/libjasper*.dll ${outdir} -f
cp /mingw64/bin/libjpeg*.dll ${outdir} -f
cp /mingw64/bin/libpango*.dll ${outdir} -f
cp /mingw64/bin/libpcre*.dll ${outdir} -f
cp /mingw64/bin/libpixman*.dll ${outdir} -f
cp /mingw64/bin/libpng*.dll ${outdir} -f
cp /mingw64/bin/libssl*.dll ${outdir} -f
cp /mingw64/bin/libstdc++*.dll ${outdir} -f
cp /mingw64/bin/libthai*.dll ${outdir} -f
cp /mingw64/bin/libtiff*.dll ${outdir} -f
cp /mingw64/bin/libturbojpeg*.dll ${outdir} -f
cp /mingw64/bin/libwinpthread*.dll ${outdir} -f
cp /mingw64/bin/libxml*.dll ${outdir} -f
cp /mingw64/bin/zlib*.dll ${outdir} -f
mkdir -p ${outdir}/lib/gdk-pixbuf-2.0/2.10.0/loaders
cp /mingw64/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache ${outdir}/lib/gdk-pixbuf-2.0/2.10.0/ -rf
cp /mingw64/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.dll ${outdir}/lib/gdk-pixbuf-2.0/2.10.0/loaders/ -rf
mkdir -p ${outdir}/share/glib-2.0/schemas
cp /mingw64/share/glib-2.0/schemas/* ${outdir}/share/glib-2.0/schemas/ -rf
mkdir -p ${outdir}/share/icons
cp /mingw64/share/icons/* ${outdir}/share/icons/ -rf
mkdir -p ${outdir}/share/themes
cp /mingw64/share/themes/* ${outdir}/share/themes/ -rf
mkdir -p ${outdir}/share/locale/en
cp /mingw64/share/locale/en/* ${outdir}/share/locale/en/ -rf
mkdir -p ${outdir}/share/locale/zh_CN
cp /mingw64/share/locale/zh_CN/* ${outdir}/share/locale/zh_CN/ -rf
mkdir -p ${outdir}/share/locale/zh_HK
cp /mingw64/share/locale/zh_HK/* ${outdir}/share/locale/zh_HK/ -rf
mkdir -p ${outdir}/share/locale/zh_TW
cp /mingw64/share/locale/zh_TW/* ${outdir}/share/locale/zh_TW/ -rf
echo "package ${bin} ok"

windows批处理脚本文件:

ECHO OFF
SET MINGW64DIR=D:\Software\msys64\mingw64
SET MINGW64BIN=%MINGW64DIR%\bin
SET MINGW64LIB=%MINGW64DIR%\lib
SET MINGW64SHARE=%MINGW64DIR%\share
SET PATH=%PATH%;%MINGW64BIN%
SET APPDIR=%~dp0
SET APP=gtkgui
SET OUTDIR=%APPDIR%%APP%.out
SET BIN=%OUTDIR%\%APP%.exe
SET RES=%APP%-gresource
SET RES_C=%RES%.c
SET RES_H=%RES%.h
SET RES_X=%APPDIR%%APP%.gresource.xml
MKDIR %OUTDIR%
CD /D %OUTDIR%

ECHO "compiling %RES_C%"
%MINGW64BIN%\glib-compile-resources --target=%RES_C% --generate-source %RES_X% --sourcedir=%APPDIR%
ECHO "compile %RES_C% ok"
ECHO "compiling %RES_H%"
%MINGW64BIN%\glib-compile-resources --target=%RES_H% --generate-header %RES_X% --sourcedir=%APPDIR%
ECHO "compile %RES_H% ok"

ECHO "compiling %BIN%"
@REM %MINGW64BIN%\gcc %APPDIR%%APP%.c %RES_C% -s -o2 -Wl,-subsystem,windows -o %BIN% `pkg-config --cflags --libs gtk+-3.0 glib-2.0 gio-2.0` 
@REM %MINGW64BIN%\gcc %APPDIR%%APP%.c %RES_C% -o %BIN% `pkg-config --cflags --libs gtk+-3.0 glib-2.0 gio-2.0` 
FOR /F "TOKENS=* DELIMS=" %%I IN ('%MINGW64BIN%\pkg-config --cflags --libs gtk+-3.0 glib-2.0 gio-2.0') DO (%MINGW64BIN%\gcc %APPDIR%%APP%.c %RES_C% -s -o2 -Wl,-subsystem,windows -o %BIN% %%I)
ECHO "compile %BIN% ok"

DEL /S /Q %RES_C%
DEL /S /Q %RES_H%
ECHO "clean up %RES_C% %RES_H%"
  
@REM DEL /S /Q %BIN%
@REM ECHO "clean up %BIN%"

ECHO "packagling %APP%"
XCOPY %BIN% %OUTDIR% /E /F /Y
  
XCOPY %MINGW64BIN%\libasprintf*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libatk*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libbz2*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libcairo*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libcharset*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libcroco*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libcrypto*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libdatrie*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libepoxy*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libexpat*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libffi*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libfontconfig*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libfreeglut*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libfreetype*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libfribidi*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgailutil*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgcc*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgdk*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgettext*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgio*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libglib*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgmodule*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgobject*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgraphite*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgthread*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libgtk*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libharfbuzz*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libiconv*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\liBINtl*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libjasper*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libjpeg*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libjson*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\liblzma*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libmpdec*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libobjc*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libpango*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libpcre*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libpixman*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libpng*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\librsvg*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libssl*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libstdc++*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libthai*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libtiff*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libturbojpeg*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libwinpthread*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\libxml*.dll %OUTDIR% /E /F /Y
XCOPY %MINGW64BIN%\zlib*.dll %OUTDIR% /E /F /Y
MKDIR %OUTDIR%\lib\gdk-pixbuf-2.0\2.10.0\loaders
XCOPY %MINGW64LIB%\gdk-pixbuf-2.0\2.10.0\loaders.cache %OUTDIR%\lib\gdk-pixbuf-2.0\2.10.0\ /E /F /Y
XCOPY %MINGW64LIB%\gdk-pixbuf-2.0\2.10.0\loaders\*.dll %OUTDIR%\lib\gdk-pixbuf-2.0\2.10.0\loaders\ /E /F /Y
MKDIR %OUTDIR%\share\glib-2.0\schemas
XCOPY %MINGW64SHARE%\glib-2.0\schemas\* %OUTDIR%\share\glib-2.0\schemas\ /E /F /Y
MKDIR %OUTDIR%\share\icons
XCOPY %MINGW64SHARE%\icons\* %OUTDIR%\share\icons\ /E /F /Y
MKDIR %OUTDIR%\share\themes
XCOPY %MINGW64SHARE%\themes\* %OUTDIR%\share\themes\ /E /F /Y
MKDIR %OUTDIR%\share\locale\en
XCOPY %MINGW64SHARE%\locale\en\* %OUTDIR%\share\locale\en\ /E /F /Y
MKDIR %OUTDIR%\share\locale\zh_CN
XCOPY %MINGW64SHARE%\locale\zh_CN\* %OUTDIR%\share\locale\zh_CN\ /E /F /Y
MKDIR %OUTDIR%\share\locale\zh_HK
XCOPY %MINGW64SHARE%\locale\zh_HK\* %OUTDIR%\share\locale\zh_HK\ /E /F /Y
MKDIR %OUTDIR%\share\locale\zh_TW
XCOPY %MINGW64SHARE%\locale\zh_TW\* %OUTDIR%\share\locale\zh_TW\ /E /F /Y
  
ECHO "package %BIN% ok"
ECHO ON

4.执行编译

msys2 64命令行下执行:

$cd /home/xxx/appdemo/

$./build.sh

5.运行示例


上传的附件:
×
打赏作者
最新回复 (0)
查看全部
全部楼主
返回