2016-04-11 5 views
1

に基づいてラベルを変更し、私はGTKの混乱の中で最もせずにこのコードを書いた:GTK:私が何を意味するか示すためにコンソール入力

//more gtk declaration stuff above 
int access; 
access = 0; 

int tries; 
tries = 0; 

string input; 
input = ""; 

string code; 
code = ""; 

while(access != 1 && tries < 4){ 
    directions((gpointer)lbl); //change label to "type 'finger'" 
    cin >> input; 

    if(input.compare("finger") = 0){ 
     while(code.compare("1") != 0 && tries < 4){ 
      fpcheck((gpointer)lbl); //change label "Enter the secret code ('1')" 
      cin >> code; 
      if(code.compare("1") != 0){ 
       retry((gpointer) lbl);//change label "Try again!" 
       tries ++;  
      } 
      else{ 
       fprecog((gpointer) lbl); //change label "Recognized!" 
       access = 1; 
      } 
     } 
    } 
} 
if(access = 1) 
    //change label "Access Granted!" 
else 
    //change label "No access." 

gtk_main(); 
return 0; 

明らかにこれはまさに(gtk_mainいるため、動作しません。 )は最後まで呼び出されません。コンソールのものはうまく動作しますが、ウィンドウが最後までポップアップしないので、ユーザーは何をすべきか分からず、gtk_main()を早期に置くと、プログラムはgtk_main()ループでスタックされます何も起こりません。

この種のフローは、通常GTKでどのように達成されますか?私はメインから抜け出すためにいくつかのgtk_threadを試しましたが、それは明らかに廃止されているので、私はそれを使わないようにしています。

入力はGUIからのものではないので、入力はgtk_main()ではないスレッドによって読み取られなければなりません。実際には、それはビーグルボーンブラックに差し込まれたデバイスになりますが、これはより単純な同様の状況だと私は思う。

使用される実際の入力方法は、1)UARTチャネルを介して送信されたバイトと受信されたバイトに基づいてアクションを実行するフィンガープリントセンサー、2)BeagleBone BlackでOpenCVメソッドを使用するUSB​​カメラと顔認識スクリプトDebianを実行して、ラップトップにネットワーク接続して、集中的なopencvを実行します。今のところ私はFPセンサーでそれを取得しようとしています。私たちのインターフェースでは、intを返すFPセンサーメソッドを呼び出すことができ、そのintに応じて何かをすることができます。

返されるintに応じてGTKラベルを変更してから、ラベルが表示された後に別のメソッドを呼び出す必要があります。ここで

は、私のようなルックスと統合しようとしているどのようなコードの抜粋です:

