Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

MinGWのインストール

http://www.mingw.org/

左の「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
Allpy 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"}
pack .b1

コンパイルする

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

gcc test.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

gpsnmeajp
電子工作が主な趣味ですが、PC用のツールを作るのも好きです。 特にライセンスを明記していないソースコードのライセンスについてはCC0です。
https://sabowl.sakura.ne.jp/gpsnmeajp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした