gtk_drawing_area_size first parameter - c

Hello guys I'm using C and GTK+ 2 I want to make a simple paint program like MS program but by these two tools only okay I just started and I want your hands to reach the end :)
look to my code here
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *drawingArea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(gtk_main_quit), G_OBJECT(window));
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit),
G_OBJECT(window));
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
drawingArea = gtk_drawing_area_new();
/*The problem is in the next line */
gtk_drawing_area_size(G_OBJECT(drawingArea), 200, 200);
gtk_container_add(GTK_CONTAINER(window), drawingArea);
gtk_widget_show(drawingArea);
gtk_widget_show(window);
gtk_main();
return 0;
}
my problem is in the commented line
gtk_drawing_area_size(G_OBJECT(drawingArea),200,200);
the error when compiling
ibrahim#ibrahim-PC:~/Desktop$ gcc main.cpp -o base `pkg-config --cflags --libs gtk+-2.0`
main.cpp: In function ‘int main(int, char**)’:
main.cpp:14:52: error: cannot convert ‘GObject* {aka _GObject*}’ to ‘GtkDrawingArea* {aka _GtkDrawingArea*}’ for argument ‘1’ to ‘void gtk_drawing_area_size(GtkDrawingArea*, gint, gint)’
So Please help me

That's a common gotcha in GTK+. You have to cast the widget to the type that exposes the method (i.e. the implementing type). You should write:
gtk_drawing_area_size(GTK_DRAWING_AREA(drawingArea), 200, 200);
Instead of:
gtk_drawing_area_size(G_OBJECT(drawingArea), 200, 200);
Because the GObject type does not support the gtk_drawing_area_size() method, but the GtkDrawingArea type does.
(Actually, it's more like gtk_drawing_area_size() does not support taking a GObject instance, since GTK+'s object oriented nature is abstracted that way in C.)

Related

How to hide console window from Windows Gtk C programs compiled with cl

Due to unstable and unreliable mingw / MSYS2 behaviours on Windows 11 (x86_64), I have decided to use the Windows-native cl compiler bundled with Visual Studio to compile Gtk 3 programs written in C. I am using Gtk 3 built with the gvsbuild script. My Gtk 3 test program compiles successfully with the cl compiler, using a compiler command-file / response-file for the compile and linker options, but when I run the compiled Gtk 3 program, I get a console window behind it.
I have searched tirelessly on StackOverflow as well as the rest of the internet and have not found a solution that addresses my cl-specific situation.
I have tried using /SUBSYSTEM:WINDOWS which causes a compiler error because the compiler can't find WinMain hidden by Gtk. I have tried /D"subsystem,windows", /Dmwindows as well as /Dsubsystem=gui with and without the - in front, but none solve the issue.
I have also tried this bit of code, which causes a huge amount of errors because the compiler can't find Windows-specific code hidden by Gtk:
#ifdef _WIN32
AllocConsole();
ShowWindow(GetConsoleWindow(), SW_HIDE);
#endif
Here is the test program:
#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), "Hello internet from Gtk Windows!");
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've elected not to post the compiler command-file contents as it's quite lengthy.
For those who may answer "Just use mingw, MSYS2, cygwin, etc" I'd rather stay with a cl-specific solution please.
Is there a cl-specific option for suppressing the console window when compiling and running C Gtk 3 programs on Windows?
A big thanks to Tony Lee for the recommendation! This code is working properly after specifying /SUBSYSTEM:WINDOWS in the linker options:
#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), "Hello internet from Gtk Windows!");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}
#ifdef _WIN32
int WinMain (void * hInstance, void * hPrevInstance, char ** argv, int nCmdShow)
#else
int main (int argc, char ** argv)
#endif
{
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), 0, argv);
g_object_unref (app);
return status;
}
It should be noted that I had to put a zero for the argc value in g_application_run(), so that's another (minor) issue I'll have to figure out later, but if your Gtk program doesn't need to process command-line arguments, it's fine.
The VS 2022 help on /SUBSYSTEM under Windows says to use it when:
The application doesn't require a console, probably because it creates
its own windows for interaction with the user.
Which is exactly what's required here - There's a Raymon Chen article called "WinMain is just the conventional name for the Win32 process entry point" so when the OP found it undefined, it just needed to be declared instead of main. It documents the WinMain prototype as:
WinMain(HINSTANCE *, HINSTANCE *, char *, int)
However, MS documents the WinMain prototype without the * on HINSTANCE in an article called "WinMain: The Application Entry Point" as
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
You could include Windows.h but it doesn't appear there's a requirement to use hInstance and hPrevInstance so void * should work as a substitute.

