GTK - 禁用输入字段时出现 pango 严重错误
GTK - pango-critical error when disabling entry field
我在尝试禁用输入字段时遇到以下错误(两次):
(SDS-CW:7145): Pango-CRITICAL **: 16:38:37.521: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
(SDS-CW:7145): Pango-CRITICAL **: 16:38:37.521: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
这个想法是从输入字段中获取一个 IP 地址到程序中。然而,在我开始尝试验证该条目是一个有效的 IP 地址之前,这一切都运行良好。它曾经在按下提交按钮后立即禁用该字段以防止用户更改输入的文本,但是现在该字段空白并且似乎中断了,如下所示。
当输入字段未被禁用时,我没有收到错误。
但是,验证函数似乎 运行 正常,并且检查函数 wait_for_connction()
(在新线程中 运行)开始 运行ning,但始终如一函数迭代 1 次后,将抛出 pango 错误。
这是我在输入字段中输入 192.168.0.254
时的完整控制台输出:
/home/csc/CLionProjects/SDS-CW/GUIs/Server/cmake-build-debug/SDS-CW
Valid IP
Selected Server IP: xxx.xxx.xxx.xxx
Checking server...
(SDS-CW:7423): Pango-CRITICAL **: 16:57:11.582: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
(SDS-CW:7423): Pango-CRITICAL **: 16:57:11.582: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
Checking server...
Checking server...
Checking server...
Checking server...
Connected to: xxx.xxx.xxx.xxx
Conn success
有趣的是,每次 GTK window 失去焦点时,我似乎都会再次遇到错误,然后在重新获得焦点时再次出现错误。
这是按钮的回调:
int connect_server(GtkButton *button, gpointer user_data) {
struct data *server_data = (struct data*)user_data;
GtkWidget *serverIPEntry = server_data->serverIPEntry;
GtkWidget *sererPortEntry = server_data->serverPortEntry;
GtkWidget *connectButton = server_data->connectButton;
GtkWidget *serverIPErrorLabel = server_data->serverIPErrorLabel;
GtkWidget *serverPortErrorLabel = server_data->serverPortErrorLabel;
char* serverIP = (char*)gtk_entry_get_text(GTK_ENTRY(serverIPEntry));
char* serverPortStr = (char*)gtk_entry_get_text(GTK_ENTRY(sererPortEntry));
int serverPort = atoi(serverPortStr);
int status;
gtk_widget_set_name(serverIPEntry, "fieldsNormal");
gtk_label_set_text(GTK_LABEL(serverIPErrorLabel), "");
// TODO: Check for valid IP and Port
if (strcmp(serverIP, "") == 0) {
gtk_widget_set_name(serverIPEntry, "fieldsError");
gtk_label_set_text(GTK_LABEL(serverIPErrorLabel), "Please enter an IP");
return -1;
} else if (validate_ip(serverIP) == 1){
// TODO: Check if IP Address given is valid
g_print("Valid IP\n");
} else {
g_print("Invalid IP\n");
}
g_print("Selected Server IP: %s\n", selectedServerStr);
gtk_widget_set_sensitive(connectButton, FALSE);
append_to_log("Attempting connection, please wait...\n", 1);
gtk_widget_set_sensitive(serverIPEntry, FALSE); // ERROR HAPPENING WHEN I RUN THIS LINE
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), "Connecting...");
status = pthread_create(&connThread, NULL, wait_for_connection, server_data);
// TODO: Check thread status code
if (status != 0) {
printf("Thread returned error code %d\n", status);
exit(-1);
}
return 1;
}
void *wait_for_connection(void* server_data) {
struct data *srvDat = server_data;
GtkWidget *disconnectButton = srvDat->disconnectButton;
GtkWidget *connectButton = srvDat->connectButton;
GtkWidget *statLabel = srvDat->statLabel;
GtkWidget *serverIPEntry = srvDat->serverIPEntry;
requestConnect = 1;
for (int i = 0; i < 10; i++) {
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(workingSetProgressBar));
g_print("Checking server...\n");
// THIS BELOW IS FOR TESTING ONLY
if (i == 4) {
connected = 1;
}
// THIS ABOVE IS FOR TESTING ONLY
if (connected == 1) {
connSuccess = 1;
break;
}
connSuccess = 0;
sleep(1);
}
if (connSuccess == 1) {
g_print("Connected to: %s\n", selectedServerStr);
printf("Conn success\n");
// TODO: Change button to disconnect button
// TODO: Set progress to 0
gtk_widget_hide(connectButton);
gtk_widget_show(disconnectButton);
gtk_widget_set_name(statLabel, "connLabel");
gtk_label_set_text(GTK_LABEL(statLabel), "Connected");
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(workingSetProgressBar), 0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), NULL);
char* connLog = "Connected To: ";
char* strToLog;
if((strToLog = malloc(strlen(connLog)+strlen(selectedServerStr)+5)) != NULL){
strToLog[0] = '[=12=]';
strcat(strToLog, connLog);
strcat(strToLog, selectedServerStr);
strcat(strToLog, "\n");
} else {
// TODO: Deal with failed malloc
}
append_to_log(strToLog, 1);
pthread_exit(&connThread);
} else if (connSuccess == 0) {
gtk_widget_set_sensitive(serverIPEntry, TRUE);
gtk_widget_set_sensitive(connectButton, TRUE);
printf("Conn failed\n");
append_to_log("Connection failed\n", 1);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(workingSetProgressBar), 0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), "Disconnected");
pthread_exit(&connThread);
}
}
这是我用来将条目验证为 IP 地址的函数 validate_ip()
,这似乎导致了这个问题:
int validate_number(char *str) {
while (*str) {
if(!isdigit(*str)){ //if the character is not a number, return false
return 0;
}
str++; //point to next character
}
return 1;
}
int validate_ip(char *ip) { //check whether the IP is valid or not
int i, num, dots = 0;
char *ptr;
if (ip == NULL)
return 0;
ptr = strtok((char*)ip, "."); //cut the string using dot delimiter
if (ptr == NULL)
return 0;
while (ptr) {
if (!validate_number(ptr)) //check whether the sub string is holding only number or not
return 0;
num = atoi(ptr); //convert substring to number
if (num >= 0 && num <= 255) {
ptr = strtok(NULL, "."); //cut the next part of the string
if (ptr != NULL)
dots++; //increase the dot count
} else
return 0;
}
if (dots != 3) //if the number of dots are not 3, return false
return 0;
return 1;
}
如有任何帮助,我们将不胜感激。谢谢!
刚刚通过将 validate_ip()
函数的开始更改为如下内容来解决此问题:
int validate_ip(char *ipOrig) { //check whether the IP is valid or not
char* ip[17];
strcpy((char*)ip, ipOrig);
int i, num, dots = 0;
char *ptr;
....
看起来 validate_ip()
函数更改传递给它的变量的值是一个问题,所以我复制了要在函数中使用的传入变量。
我在尝试禁用输入字段时遇到以下错误(两次):
(SDS-CW:7145): Pango-CRITICAL **: 16:38:37.521: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
(SDS-CW:7145): Pango-CRITICAL **: 16:38:37.521: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
这个想法是从输入字段中获取一个 IP 地址到程序中。然而,在我开始尝试验证该条目是一个有效的 IP 地址之前,这一切都运行良好。它曾经在按下提交按钮后立即禁用该字段以防止用户更改输入的文本,但是现在该字段空白并且似乎中断了,如下所示。
当输入字段未被禁用时,我没有收到错误。
但是,验证函数似乎 运行 正常,并且检查函数 wait_for_connction()
(在新线程中 运行)开始 运行ning,但始终如一函数迭代 1 次后,将抛出 pango 错误。
这是我在输入字段中输入 192.168.0.254
时的完整控制台输出:
/home/csc/CLionProjects/SDS-CW/GUIs/Server/cmake-build-debug/SDS-CW
Valid IP
Selected Server IP: xxx.xxx.xxx.xxx
Checking server...
(SDS-CW:7423): Pango-CRITICAL **: 16:57:11.582: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
(SDS-CW:7423): Pango-CRITICAL **: 16:57:11.582: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
Checking server...
Checking server...
Checking server...
Checking server...
Connected to: xxx.xxx.xxx.xxx
Conn success
有趣的是,每次 GTK window 失去焦点时,我似乎都会再次遇到错误,然后在重新获得焦点时再次出现错误。
这是按钮的回调:
int connect_server(GtkButton *button, gpointer user_data) {
struct data *server_data = (struct data*)user_data;
GtkWidget *serverIPEntry = server_data->serverIPEntry;
GtkWidget *sererPortEntry = server_data->serverPortEntry;
GtkWidget *connectButton = server_data->connectButton;
GtkWidget *serverIPErrorLabel = server_data->serverIPErrorLabel;
GtkWidget *serverPortErrorLabel = server_data->serverPortErrorLabel;
char* serverIP = (char*)gtk_entry_get_text(GTK_ENTRY(serverIPEntry));
char* serverPortStr = (char*)gtk_entry_get_text(GTK_ENTRY(sererPortEntry));
int serverPort = atoi(serverPortStr);
int status;
gtk_widget_set_name(serverIPEntry, "fieldsNormal");
gtk_label_set_text(GTK_LABEL(serverIPErrorLabel), "");
// TODO: Check for valid IP and Port
if (strcmp(serverIP, "") == 0) {
gtk_widget_set_name(serverIPEntry, "fieldsError");
gtk_label_set_text(GTK_LABEL(serverIPErrorLabel), "Please enter an IP");
return -1;
} else if (validate_ip(serverIP) == 1){
// TODO: Check if IP Address given is valid
g_print("Valid IP\n");
} else {
g_print("Invalid IP\n");
}
g_print("Selected Server IP: %s\n", selectedServerStr);
gtk_widget_set_sensitive(connectButton, FALSE);
append_to_log("Attempting connection, please wait...\n", 1);
gtk_widget_set_sensitive(serverIPEntry, FALSE); // ERROR HAPPENING WHEN I RUN THIS LINE
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), "Connecting...");
status = pthread_create(&connThread, NULL, wait_for_connection, server_data);
// TODO: Check thread status code
if (status != 0) {
printf("Thread returned error code %d\n", status);
exit(-1);
}
return 1;
}
void *wait_for_connection(void* server_data) {
struct data *srvDat = server_data;
GtkWidget *disconnectButton = srvDat->disconnectButton;
GtkWidget *connectButton = srvDat->connectButton;
GtkWidget *statLabel = srvDat->statLabel;
GtkWidget *serverIPEntry = srvDat->serverIPEntry;
requestConnect = 1;
for (int i = 0; i < 10; i++) {
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(workingSetProgressBar));
g_print("Checking server...\n");
// THIS BELOW IS FOR TESTING ONLY
if (i == 4) {
connected = 1;
}
// THIS ABOVE IS FOR TESTING ONLY
if (connected == 1) {
connSuccess = 1;
break;
}
connSuccess = 0;
sleep(1);
}
if (connSuccess == 1) {
g_print("Connected to: %s\n", selectedServerStr);
printf("Conn success\n");
// TODO: Change button to disconnect button
// TODO: Set progress to 0
gtk_widget_hide(connectButton);
gtk_widget_show(disconnectButton);
gtk_widget_set_name(statLabel, "connLabel");
gtk_label_set_text(GTK_LABEL(statLabel), "Connected");
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(workingSetProgressBar), 0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), NULL);
char* connLog = "Connected To: ";
char* strToLog;
if((strToLog = malloc(strlen(connLog)+strlen(selectedServerStr)+5)) != NULL){
strToLog[0] = '[=12=]';
strcat(strToLog, connLog);
strcat(strToLog, selectedServerStr);
strcat(strToLog, "\n");
} else {
// TODO: Deal with failed malloc
}
append_to_log(strToLog, 1);
pthread_exit(&connThread);
} else if (connSuccess == 0) {
gtk_widget_set_sensitive(serverIPEntry, TRUE);
gtk_widget_set_sensitive(connectButton, TRUE);
printf("Conn failed\n");
append_to_log("Connection failed\n", 1);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(workingSetProgressBar), 0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), "Disconnected");
pthread_exit(&connThread);
}
}
这是我用来将条目验证为 IP 地址的函数 validate_ip()
,这似乎导致了这个问题:
int validate_number(char *str) {
while (*str) {
if(!isdigit(*str)){ //if the character is not a number, return false
return 0;
}
str++; //point to next character
}
return 1;
}
int validate_ip(char *ip) { //check whether the IP is valid or not
int i, num, dots = 0;
char *ptr;
if (ip == NULL)
return 0;
ptr = strtok((char*)ip, "."); //cut the string using dot delimiter
if (ptr == NULL)
return 0;
while (ptr) {
if (!validate_number(ptr)) //check whether the sub string is holding only number or not
return 0;
num = atoi(ptr); //convert substring to number
if (num >= 0 && num <= 255) {
ptr = strtok(NULL, "."); //cut the next part of the string
if (ptr != NULL)
dots++; //increase the dot count
} else
return 0;
}
if (dots != 3) //if the number of dots are not 3, return false
return 0;
return 1;
}
如有任何帮助,我们将不胜感激。谢谢!
刚刚通过将 validate_ip()
函数的开始更改为如下内容来解决此问题:
int validate_ip(char *ipOrig) { //check whether the IP is valid or not
char* ip[17];
strcpy((char*)ip, ipOrig);
int i, num, dots = 0;
char *ptr;
....
看起来 validate_ip()
函数更改传递给它的变量的值是一个问题,所以我复制了要在函数中使用的传入变量。