Rezie gtk3 window to fit grid - c

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)

Related

Simulate backspace button press gtk in C

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.

GTK - Cannot print buffer value using function `printf`

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!

Why am I getting the realloc(): invalid next size error for this code?

I have typed this code, and when I compile the code it seems fine but when I execute the executable, as soon as I go to the place corresponding to this file, the app quits and I get realloc(): Invalid next size Aborted (core dumped). Can someone please tell me the correct code and say why? This problem have been vexing me for a while. Oh and HTFAR stands for
Help topic function array. So there. I am trying to make a help center for my ripoff of minecraft
#include "DisplayHelp.h"
#include <stdlib.h>
#define NOTHING
#define molloc(arg) malloc(arg)
GtkWidget(*List)=NULL;
void (**HTFAR)(void);
uint NumberOfT = 0;
void HelpNewTemplate(const char *Title, const char *Text) {
}
void HelpAbout(void) {
char *Text ="<span font=\"24\">FakeCraft\n\nCreator: Asadefa\n\nVersion: 1.0.0</span>";
GtkWidget (*Dialog) = gtk_message_dialog_new(GTK_WINDOW(Window), 1, 0, 2, EMPTYSTRING);
gtk_message_dialog_set_markup(GTK_MESSAGE_DIALOG(Dialog), Text);
gtk_window_set_title(GTK_WINDOW(Dialog), "About");
gtk_window_set_position(GTK_WINDOW(Dialog), 0);
gtk_dialog_run(GTK_DIALOG(Dialog));
gtk_widget_destroy(Dialog);
}
void HelpPlacingBlocks(void) {
printf("sadf\n");
}
void HelpMiningBlocks(void) {
printf("asdf\n");
}
void HelpCrafting(void) {
}
void HelpSmelting(void) {
}
void HelpShowTopic(void) {
GtkListBoxRow (*SRow);
SRow = gtk_list_box_get_selected_row(GTK_LIST_BOX(List));
if(SRow != NULL NOTHING NOTHING NOTHING NOTHING NOTHING){
unsigned int NRow = gtk_list_box_row_get_index(SRow);
(*HTFAR[NRow])();
}else{
}
}
void AddHT(const char *Name, GtkWidget (*Label), void(HTF)(void)) {
const char *TFormat = ("<span font=\"16\">%s</span>");
char *Format = g_markup_printf_escaped(TFormat, Name);
Label = gtk_label_new(NULL NOTHING NOTHING NOTHING);
gtk_widget_set_halign(Label, GTK_ALIGN_START);
gtk_widget_set_margin_start(Label, 0x0000010);
gtk_widget_set_margin_top(Label, 0x000008);
gtk_widget_set_margin_bottom(Label, 0x000008);
gtk_label_set_markup(GTK_LABEL(Label), Format);
gtk_container_add(GTK_CONTAINER(List), Label);
HTFAR = realloc(HTFAR,sizeof(void*));
HTFAR[NumberOfT] = &HTF;
NumberOfT += 0x1;
printf("Added HT %s\n", Name);
g_free(Format);
}
//Handle Size
void DisplayHelp(void) {
HTFAR = molloc(0x00);
gtk_main_quit(NOTHING);
gtk_widget_destroy(Box);
Box = gtk_grid_new(NOTHING);
gtk_grid_set_row_homogeneous(GTK_GRID(Box), TRUE);
gtk_grid_set_column_homogeneous(GTK_GRID(Box), TRUE);
gtk_container_add(GTK_CONTAINER(Window),Box NOTHING);
List = gtk_list_box_new();
GtkWidget (*ListC) = gtk_scrolled_window_new(NULL, NULL NOTHING);
gtk_grid_attach(GTK_GRID(Box),ListC, 0x0, 0x0, 0x1, 0x8 NOTHING);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ListC), 2, 1);
gtk_container_add(GTK_CONTAINER(ListC), List);
GtkWidget (*Label) = NULL;
GtkWidget (*Button) = NULL;
GtkWidget (*Hbox) = gtk_box_new(0, 10);
gtk_box_set_homogeneous(GTK_BOX(Hbox),1);
Button = gtk_button_new_with_label("Done");
gtk_container_set_border_width(GTK_CONTAINER(Hbox), 12);
g_signal_connect(Button, "clicked", DisplayOptions, NULL);
gtk_grid_attach_next_to(GTK_GRID(Box),Hbox,ListC,3, 1, 2);
gtk_box_pack_end(GTK_BOX(Hbox), Button, 1, 1, FALSE);
AddHT("Placing Blocks", Label, HelpPlacingBlocks);
AddHT("Mining Blocks", Label, HelpMiningBlocks);
AddHT("Crafting", Label, HelpCrafting);
AddHT("Smelting", Label, HelpSmelting);
AddHT("About", Label, HelpAbout);
free(HTFAR);
Button = gtk_button_new_with_label("Show Topic");
gtk_box_pack_start(GTK_BOX(Hbox), Button, 1, 1, FALSE);
g_signal_connect(Button,"clicked",HelpShowTopic, NULL);
Label = gtk_label_new(EMPTYSTRING);
char *TXT = ("<span font = \"16\">Help Center</span>");
gtk_grid_attach_next_to(GTK_GRID(Box),Label,ListC,2,1,1);
gtk_label_set_markup(GTK_LABEL(Label), TXT);
printf(ESSTR, "Help" NOTHING);
gtk_widget_show_all(Window);
gtk_main();
}
Why is this happening and what is the correct code to type?
HTFAR = realloc(HTFAR,sizeof(void*));
should be
HTFAR = realloc(HTFAR,sizeof(void(*)(void))*(NumberOfT+1));
You got the specific error you did because realloc() moved the block and you overwrote the block after the one returned by (I think) malloc(0x0).