while(key != 'x') 
    { 
     imshow("main_display", welcome); 
     key = waitKey(1); //poll keyboard at active screen 

     //key = getkey(); //TODO: poll from TFT instead 

     switch(key) 
     { 
      case 'i': //Identify User 
       imshow("main_display", press_finger); 
       waitKey(1); 
       printf("\n---IDENTIFY USER---\n"); 
       post_log(1, 0); 

       do_reg = true; 
       Ret = GT_LED_On(LS); 
       printf("\nPress Finger"); 

       //something to force console text before loop starts...? 

       Timer.InitTimer(); 
       while(GT_IsPressFinger(LS) == 0 && ((Timer.ElapsedTime_ms() < TIMEOUT))) {} 
       if(Timer.ElapsedTime_ms() >= TIMEOUT) 
       { 
        printf("\nCapture TIMEOUT\n"); 
        Ret = GT_LED_Off(LS); 
        post_log(6, user_id); 
        imshow("main_display", fps_timeout); 
        waitKey(1000); 
        do_reg = false; 
        break; //??????????????????????????? GOTO??? 
       } 
       printf("\nCapturing...Standby...\n"); 
       imshow("main_display", hold_finger); 
       waitKey(1); 
       Ret = GT_CaptureFinger(LS, 0); 

基本的に代わりのimshowを()私たちは、実際のGUIフレームワークを使用しよう、としているデバイスからすでにOpenCVのためにGTKが登場していますが、GTKを守るのが良いでしょう。このコンソールの質問は、単純なコンテキストでimshow()をgtkウィンドウのラベル変更に置き換える方法を理解しようとしています。

+0

GUIプログラムのCLIデータ入力のポイントは何ですか? – oldtechaa

+0

ここでのCLIは、より堅牢な設定をテストしています。元の質問では、単純化するために光沢を付けましたが、詳細を追加します。 – Will

答えて

0

ブレイクの助けを借りて、私は解決策を見つけたと思うが、その最高のものかどうかはわからない。

gtk_main()が起きている間に入力を取得し、そのときに関数を呼び出すために、標準入力ファイル記述子にglibio呼び出しを追加して、cinスタイル入力を検出しました。他のコードをコールバック関数として使用しました。この部分の助けを借りてブレイクに感謝します。

次に、この新しいミニスレッドのテキストを実際に更新するために、main_iteration()を呼び出すupdate()関数を作成し、gtk_main()を1回ループします。 Here's documentation on that.これは安全な使い方か、より良い解決策があるかどうかわかりませんが、プログラムは今私がしたいことをします。

今後の参考になる完全なコードです。

#include <gtk/gtk.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <iostream> 
#include <string> 
#include <glib.h> 


using namespace std; 

void update(){ 
while (gtk_events_pending()) 
gtk_main_iteration();} 

void fpcheck(/*GtkWidget *widget, GdkEvent *event,*/ gpointer window) { 
    gchar const *text = "<span font='32' weight='bold' color='#DDDDDD'>Enter the Secret\nCode. ('1')</span>"; 
    gtk_label_set_markup(GTK_LABEL(window), text); 
} 

void fprecog(/*GtkWidget *widget, GdkEvent *event,*/ gpointer window) { 
    gchar const *text2 = "<span font='32' weight='bold' color='#DDDDDD'>Fingerprint Recognized!</span>"; 
    gtk_label_set_markup(GTK_LABEL(window), text2); 
} 

void directions(/*GtkWidget *widget, GdkEvent *event,*/ gpointer window){ 
    gchar const *text3 = "<span font='32' weight='bold' color='#DDDDDD'>Type 'finger'.</span>"; 
    gtk_label_set_markup(GTK_LABEL(window), text3); 
} 

void retry(/*GtkWidget *widget, GdkEvent *event,*/ gpointer window){ 
    gchar const *text4 = "<span font='32' weight='bold' color='#DDDDDD'>Try Again.</span>"; 
    gtk_label_set_markup(GTK_LABEL(window), text4); 
} 

void accessed(/*GtkWidget *widget, GdkEvent *event,*/ gpointer window){ 
    gchar const *text5 = "<span font='32' weight='bold' color='#DDDDDD'>Access Granted!</span>"; 
    gtk_label_set_markup(GTK_LABEL(window), text5); 
} 

void denied(/*GtkWidget *widget, GdkEvent *event,*/ gpointer window){ 
    gchar const *text6 = "<span font='32' weight='bold' color='#DDDDDD'>Access Denied.</span>"; 
    gtk_label_set_markup(GTK_LABEL(window), text6); 
} 


gboolean callback(GIOChannel *gio, GIOCondition condition, gpointer lbl){ 
    int access; 
    access = 0; 

    int tries; 
    tries = 0; 

    string input; 
    input = ""; 

    string code; 
    code = ""; 

    while(access != 1 && tries < 4){ 
     directions((gpointer)lbl); //change label to "type 'finger'" 
     update(); 
     cin >> input; 

     if(input.compare("finger") == 0){ 
      while(code.compare("1") != 0 && tries < 4){ 
       fpcheck((gpointer)lbl); //change label "Enter the secret code ('1')" 
       update(); 
       cin >> code; 
       if(code.compare("1") != 0){ 
        retry((gpointer) lbl);//change label "Try again!" 
        update(); 
        tries ++;  
       } 
       else{ 
        fprecog((gpointer) lbl); //change label "Recognized!" 
        update(); 
        access = 1; 
       } 
      } 
     } 
    } 
    if(access == 1) 
     accessed((gpointer)lbl); 
     //change label "Access Granted!" 
    else 
     denied((gpointer)lbl); 
     //change label "No access." 
} 


int main(int argc, char *argv[]){ 

    GtkWidget *window; //main window 
    GtkWidget *lbl; //text 
    GdkColor color = {0, 0x0, 0x0, 0x0}; //window color 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); //init window 
    //gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); //window pos on screen 
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE); //user cant resize //doesnt work 
    //gtk_window_set_default_size(GTK_WINDOW(window), 800, 480); //window size 

    gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); //set color to window 
    gtk_window_set_decorated(GTK_WINDOW(window), FALSE); //borderless 
    gtk_widget_show(window); 

    lbl = gtk_label_new(NULL); //label init 
    gtk_container_add(GTK_CONTAINER(window), lbl); 
    gtk_widget_set_size_request(lbl,800,480); //sets area that text can be //breaks alignment 
    gtk_misc_set_alignment(GTK_MISC(lbl), .5, .5); //alignment 
    gtk_label_set_line_wrap_mode(GTK_LABEL(lbl), PANGO_WRAP_WORD_CHAR); //sets line wrap on 

    gchar const *str = "<span font='32' weight='bold' color='#DDDDDD'>Press Enter to begin.</span>"; //label text, uses pango markup 
    gtk_label_set_markup(GTK_LABEL(lbl), str); //add pango str to label 
    gtk_label_set_angle(GTK_LABEL(lbl), -90); 

    gtk_widget_show(lbl); 

    //fpcheck((gpointer)lbl); 
    //g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(fpcheck), (gpointer) lbl); //calls fpcheck to change label 
    //g_signal_connect(G_OBJECT(window), "key-release-event", G_CALLBACK(fprecog), (gpointer) lbl);  
    //fprecog((gpointer)lbl); 

    g_signal_connect(G_OBJECT(window), "destroy", 
    G_CALLBACK(gtk_main_quit), NULL); 

    //gtk_widget_show_all(window); //build the window all at once 

    //label says "Ready" 

    GIOChannel *gio; 
    gio = g_io_channel_unix_new(STDIN_FILENO); 
    guint ret; 
    ret = g_io_add_watch(gio, G_IO_IN, callback, (gpointer)lbl); 

    gtk_main(); 

    return 0; 
} 
1