Cannot find -1dwmapi error: 1d returned 1 exit status on CodeBlocks, basic GCC application

I am working on my college project.
I am new to GCC, GTK and all related stuff.
I have successfully installed GTK on Windows 10 via MSYS2.
I have followed this tutorial:
https://www.youtube.com/watch?v=rUJFYOCbuDg
In the next part of tutorial,
I am using Codeblocks (as discussed in the tutorial):
https://www.youtube.com/watch?v=TlwWKzJFNqo&ab_channel=MichaelB.
When I copy paste this code in main.c in my project GTK3_Demo
#include <gtk/gtk.h>
static int counter = 0;
void greet(GtkWidget* widget, gpointer data)
{
// printf equivalent in GTK+
g_print("Welcome to GTK\n");
g_print("%s clicked %d times\n",
(char*)data, ++counter);
}
void destroy(GtkWidget* widget, gpointer data)
{
gtk_main_quit();
}
int main(int argc, char* argv[])
{
GtkWidget* window;
GtkWidget* button;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy",
G_CALLBACK(destroy), NULL);
/* Let's set the border width of the window to 20.
* You may play with the value and see the
* difference. */
gtk_container_set_border_width(GTK_CONTAINER(window), 20);
button = gtk_button_new_with_label("Click Me!");
g_signal_connect(GTK_OBJECT(button),
"clicked", G_CALLBACK(greet),
"button");
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
I get following error :
||=== Build: Debug in GTK3_Demo (compiler: GNU GCC Compiler) ===|
C:\Users\raman\Documents\GTK3_Demo\main.c||In function 'activate':|
C:\Users\raman\Documents\GTK3_Demo\main.c|23|warning: implicit declaration of function 'gtk_window_set_child' [-Wimplicit-function-declaration]|
ld.exe||cannot find -ldwmapi|
||error: ld returned 1 exit status|
||=== Build failed: 2 error(s), 1 warning(s) (0 minute(s), 2 second(s)) ===|

How to add gtk lib in Visual studio code?