Update of an integer between functions

I have a big code of GTK2 in which I´m having troubles updating the value of an integer (in this case trigan, that its defined in the main body and callbacked to the two functions that are giving me this problem).
I intend to press the button RUN that calls the function RUN that starts displaying numbers in real time. Then, while text its running I will press STOP button that calls the function STOP, updating the value of trigan to 1.
Here is the piece of code in question:
void STOP(GtkWidget *widget, GObject *context_object_stp)
{
GtkEntry *trigan = g_object_get_data (context_object_stp, "trigan");
trigan=1;
}
void RUN(GtkWidget *widget, GObject *context_object)
{
GtkEntry *buffer= g_object_get_data (context_object, "buffer");
GtkEntry *wins = g_object_get_data (context_object, "wins");
GtkEntry *trigan = g_object_get_data (context_object, "trigan");
GtkWidget iter;
GtkTextIter iterscrll;
GtkTextMark *mark;
mark = gtk_text_buffer_get_insert(buffer);
gtk_text_buffer_get_iter_at_mark(buffer, &iterscrll, mark);
gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
trigan=0;
int i=0;
int k=0;
for (i=0; i<90; i=i+1)
{
while (trigan==1)
{
}
gchar * stuff = g_strdup_printf("%d"" [%d]\n", i, trigan);
/* Inserts buffer at position iter. */
gtk_text_buffer_insert(buffer, &iter, stuff, -1);
g_free(stuff);
/* Forcing. */
while (gtk_events_pending())
gtk_main_iteration();
/* Scrolls text_view the minimum distance such that mark is contained within the visible area of the widget. */
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(wins), mark);
for (k=0; k<50000000; k=k+1)
{
k++;
}
k=0;
}
}
My logic say that whit this value of trigan=1 the
while (trigan==1)
{
}
should "stop" the function RUN, but it doesn't.
Help please!
yes, your assumption is correct but take a look at this extract of your code:
triga=0;
int i=0;
int k=0;
for (i=0; i<90; i=i+1)
{
while (triga==1)
{
}
as you see, triga is defined, assigned to 0 an never manipoulated in between before the while... so the condition while (triga==1) is false...
that is the reason..

How to use visibility of any widget on gtk?

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;
}

Resources