为了证明我的意思,我写了这段代码而没有大部分的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的东西来突破main,但这显然已被弃用,所以我试图不使用它。
输入必须由不是gtk_main()的线程读取,因为输入不是来自GUI。实际上,它将是一个插入beaglebone黑色的设备,但我认为这是一个更简单的类似情况。
将使用的实际输入方法是1)指纹传感器,它通过UART通道根据发送和接收的字节执行操作,2)使用OpenCV方法在BeagleBone Black上运行的usb相机和面部识别脚本Debian,联网到笔记本电脑做强化opencv的东西。目前我只想尝试使用FP传感器。使用我们的接口,我们可以调用FP传感器方法,该方法返回一个int,并根据该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 :(得分:1)
我认为您正在寻找的是Glib IO Channel。如果将此绑定到标准输入文件描述符,则在用户按Enter键时会触发该信号。然后你应该能够使用cin来获取文本。
如果您打算获取某种类型的密码,可以考虑使用using a dialog来捕获用户输入。
答案 1 :(得分:0)
好吧,在Blake的帮助下,我想我找到了一个解决方案,但我不知道它是否是最好的解决方案。
为了在gtk_main()发生时获取输入,并在发生这种情况时调用函数,我在标准输入文件描述符上添加了一个glib io调用来检测cin样式输入。我使用其他代码作为回调函数。感谢Blake对这部分的帮助。
然后,为了实际更新这个新的迷你线程中的文本,我创建了一个update()函数来调用main_iteration(),同时循环通过gtk_main()一次。 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;
}