I get the contents of my textview and I want to display the contents in the terminal using the printf function. But have stange symbols (Why?):
// get textbuffer from textview end print value in terminal
void on_lower_button_clicked(GtkWidget *lower_button, GtkTextView *textview_1)
{
GtkTextBuffer *textbuffer_1;
textbuffer_1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview_1));
printf("%s\n", textbuffer_1); // strange symbols from my buffer ...
}
int main(int argc, char *argv[])
{
GtkWidget *lower_button;
GtkBuilder *builder;
GtkWidget *window;
GError *error = NULL;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
if(!gtk_builder_add_from_file(builder, "template.ui", &error)) {
g_printerr("Error loading file: %s\n", error->message);
g_clear_error(&error);
return 1;
}
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
lower_button = GTK_WIDGET(gtk_builder_get_object(builder, "lower_button"));
gtk_builder_connect_signals(builder, NULL);
// when I click on the button (lower_button) call
// on_lower_button_clicked function and transferred to her textview_1
g_object_unref(G_OBJECT(builder));
gtk_widget_show(window);
gtk_main();
return 0;
}
GtkTextBuffer is not a character array, it is a GTK object that can not be simply printed as text.
You need to extract the text from it if you want to print it or write it to file.
To do this, you will need to get a couple of GtkTextIter objects, and then use gtk_text_buffer_get_text.
Note, that if you have non English characters in your text, you may still have issues using printf, because the resulting text is UTF-8 encoded.
Here is an example code:
GtkTextIter start, end;
gchar *text;
gtk_text_buffer_get_start_iter(textview_1, &start);
gtk_text_buffer_get_end_iter(textview_1, &end);
text = gtk_text_buffer_get_text(textview_1, &start, &end, FALSE);
printf("%s\n",text);
g_free(text); //you need to clean up this buffer!
Related
On the first call of
gtk_main();
The size of the window is set by the total size of the grid.
But on second calls, it doesn't update.
Code to replicate
int main(int argc, char **argv) {
GtkWidget *mainWidget, *grid, *calculate;
gtk_init(&argc, &argv);
mainWidget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
grid = gtk_grid_new();
gtk_container_add(GTK_CONTAINER(mainWidget), grid);
int i;
static GtkWidget *a[10];
for (i = 0; i != 10; i++) {
char str[1];
a[i] = gtk_button_new_with_label(str);
gtk_grid_attach(GTK_GRID(grid), a[i], 1, i, 1, 1);
g_signal_connect(a[i], "clicked", G_CALLBACK(gtk_main_quit), NULL);
}
gtk_window_set_decorated(mainWidget, FALSE);
gtk_widget_show_all(mainWidget);
gtk_main();
for (i = 0; i != 9; i++) {
gtk_container_remove(GTK_GRID(grid), a[i]);
}
gtk_widget_show_all(mainWidget);
gtk_main();
return 0;
}
Well. I tried to use GDB to find the function that calculates the size of the window on the first call but I'm having some trouble.
So, as it turns out, unlike other toolkits. Not naming names (QT, Most Web Browsers), you (by default) cannot shrink a GTK window below its contents. So, a practical solution to this problem is.
gtk_window_resize(mainWidget, 1, 1)
I spot very strange behavior using a GValue:
This code runs fine:
#include <gtk/gtk.h>
int
main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
{
GValue value;
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, "hallo");
gchar * strVal = g_strdup_value_contents (&value);
g_print ("gvalue: %s\n", strVal);
free (strVal);
g_value_unset (&value);
}
return 0;
}
However, the following code spawns the warning cannot initialize GValue with type 'gchararray', the value has already been initialized as '(null)' in the marked line.
Note, that the only thing, that's changed, is the new block with another GValue inside.
#include <gtk/gtk.h>
int
main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
{
GValue value;
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, "hallo"); // warning spawns here
gchar * strVal = g_strdup_value_contents (&value);
g_print ("gvalue: %s\n", strVal);
free (strVal);
g_value_unset (&value);
}
{
GValue value2;
g_value_init (&value2, G_TYPE_INT);
g_value_set_int (&value2, 15);
gchar * strVal = g_strdup_value_contents (&value2);
g_print ("gvalue: %s\n", strVal);
free (strVal);
g_value_unset (&value2);
}
return 0;
}
Can someone tell me what is going on here?
You improperly initialized GValue.
GValue value = G_VALUE_INIT;
Not initialized variables at block scope have some garbage value, which may happen to be invalid and trigger an assertion (or may happen to be valid and nothing happens).
I am writing an app on raspberry in gtk+3/C which requires a virtual numpad (e.g 0-9, backspace and enter). I will use it with a touch screen, so no keyboard or mouse available (just like a kiosk).
I am adopting this code which allows me to use button press to emulate the number and display to an entry, however I am stuck at giving it the backspace function (go back and delete one previous char) and enter function (e.g when I'm done with input, press that button will help me to get back to the main screen).
/*
gcc -Wall keyboard1.c -o keyboard1 `pkg-config --cflags --libs gtk+-3.0`
Tested with GTK3.22 and GTK3.22 on Ubuntu18.04
*/
#include<gtk/gtk.h>
struct key{
gint id;
GtkWidget *button;
};
static const gchar letters[18]="QWERTYASDFGHZXCVBN";
//Need single chars as strings.
static gchar single_char[2]={'A', '\0'};
static void button_clicked(GtkWidget *button, gpointer *user_data)
{
gpointer *button_index=g_hash_table_lookup((GHashTable*)user_data[0], button);
g_print("Button index %i\n", (gint)(*button_index));
gint index=(gint)(*button_index);
single_char[0]=letters[index];
gchar *string=g_strdup_printf("%s%s", gtk_entry_get_text(GTK_ENTRY(user_data[1])), single_char);
gtk_entry_set_text(GTK_ENTRY(user_data[1]), string);
g_free(string);
}
int main(int argc, char *argv[])
{
gtk_init (&argc, &argv);
gint i=0;
gint j=0;
GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Keyboard");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 200);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
GtkWidget *entry=gtk_entry_new();
gtk_widget_set_hexpand(entry, TRUE);
//Save buttons in an array.
struct key k1;
GArray *keyboard=g_array_new(FALSE, FALSE, sizeof(struct key));
for(i=0;i<18;i++)
{
single_char[0]=letters[i];
k1.id=i;
k1.button=gtk_button_new_with_label(single_char);
g_array_append_val(keyboard, k1);
}
//A hash table to look up array index values.
struct key *p1=NULL;
GHashTable *hash_table=g_hash_table_new(NULL, NULL);
for(i=0;i<18;i++)
{
p1=&g_array_index(keyboard, struct key, i);
g_hash_table_insert(hash_table, p1->button, &(p1->id));
}
gpointer user_data[2]={hash_table, entry};
GtkWidget *grid1=gtk_grid_new();
for(i=0;i<3;i++)
{
for(j=0;j<6;j++)
{
p1=&g_array_index(keyboard, struct key, i*6+j);
gtk_grid_attach(GTK_GRID(grid1), p1->button, j, i, 1, 1);
g_signal_connect(p1->button, "clicked", G_CALLBACK(button_clicked), user_data);
}
}
GtkWidget *scroll=gtk_scrolled_window_new(NULL, NULL);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_hexpand(scroll, TRUE);
gtk_container_add(GTK_CONTAINER(scroll), grid1);
GtkWidget *expander=gtk_expander_new("Keyboard");
gtk_widget_set_vexpand(expander, TRUE);
gtk_widget_set_hexpand(expander, TRUE);
gtk_container_add(GTK_CONTAINER(expander), scroll);
GtkWidget *grid2=gtk_grid_new();
gtk_grid_attach(GTK_GRID(grid2), expander, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid2), entry, 0, 1, 1, 1);
gtk_container_add(GTK_CONTAINER(window), grid2);
gtk_widget_show_all(window);
gtk_main();
g_hash_table_destroy(hash_table);
g_array_free(keyboard, TRUE);
return 0;
}
Here is the link to the post.
I have tried to replace a char in the gchar letters[18]="QWERTYASDFGHZXCVBN"; with \b, \n and \t as to replace backspace, newline and tab, but only \t works. \b gave me a strange symbol:
Could you give me suggestions on how to do it. Thank you very much!
You seem to confuse two things: gtk_entry_set_text sets the caption of a GTK element to a string of characters. It does not interpret it's characters.
That's why gtk_entry_set_text works well with non-control characters but stuck at \b. You had to send a GtkEvent using gtk_propagate_event to handle this properly (see here and here). \n is not a control character is this manner: It's possible that the GTK element your writing to just doesn't support newlines and Return would be interpreted as confirmation.
I am new on GTK...
I want to do hide the label at first and when I will click on the "click" button it will show the label.I used gtk_widget_hide(label)...bt it is not working.and will use fixed container don't change it.
here is my code ==>
#include <gtk/gtk.h>
void destroy(GtkWidget* widget,gpointer *data){
/*gtk_main_quit();*/
g_print ("hide\n");
}
int main(int argc, char *argv[])
{
GtkWidget *window,*button,*label,*fixed;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"Demo");
gtk_widget_set_size_request(window,200,400);
gtk_container_set_border_width(GTK_CONTAINER(window),10);
fixed = gtk_fixed_new();
button = gtk_button_new_with_mnemonic("Click");
gtk_widget_set_size_request(button,20,20);
label = gtk_label_new("BOOM!!");
gtk_widget_hide(label);
g_signal_connect_swapped(G_OBJECT(button),"clicked",G_CALLBACK(destroy),NULL);
gtk_fixed_put(GTK_FIXED(fixed),button,0,0);
gtk_fixed_put(GTK_FIXED(fixed),label,30,30);
gtk_container_add(GTK_CONTAINER(window),fixed);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
use gtk_widget_hide() at end of gtk_widget_show_all(window)
because u have taken label in Fixed container and Fixed contain is in window.and then u called gtk_widget_show_all(window)thats means show the all contents that have in window....thats why have to use like this===>
#include <gtk/gtk.h>
void destroy(GtkWidget* label,gpointer *data){
/*gtk_main_quit();*/
g_print ("hide\n");
gtk_widget_show(label);
}
int main(int argc, char *argv[])
{
GtkWidget *window,*button,*label,*fixed;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"Demo");
gtk_widget_set_size_request(window,200,400);
gtk_container_set_border_width(GTK_CONTAINER(window),10);
fixed = gtk_fixed_new();
button = gtk_button_new_with_mnemonic("Click");
gtk_widget_set_size_request(button,20,20);
label = gtk_label_new("BOOM!!");
g_signal_connect_swapped(G_OBJECT(button),"clicked",G_CALLBACK(destroy),label);
gtk_fixed_put(GTK_FIXED(fixed),button,0,0);
gtk_fixed_put(GTK_FIXED(fixed),label,30,30);
gtk_container_add(GTK_CONTAINER(window),fixed);
gtk_widget_show_all(window);
gtk_widget_hide(label);
gtk_main();
return 0;
}
I am using GTK in C and I would like to make a form in order to collect input from user. I use GTK_ENTRY in order to collect user's input.
Unfortunately I don't know how I can put the execution is "pause" in order to wait that user enters its input and resume it as soon as the input is ready.
Can you help me, please?
Thanks
#include <gtk/gtk.h>
static void on_button_clicked(GtkButton *button,gpointer data);
static void on_entry_activate(GtkEntry *entry,gpointer data);
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *entry;
GtkWidget *button;
GtkWidget *hbox;
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"entry");
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_container_set_border_width(GTK_CONTAINER(window),5);
hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
gtk_container_add(GTK_CONTAINER(window),hbox);
entry=gtk_entry_new();
gtk_box_pack_start(GTK_BOX(hbox),entry,TRUE,TRUE,5);
button=gtk_button_new_with_label("Ok");
gtk_box_pack_start(GTK_BOX(hbox),button,FALSE,FALSE,0);
g_signal_connect(G_OBJECT(window),"destroy",
G_CALLBACK(gtk_main_quit),NULL);
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(on_button_clicked),entry);
g_signal_connect(G_OBJECT(entry),"activate",/* when you press ENTER */
G_CALLBACK(on_entry_activate),NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void on_button_clicked(GtkButton *button,gpointer data)
{
GtkWidget *entry=(GtkWidget *)data;
GtkWidget *dialog;
gchar buff[1024];
g_snprintf(buff,1024,"You input '%s' !",
gtk_entry_get_text(GTK_ENTRY(entry)));
dialog=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO,GTK_BUTTONS_OK,"%s",buff);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
gtk_entry_set_text(GTK_ENTRY(entry),"");
}
static void on_entry_activate(GtkEntry *entry,gpointer data)
{
g_printf("%s\n",gtk_entry_get_text(GTK_ENTRY(entry)));
}
This example is very simple. Input is ready when user press ENTER in entry or click OK BUTTON
The code is very easy to read, i think. Good luck!