LoginSignup
9
13

More than 1 year has passed since last update.

WindowsでgccでC言語で簡単にGUI(Tcl/Tk)

Last updated at Posted at 2019-09-03

はじめに

職場でちょっとツール作りたいけど、使う人のことも考えてGUIにしたい、C言語で組みたい、ライセンスとかも考えてgccで作りたい、ライブラリ色々覚えたくない、そんなときにさっと使える手順です

MinGWのインストール

左の「download/installer」でインストーラが手に入ります。
実行してインストール。

インストール後のInstallation Manager
左のBasic Setupを選び

  • mingw32-base-bin
  • mingw32-gcc-g++-bin

をクリックしてMark

左のAll Packages→MinGW→MinGW Contributedを選び

  • mingw32-tcl-bin
  • mingw32-tk-bin

をクリックしてMark

左上のInstallation
Apply Changes
でインストールを実行

MinGWにPATHを通す

システムのPATHにC:\MinGW\binを登録します。

こちらの記事など参考にどうぞ

Windows10で実行ファイルへのパスを通す手順
https://qiita.com/shuhey/items/7ee0d25f14a997c9e285

ソースを作る

適当なフォルダに以下のように作ります。

C言語のソースが以下です。

main.c
/*
 * These codes are licensed under CC0.
 * http://creativecommons.org/publicdomain/zero/1.0/deed.ja
 */
#include <tcl.h>
#include <tk.h>

//独自コマンドの作成
int proc(ClientData clientData, Tcl_Interp* interp, int argc, const char* argv[])
{
    //argc:引数の数
    //argv[0]:自分自身(コマンド名)
    //argv[1]~:引数

    if ( argc != 1 )
    {
        char *retmsg = "argument error";
        Tcl_SetResult(interp, retmsg, TCL_VOLATILE);
        return TCL_ERROR;
    }
    printf("Call!\n");

    char *retvalue = "0";
    Tcl_SetResult(interp, retvalue, TCL_VOLATILE);
    return TCL_OK;

    //終了コードの種類
    //TCL_OK、TCL_ERROR、 TCL_RETURN、TCL_BREAK、またはTCL_CONTINUE

    //応答の種類
    //TCL_STATIC ... データが静的な領域(static char)にあって、関数を抜けてもその領域が上書きされない場合
    //TCL_VOLATILE ... データが揮発する(auto char)スタック領域にあり、関数を抜けると上書きされる場合
    //TCL_DYNAMIC ... データがAPI Tcl_Allocで確保された領域にある場合
}

int main(int argc, char* argv[])
{
    Tcl_Interp *interp = Tcl_CreateInterp(); //インタプリタを作成
    Tcl_FindExecutable(argv[0]); //初期化前準備
    if ( Tcl_Init(interp) == TCL_ERROR ) //Tclを初期化(スタンダートライブラリinit.tclをロード)
    {
        const char *errmsg = Tcl_GetStringResult(interp); //エラーメッセージの取得
        printf("インタプリタの初期化に失敗: %s\n",errmsg);
        return -1;
    }
    if ( Tk_Init(interp) == TCL_ERROR ) //Tkを初期化(GUIライブラリをロード)
    {
        const char *errmsg = Tcl_GetStringResult(interp); //エラーメッセージの取得
        printf("GUIライブラリの初期化に失敗: %s\n", errmsg);
        return -1;
    }

    //コマンドを作る
    Tcl_CreateCommand(interp,"testproc",proc,NULL,NULL);

    if ( Tcl_EvalFile(interp, "script.tcl") == TCL_ERROR )//インタプリタで実行
    {
        const char *errmsg = Tcl_GetStringResult(interp); //エラーメッセージの取得
        printf("実行失敗: エラー内容:%s\n", errmsg);
        return -1;
    }else{
        const char *errmsg = Tcl_GetStringResult(interp); //エラーメッセージの取得
        printf("実行成功:%s\n", errmsg);
    }

    Tk_MainLoop();//Tkのイベントループへ

    Tcl_DeleteInterp(interp); //インタプリタのお片付け
    return 0;
}

TCL言語のソースが以下です。(GUI定義ファイルのようなものと考えてください)

script.tcl
button .b1 -text "Hello World" -command {puts "Hello World"}
button .b2 -text "Call proc" -command {testproc}
pack .b1 .b2

コンパイルする

ソースのあるフォルダでコマンドプロンプトを開き、以下を実行します。

gcc main.c -o test.exe -ltcl86 -ltk86

実行する

test.exeを実行します。
上のボタンを押すとHello Worldが表示され、
下のボタンを押すとC言語のproc関数が実行されます。

image.png

配布時の注意

一見EXEファイルとTCLファイルで動くように思えますが、実際にはMinGWフォルダ内のファイルに依存しています。
配布するには、以下のようなフォルダ構成にして配布してください。

配布フォルダ
├─bin
|  ├─test.exe
|  ├─script.tcl
|  ├─libgcc_s_dw2-1.dll ←C:\MinGW\binにあるファイル
|  ├─tcl86.dll ←C:\MinGW\binにあるファイル
|  └─tk86.dll ←C:\MinGW\binにあるファイル
└─lib
    ├─tcl8.6 ←C:\MinGW\libにあるフォルダ
    └─tk8.6 ←C:\MinGW\libにあるフォルダ

Tcl/tkのライセンスにも目を通しておいてください
https://www.tcl.tk/software/tcltk/license.html

おわりに

Tcl/Tkは、見た目は素朴ですがかなり簡単にGUIが書けるツールキット&言語です。
C言語に組み込む前提で作られているため、このようにかなり簡単に使用できます。

TCL言語自体の使い方については以下などを参照してください。

Tcl/Tk GUI Programming
http://www.nct9.ne.jp/m_hiroi/tcl_tk.html

Tcl/Tkのススメ
https://sites.google.com/site/gpsnmeajp/tcl-tk/tcl-tknosusume

Tcl/tk簡易リファレンス
https://sites.google.com/site/gpsnmeajp/tcl-tk/tcl-tk-jian-yirifarensu

Tcl/TkでWindowsプログラミング
http://web.archive.org/web/20160116031827/http://homepage3.nifty.com/kaku-chan/tcl_tk/index.html

9
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
13