I am coding a GUI (using GTK3) for a simple program that performs a simulation and plots the requested graph (using gnuplot).
When I'm using only gnuplot, I have no problem. The graph looks exactly like I want. However, when I try using this same code from GTK, it doesn't work anymore. It truncates all my value. Why ? What should I do to fix this?
This is the expected result (gnuplot without GTK):
And this is the actual result (gnuplot with GTK) :
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
FILE *gp = popen("gnuplot -persist", "w");
fprintf(gp, "plot '-' using 1:2 with lines\n");
int i;
for(i = 0; i < 13; i++){
fprintf(gp, "%d %f\n", i, 0.1*i);
}
pclose(gp);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Related
I have a simple GTK app written in C that segfaults on the line window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
Here is the code:
#include <gtk/gtk.h>
int main(int argc, char **argv) {
GtkApplication *app = NULL;
GtkWidget *window = NULL;
app = gtk_application_new("com.github.Toothless204", G_APPLICATION_FLAGS_NONE);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(app, GTK_WINDOW(window));
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
I have googled around to find an answer but didn't find anything that actually provided an answer as to what the problem could be
Problem: tried to create a window before the GTK+ initialization functions was called by the GtkApplication.
Before using GTK+, you need to initialize it.
https://developer.gnome.org/gtk3/stable/gtk3-General.html
#include <gtk/gtk.h>
int main(int argc, char **argv) {
GtkWidget *window = NULL;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
gtk_main();
return 0;
}
For the same reason GtkApplication windows must be added after the GApplication 'startup' signal has been emitted.
https://wiki.gnome.org/HowDoI/GtkApplication
#include <gtk/gtk.h>
static void activate (GApplication *app, gpointer user_data) {
GtkWidget *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(window));
gtk_widget_show (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new ("com.github.Toothless204", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
I would like to update a GtkLabel with data imported from a text file, but it doesn't evaluate \n as a newline character, as it should normally do.
The file contains (for example):
This is a\nnewline.
How do I get this \n understood by GtkLabelĀ ?
This is my complete code:
#include <gtk/gtk.h>
#include <string.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *label, *window;
gchar* test_char;
ssize_t len;
FILE* fh;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Test GTK");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 100);
label = gtk_label_new ("");
fh = fopen ("file.txt", "r");
getline (&test_char, &len, fh);
gtk_label_set_text (GTK_LABEL (label), test_char);
gtk_container_add (GTK_CONTAINER (window), label);
gtk_widget_show_all (window);
fclose (fh);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
The key is converting the literal \n to \n.
There are two ways to do this I can come up with (I leave out the file reading part):
Text in test file:
That's\na\ntest,\nfolks!
1.
gchar *new_txt = g_strcompress (test_char);
gtk_label_set_text (GTK_LABEL (label), new_txt);
g_free (new_txt);
2.
GRegex *regex = g_regex_new ("\\\\n", 0, 0, NULL);
gchar *new_txt = g_regex_replace (regex, test_char, -1, 0, "\\n", 0, NULL);
gtk_label_set_text (GTK_LABEL (label), new_txt);
g_free (new_txt);
g_regex_unref (regex);
Note that you have to escape twice: first for C, then for the regex engine, so that the latter sees: replace \\n with \n. You have to escape both backslashes of \\n for C, that's why you get four backslashes in the string that has to be replaced.
Result for both:
Both ways need a newly-allocated string to store the converted text, so you have to free the memory after usage.
I have a problem with quitting a gtk application. The function call of g_application_quit results in the subsequent error:
GLib-GIO-CRITICAL **: g_application_quit: assertion 'G_IS_APPLICATION (application)' failed
The code snippet looks like this:
g_signal_connect(app_window, "destroy", G_CALLBACK(g_application_quit), app);
I tried this also, but still throws the same error:
g_signal_connect(app_window, "destroy", G_CALLBACK(g_application_quit), G_APPLICATION(app));
The app got initialized as:
GtkApplication *app = gtk_application_new("my.ne.sweeper", G_APPLICATION_FLAGS_NONE);
Any help is appreciated. Thank you.
You don't need to connect g_application_quit to window's destroy signal explicitly if You are using G_APPLICATION, it is done automatically.
Here goes the minimalistic example:
#include <gtk/gtk.h>
static void activate (GtkApplication* app, gpointer data) {
GtkWidget *window;
window = gtk_application_window_new(app);
gtk_window_set_default_size(GTK_WINDOW (window), 400, 200);
gtk_widget_show_all(window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new("your.app.name", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
I am trying to change the cursor of a window dynamically with GTK3 but gtk_widget_get_parent_window doesn't seem to work.
Could someone please point out what I'm doing wrong? Thanks!
// https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
// minimal example
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
// Here \/\/\/\/\/ .
GdkWindow* w = gtk_widget_get_parent_window(window);
GdkCursor* c = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_WATCH);
gdk_window_set_cursor(w, c);
// /\/\/\/\/\ .
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
(main.exe:16508): Gdk-CRITICAL **: gdk_window_set_cursor: assertion
'GDK_IS_WINDOW (window)' failed
I am using GTK 3.16 with msys2
Many thanks in advance.
Extending #andlabs comment
Any attempt to change the cursor needs to be done after the widget has been added to the widget hierarchy or in GTK terms realized.
Calling gtk_widget_get_parent_window() or even gtk_widget_get_window() before a realize event has been fired for the widget will result in a NULL pointers in both cases.
Like #andlabs it is safer to use gtk_widget_get_window() in combination with a GtkWindow.
The solution.
static GdkWindow* G_WINDOW = 0;
static GdkCursor* G_CURSOR = 0;
// call after WindowRealize()
void changecursor()
{
assert(G_WINDOW != NULL);
gdk_window_set_cursor(G_WINDOW, G_CURSOR);
}
static void WindowRealize(GtkWidget *window, gpointer data)
{
G_CURSOR_HAND = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_HAND2);
G_WINDOW = gtk_widget_get_window(window);
}
static void activate(GtkApplication* app,gpointer user_data)
{
GtkWidget *window = gtk_application_window_new(app);
...
g_signal_connect(window, "realize", G_CALLBACK(WindowRealize), NULL);
gtk_widget_show_all (window);
}
I'm running a basic GTK app from the GTK website's tutorials, and I'm getting the following warning:-
*** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.
I've installed the gtk+ and gtk+3 packages with brew. Here is the code from the file:-
#include
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
I'm running OS X 10.10.5, MacBook Pro 13in Retina.
Any ideas? Thanks!