I try to add gtk library to my file in Visual Studio code on my Arch Linux ,but it underlines "#include line and writes:
#include errors detected. Please update your includePath. Squiggles are disabled for this translation unit (/home/mikhailkhr/My projects/C projects/Test/Test.c).
cannot open source file "glibconfig.h" (dependency of "gtk/gtk.h")
It does compile this file with:
gcc `pkg-config gtk+-3.0 --cflags` ProgName.c `pkg-config gtk+-3.0 --libs`
But why does it underline this?
And how to fix this?
Thanks.
Sorse code:
#define _PROGRAM_NAME "whoami"
#include <stdlib.h>
#include <pwd.h>
#include <stdio.h>
#include <gtk/gtk.h>
const char *getUserName()
{
uid_t uid = geteuid();
struct passwd *pw = getpwuid(uid);
if (pw)
{
return pw->pw_name;
}
return "";
}
static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello %s\n", getUserName());
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *button_box;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);
button = gtk_button_new_with_label (getUserName());
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
gtk_container_add (GTK_CONTAINER (button_box), button);
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;
}
Add /usr/lib/glib-2.0/include/ to the include paths.
Basically one wants to add the output from pkg-config to the VSCode includes.
To dump the output on a shell, use:
echo $(pkg-config --libs --cflags gtk+-3.0)
If you want to provide pkg-config as a VSCode task argument see this answer.
I am happily using this VSCode extension with GCC and Clang.
Here is my gist to kick off coding GTK 3 in C with VSCode.
Happy hacking!
I added this to the include path inside .vscode/c_cpp_properties.json:
"includePath": [
"${workspaceFolder}/**",
"/usr/include/gtk-3.0",
"/usr/include/glib-2.0",
"/usr/lib/x86_64-linux-gnu/glib-2.0/include",
"/usr/include/pango-1.0",
"/usr/include/harfbuzz",
"/usr/include/cairo",
"/usr/include/gdk-pixbuf-2.0",
"/usr/include/atk-1.0"
],
If you need gtkmm:
"/usr/include/gtkmm-3.0",
"/usr/include/glibmm-2.4",
"/usr/include/sigc++-2.0",
"/usr/lib/x86_64-linux-gnu/sigc++-2.0/include",
"/usr/lib/x86_64-linux-gnu/glibmm-2.4/include",
"/usr/include/giomm-2.4/giomm",
"/usr/include/giomm-2.4",
"/usr/include/glibmm-2.4",
"/usr/include/glibmm-2.4/glibmm",
"/usr/lib/x86_64-linux-gnu/giomm-2.4/include",
"/usr/include/gdkmm-3.0",
"/usr/lib/x86_64-linux-gnu/gdkmm-3.0/include",
"/usr/include/pangomm-1.4",
"/usr/lib/x86_64-linux-gnu/pangomm-1.4/include",
"/usr/include/cairomm-1.0",
"/usr/include/freetype2",
"/usr/lib/x86_64-linux-gnu/gtkmm-3.0/include",
"/usr/lib/x86_64-linux-gnu/atkmm-1.6/include",
"/usr/include/atkmm-1.6"
If you open gtk/gtk.h (F12 go to definition):
You'll see a bunch of other red lines:
Which, generally saying, is your error message.
In most cases, if you open 1 of those header files , you'll see that some header path is missing (non related to gtk/ core , pango in this case):
Simply search the name (pango as example here) under your include directory (mine one is C:\msys64\mingw64\include under the Windows):
Now, when you're sure it's installed (install it in case of opposite answer) you need to create .vscode folder under your working-project directory and create a file c_cpp_properties.json
In this file you will tell to VSCode, where the required header files are stored:
{
"configurations": [
{
"name": "Win32",
"includePath": [ "C:\\msys64\\mingw64\\include\\pango-1.0" , "C:\\msys64\\mingw64\\include\\gtk-3.0" ,"C:\\msys64\\mingw64\\include", "C:\\msys64\\mingw64\\include\\glib-2.0"],
"intelliSenseMode": "gcc-x64",
"compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe",
"cStandard": "gnu11",
"cppStandard": "gnu++14"
}
],
"version": 4
}
(Full documentation about properties of the file you can find here)
Which solves one of the previous errors:
You should repeat and add those pathes into the includePath property untill it will be fully solved.

how to close GTK window with C