あなたが探しているのはGlib IO Channelだと思います。これを標準の入力ファイル記述子に結び付けると、ユーザーがenterを押すとシグナルが発せられます。次に、cinを使ってテキストを取得できるはずです。

パスワードを入力する場合は、代わりにusing a dialogと入力してユーザー入力を取得することを検討してください。

+0

これはうまくいくかもしれませんが、実際に使用される入力方法は、1)UARTチャンネルを通じて送受信されたバイトに基づいてアクションを実行するフィンガープリントセンサー、2)USBカメラと顔認識スクリプトDebianを実行しているBeagleBone BlackのOpenCVメソッド。ノートパソコンにネットワーク接続され、集中的なopencvを実行します。 私はちょうどそれをFPセンサーで取得しようとしています。私たちのインターフェースでは、intを返すFPセンサーメソッドを呼び出すことができ、そのintに応じて何かをすることができます。 glibIOはそれに適していますか? – Will

+0

これはGlib IO Channelのものとまったく同じです。 UARTのファイルディスクリプタをGlib IOチャンネルにラップすると、UART上のデータを取得したときに信号が得られます。 UARTデバイスを標準入力/出力のまわりにラップしたように見えるという事実は、ファイル記述子の値以外は変更しません。私は誰かがTCPソケットで同じことをした[この例](http://stackoverflow.com/questions/9513327/gio-socket-server-client-example)をチェックすることをお勧めします。 – Blake

+0

"これを標準入力ファイル記述子に結びつける"ことを明確にすることはできますか?私は最初にコンソールの例を使って作業をしようとしていますが、[これをリソースとして](http://www.linuxjournal.com/node/8545/print)を使っていますが、これでfdを取得する方法はわかりません場合。 – Will

関連する問題