i was doing a small project where i had a a fullscreen GUI (Glade, GTK and C) and needed to give the user a way to close the screen (obviously the window manager was not available due to the window being fullscreen).
problem rices when i attempt to compile this piece of code
//close sidebar1
void on_window_sidebar1_back_clicked()
{
gtk_window_close (GtkWindow *window);
}
i receive the following error
/usr/bin/arm-linux-gnueabihf-gcc -c -g -O0 -Wall -pthread -pipe src/main.c `pkg-config --cflags --libs gtk+-3.0` -o main.o
src/main.c: In function 'on_window_sidebar1_back_clicked':
src/main.c:61:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'gtk_window_close'
gtk_window_close (GtkWindow *window);
^
src/main.c:61:20: error: expected expression before 'GtkWindow'
gtk_window_close (GtkWindow *window);
^
makefile:30: recipe for target 'main.o' failed
make: *** [main.o] Error 1
I tried to follow the documentation here, but seem to have failed badly
Does anyone have any ideas?
PS.
here is the full main.c if someone is intrested. Its my first attempt at C with gtk, so dont be too harsh, Thank you (=
#include <gtk/gtk.h>
GtkWidget *g_lbl_test;
GtkWidget *g_lbl_count;
int main(int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *window;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "glade/window_main.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
gtk_builder_connect_signals(builder, NULL);
//pointers for the labels (...used in button press)
g_lbl_test = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_test"));
g_lbl_count = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_count"));
g_object_unref(builder);
gtk_widget_show(window);
//gtk_window_fullscreen (GtkWindow *window); //dont know how to use this, same with gtk_window_close
gtk_main();
return 0;
}
//button press (just a test to make sure the window didnt freeze)
void on_btn_count_clicked()
{
static unsigned int count= 0;
char str_count[30] = {0};
gtk_label_set_text(GTK_LABEL(g_lbl_test), "Test success!");
count++;
sprintf(str_count, "%d", count);
gtk_label_set_text(GTK_LABEL(g_lbl_count), str_count);
}
//sidebar1
void on_sidebar_1_clicked()
{
GtkBuilder *builder;
GtkWidget *window;
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "glade/window_main.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window_sidebar1"));
gtk_widget_show(window);
}
//close sidebar1
void on_window_sidebar1_back_clicked()
{
gtk_window_close (GtkWindow *window);
}
// called on closing window
void on_window_main_destroy()
{
gtk_main_quit();
}
You probably should call
gtk_close_window(window);
But that window should come from somewhere.
(you may use a Gtk closure with a connection, or a callback with a client data, etc. or store somehow that window in a global variable, etc...)
Read more about C programming, then read a bit about callbacks and closures, then read more about GTK, and the signal mechanism of Gobject.
(your code shows a lot of confusion; I suggest to read the Getting started with GTK chapter after having read a good C programming book; BTW, I suggest to first write something which is not fullscreen, and only later improve it)
Don't forget to enable all warnings and debug info when compiling, that is compile with gcc -Wall -Wextra -g (and other arguments, perhaps using $(pkg-config --cflags gtk+-3.0) and also $(pkg-config --libs gtk+-3.0) for linking).
Attention! This does not follow any industrial standards and there are multiple flaws in this. I don't make any money or fame out of this so my only requirement is that it works. Take this into consideration when reading this!
I made edits to my code with what I learned and this seems to work:
void on_sidebar_1_clicked(int argc, char *argv[])
{
GtkBuilder *builder;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "glade/window_sidebar1.glade", NULL); //a whole own file for the second window
secondWindow = GTK_WIDGET(gtk_builder_get_object(builder, "window_sidebar1")); //secondWindow is defined at the start of main.c like this: "GtkWidget *secondWindow = NULL;" so that both callbacks can use it.
gtk_builder_connect_signals(builder, NULL);
gtk_widget_show(secondWindow);
gtk_main();
}
void on_sidebar1_back_clicked()
{
gtk_widget_destroy(GTK_WIDGET(secondWindow)); //here we call the widget to be closed instead of the window. Seems to work a lot better than the gtk_window_close, dunno why.
}
This code was written fast (and furious) so it's a little crude. I made some changes to my glade files as well, if someone needs a reference to those, please ask. As far as I care, this was the answer for my question. Also, I would recommend learning C and GTK (like Basile Starynkevitch said) before you start doing this kind of stuff, I didn't have the time nor motivation to do so.

Error: too few arguments to gtk_widget_new()

My O.S. is Ubuntu 12.04 (64 bit).
I am having an error when I compiled my gtk+ program on command line terminal:
second.cpp:8:43: error: too few arguments to function ‘GtkWidget* gtk_widget_new(GType, const gchar*, ...)’
/usr/include/gtk-2.0/gtk/gtkwidget.h:834:12: note: declared here
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window, *label;
window=gtk_widget_new(GTK_WINDOW_TOPLEVEL);
label=gtk_label_new("LabelName");
g_signal_connect(window, "delete-event",G_CALLBACK(gtk_main_quit), NULL);
gtk_container_add(GTK_CONTAINER(window), label);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Please help me to rectify the error, this program is executing good when I write the program without the label Widget.
It is window = gtk_window_new(GTK_WINDOW_TOPLEVEL), not window = gtk_widget_new(GTK_WINDOW_TOPLEVEL).

Resources