How to set placeholder text in GtkEntry - c

I tried this example:
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar * filename) {
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if(!pixbuf) {
fprintf(stderr, "%s\n", error->message); g_error_free(error);
}
return pixbuf;
}
void implement() {
printf("HI");
}
int main( int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *frame;
GtkWidget *label;
GtkWidget *text;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "New Message");
gtk_window_set_default_size(GTK_WINDOW(window), 310, 390);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("web.png"));
frame = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), frame);
text = gtk_entry_new();
gtk_entry_set_max_length (GTK_ENTRY (text), 0);
gtk_entry_set_width_chars (GTK_ENTRY (text), 37);
gtk_entry_set_placeholder_text(GTK_ENTRY (text), "Send a message");
gtk_fixed_put(GTK_FIXED(frame), text, 2, 360);
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_main();
return 0;
}
but getting error : undefined reference togtk_entry_set_placeholder_text'`

Make sure your GTK+ version is 3.2 or later, since that's when that particular function was added.

Related

create an headbar with about dialog in GTK+3

I'm trying to create a head bar that should contain an "About" labelled button to show up a dialog when clicked.
#include <gtk/gtk.h>
static void activate_about(GtkWidget *window, gpointer data);
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *about_button;
GtkWidget *headbar;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
headbar = gtk_header_bar_new();
gtk_header_bar_set_title (GTK_HEADER_BAR (headbar), "Welcome to GTK");
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headbar), TRUE);
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
about_button = gtk_button_new_with_mnemonic("_About");
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_container_add(GTK_CONTAINER(vbox), headbar);
gtk_container_add(GTK_CONTAINER(headbar), about_button);
g_signal_connect(about_button, "clicked",
G_CALLBACK(activate_about), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void activate_about(GtkWidget *window, gpointer data) {
const gchar *authors[] = {"ad Chi", NULL};
gtk_show_about_dialog(GTK_WINDOW(window),
"program-name", "jjkjk",
"version", "0.0.1",
"copyright", "(C) 2017 ad Chi",
"license-type", GTK_LICENSE_GPL_3_0,
"website", "https://github.com/kjk",
"comments", "Totally kj",
"authors", authors,
"documenters", NULL,
"logo-icon-name", "start-here",
"title", "About kj kj",
NULL);
return;
}
The first issue is that now I end up with two bars the window one and that of the headbar widget. I need just one. The second problem is, when I click the button I get
(button:1727): GLib-GObject-WARNING **: 17:59:47.965: invalid cast from 'GtkButton' to 'GtkWindow'
(button:1727): Gtk-CRITICAL **: 17:59:47.982: gtk_window_set_transient_for: assertion 'parent == NULL || GTK_IS_WINDOW (parent)' failed. I am new to GTK. I suppose that gtk_show_about_dialog(GTK_WINDOW(window)... is not the proper widget to use.
#include <gtk/gtk.h>
static void activate_about(GtkWidget *widget, gpointer window);
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *about_button;
GtkWidget *headbar;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
headbar = gtk_header_bar_new();
gtk_header_bar_set_title (GTK_HEADER_BAR (headbar), "Welcome to GTK");
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headbar), TRUE);
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
about_button = gtk_button_new_with_mnemonic("_About");
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_window_set_titlebar(GTK_WINDOW(window), headbar);
gtk_header_bar_pack_start(GTK_HEADER_BAR(headbar), about_button);
g_signal_connect(about_button, "clicked",
G_CALLBACK(activate_about), window);
g_signal_connect_swapped (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void activate_about(GtkWidget *widget, gpointer window) {
const gchar *authors[] = {"ad Chi", NULL};
gtk_show_about_dialog(GTK_WINDOW(window),
"program-name", "jjkjk",
"version", "0.0.1",
"copyright", "(C) 2017 ad Chi",
"license-type", GTK_LICENSE_GPL_3_0,
"website", "https://github.com/kjk",
"comments", "Totally kj",
"authors", authors,
"documenters", NULL,
"logo-icon-name", "start-here",
"title", "About kj kj",
NULL);
return;
}

How to hide a .ui file and show another .ui file in GTK+

I have a button on my window on GTK+ 3. When the button is clicked, a window from another ui file should be opened and the current window's ui should be deleted (Hide). But I don't know how to do so.I am really new to Gtk+ programming on linux.
this is my .c file:
#include <gtk/gtk.h>
static void
buttonClicked(GtkWidget *widget,
gpointer data)
{
//here I need to open another window and close the current one
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GObject *window;
GObject *button;
GError *error = NULL;
gtk_init (&argc, &argv);
builder = gtk_builder_new();
if(gtk_builder_add_from_file(builder, "main-window.ui", &error) == 0)
{
g_printerr ("Error loading file: %s\n", error->message);
g_clear_error (&error);
return 1;
}
window = gtk_builder_get_object (builder, "window");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
button = gtk_builder_get_object (builder, "buttonOpen");
g_signal_connect (button, "clicked", G_CALLBACK (buttonClicked), NULL);
gtk_main ();
return 0;
}
Use gtk_widget_show_all () and gtk_widget_hide ().
#include <gtk/gtk.h>
static void
buttonClicked(GtkWidget *widget, GObject* window)
{
GtkBuilder *builder;
GObject *window2;
GError *error = NULL;
builder = gtk_builder_new();
if(gtk_builder_add_from_file(builder, "second-window.ui", &error) == 0)
{
g_printerr ("Error loading file: %s\n", error->message);
g_clear_error (&error);
return;
}
window2 = gtk_builder_get_object (builder, "window");
gtk_widget_show_all(GTK_WIDGET(window2));
gtk_widget_hide(GTK_WIDGET(window));
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GObject *window;
GObject *button;
GError *error = NULL;
gtk_init (&argc, &argv);
builder = gtk_builder_new();
if(gtk_builder_add_from_file(builder, "main-window.ui", &error) == 0)
{
g_printerr ("Error loading file: %s\n", error->message);
g_clear_error (&error);
return 1;
}
window = gtk_builder_get_object (builder, "window");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
button = gtk_builder_get_object (builder, "buttonOpen");
g_signal_connect (button, "clicked", G_CALLBACK (buttonClicked), window);
//some widgets don't draw if their parent window was not "show alled"
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main ();
return 0;
}
Note that gpointer is actually a void* so you can pass to your function whatever you like.

How can I create new window in GTK after click?

I'm new at GTK, and I was wondering how can I create a new window after a click button. I've got this function
void cb_create_entry(GtkWidget *, gpointer);
int create_window(int argc, char *argv[]){
GtkWidget *p_window = NULL;
GtkWidget *p_main_box = NULL;
GtkWidget *p_button[5];
gtk_init (&argc, &argv);
//Create window
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Hello");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_main_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_main_box);
{
p_button[0] = gtk_button_new_with_label("Create entry");
g_signal_connect(G_OBJECT(p_button[0]), "clicked",
G_CALLBACK(cb_create_entry), NULL);
gtk_box_pack_start(GTK_BOX(p_main_box), p_button[0], FALSE, FALSE, 0);
}
gtk_widget_show_all(p_window);
gtk_main ();
return EXIT_SUCCESS;
and callback.h
#ifndef CALLBACK_H_INCLUDED
#define CALLBACK_H_INCLUDED
#include <gtk/gtk.h>
void cb_create_entry(GtkWidget *p_widget, gpointer user_data){
gtk_button_released(p_widget);
GtkWidget *p_window;
GtkWidget *p_v_box;
GtkWidget *p_entry;
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Create DB");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_v_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_v_box);
p_entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(p_v_box), p_entry, TRUE, FALSE, 0);
}
and main
int main(int argc, char const *argv[]) {
create_window(argc, argv);
return 0;
}
But it doesn't work. I'd like to create a new window with an input. But when I click on button, nothing happens.
I'm a bit confused on how you laid out your file structure. Since there's no input on that I'll assume that the file with create_window function is the same where you have main. Then, callback.h should not have implementation code.
Nevertheless, i don't see any gtk_widget_show or gtk_widget_show_all calls and not sure you suppressed or just missed them. I'll assume the later because by your description it seems that you can see the initial window.
It's also missing a call to gtk_main.
Adding GtkWidget show functions and gtk_main to your code, it does work like expected:
Lets call the first file main.c :
#include <gtk/gtk.h>
#include "callback.h"
void cb_create_entry(GtkWidget *, gpointer);
int create_window(int argc, char *argv[]){
GtkWidget *p_window = NULL;
GtkWidget *p_main_box = NULL;
GtkWidget *p_button[5];
gtk_init (&argc, &argv);
//Create window
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Hello");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_main_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_main_box);
p_button[0] = gtk_button_new_with_label("Create entry");
g_signal_connect(G_OBJECT(p_button[0]), "clicked",
G_CALLBACK(cb_create_entry), NULL);
gtk_box_pack_start(GTK_BOX(p_main_box), p_button[0], FALSE, FALSE, 0);
gtk_widget_show_all(p_window);
}
int main (int argc, char *argv[]) {
create_window(argc, argv);
gtk_main ();
return 0;
}
And the other file callbacks.h :
#include <gtk/gtk.h>
void cb_create_entry(GtkWidget *p_widget, gpointer user_data){
gtk_button_released(p_widget);
GtkWidget *p_window;
GtkWidget *p_v_box;
GtkWidget *p_entry;
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Create DB");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_v_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_v_box);
p_entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(p_v_box), p_entry, TRUE, FALSE, 0);
gtk_widget_show_all(p_window);
}
Then compiling with:
gcc -o test main.c callback.h `pkg-config --cflags --libs gtk+-3.0`
will result in a window with a button, which after being pressed will create and show a new window with a GtkEntry:
now callback.h looks like that :
int cb_create_entry(GtkWidget *p_widget, gpointer user_data){
GtkWidget *p_window = NULL;
GtkWidget *p_entry = NULL;
GtkWidget *p_button = NULL;
GtkWidget *p_main_box = NULL;
GtkWidget *p_label = NULL;
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Create entry");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
g_signal_connect (G_OBJECT (p_window), "destroy", G_CALLBACK (cb_quit), NULL);
p_main_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_main_box);
p_label = gtk_label_new("Please, name your DB");
gtk_container_add(GTK_CONTAINER(p_main_box), p_label);
p_entry = gtk_entry_new();
gtk_container_add(GTK_CONTAINER(p_main_box), p_entry);
p_button = gtk_button_new_with_label("Create !");
gtk_container_add(GTK_CONTAINER(p_main_box), p_button);
{
GtkWidget *p_quit = NULL;
p_quit = gtk_button_new_with_label("Quit");
g_signal_connect(G_OBJECT(p_quit), "clicked", G_CALLBACK(cb_quit), NULL);
gtk_box_pack_start(GTK_BOX(p_main_box), p_quit, FALSE, FALSE, 0);
}
//gtk_widget_show(p_entry);
gtk_widget_show_all(p_window);
return EXIT_SUCCESS;}

C - creating a menu with gtk3

I'm trying to make a simple menu in gtk3. I was looking at the official documentation and other code I found in the web, but still I am not able to get it to work. The menu does not appear.
I would appreciate any help. Thank you.
This is the code I have so far:
#include <stdio.h>
#include <gtk/gtk.h>
//#include "minefield.h"
enum difficulty {BEGINNER, ADVANCED, EXPERT};
static void activate(GtkApplication* app, gpointer user_data);
GdkPixbuf *create_pixbuf(const gchar * filename);
void newGame();
void openSetupDialog();
void openOptionDialog();
int main(int argc, char *argv[]) {
GtkApplication *app;
int status;
app = gtk_application_new("my.ne.sweeper", 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;
}
static void activate(GtkApplication* app, gpointer user_data) {
GdkPixbuf *app_icon;
GtkWidget *app_window;
GtkWidget *app_box;
GtkWidget *menubar;
GtkWidget *gameMenu;
GtkWidget *gameMenu_game;
GtkWidget *gameMenu_newGame;
GtkWidget *gameMenu_setup;
GtkWidget *gameMenu_options;
GtkWidget *gameMenu_quit;
GtkWidget *sep;
// App_window
app_window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(app_window), "Minesweeper");
gtk_window_set_default_size(GTK_WINDOW(app_window), 600, 400);
gtk_window_set_position(GTK_WINDOW(app_window), GTK_WIN_POS_CENTER);
// App_box
app_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(app_window), app_box);
// App_icon
app_icon = create_pixbuf("../img/app_icon.svg");
gtk_window_set_icon(GTK_WINDOW(app_window), app_icon);
// Menubar
menubar = gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(app_box), menubar, FALSE, FALSE, 0);
// Start menu
gameMenu = gtk_menu_new();
gameMenu_game = gtk_menu_item_new_with_label("Game");
gameMenu_newGame = gtk_menu_item_new_with_label("New Game");
gameMenu_setup = gtk_menu_item_new_with_label("Setup");
gameMenu_options = gtk_menu_item_new_with_label("Options");
gameMenu_quit = gtk_menu_item_new_with_label("Quit");
sep = gtk_separator_menu_item_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(gameMenu_game), gameMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), gameMenu_game);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_newGame);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_setup);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_options);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), sep);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_quit);
gtk_widget_show_all(app_window);
// Signalhandlers
g_signal_connect(app_window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(gameMenu_newGame, "activate", G_CALLBACK(newGame), NULL);
g_signal_connect(gameMenu_setup, "activate", G_CALLBACK(openSetupDialog), NULL);
g_signal_connect(gameMenu_options, "activate", G_CALLBACK(openOptionDialog), NULL);
g_signal_connect(gameMenu_quit, "activate", G_CALLBACK(gtk_main_quit), NULL);
g_object_unref(app_icon);
}
GdkPixbuf *create_pixbuf(const gchar * filename) {
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if (!pixbuf) {
fprintf(stderr, "[!] %s\n", error->message);
g_error_free(error);
}
return pixbuf;
}
void newGame() {
fprintf(stdout, "[*] %s\n", "new game..");
}
void openSetupDialog() {
fprintf(stdout, "[*] %s\n", "open setup..");
}
void openOptionDialog() {
fprintf(stdout, "[*] %s\n", "open options..");
}

How do I make a GTK3 image-in-a-window shrinkable?

I have a simple GTK3 app that displays an image from a file in a window.
When you resize the window, the image is scaled in the expose callback to fit the window.
However, once the window has grown, you can't shrink it again; the resize handles only let you make the window ever bigger.
With GTK2 it was trivial to allow grow and shrink with gtk_window_set_policy(w,1,1,1).
How can the same effect be achieved in GTK3?
Here's the ever-growing code example:
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
gboolean resize_image(GtkWidget *widget, GdkEvent *event, void *data)
{
GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(widget));
if (pixbuf == NULL)
{
g_printerr("Failed to get pixbuf\n");
return 1;
}
pixbuf = gdk_pixbuf_scale_simple(pixbuf,
widget->allocation.width, widget->allocation.height,
GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(widget), pixbuf);
return FALSE;
}
int main(int argc, char **argv)
{
GtkWidget *window = NULL;
GtkWidget *image = NULL;
if (argc < 2 || argc > 3)
{
g_printerr("Usage: %s <image>\n", argv[0]);
return 1;
}
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
image = gtk_image_new_from_file(argv[1]);
if (image == NULL)
{
g_printerr("Could not open \"%s\"\n", argv[1]);
return 1;
}
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(image, "expose-event", G_CALLBACK(resize_image), NULL);
gtk_container_add(GTK_CONTAINER(window), image);
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main();
return 0;
}
Eric Cecashon on the gtk-list mailing list suggests using a cairo drawing area inside a 1x1 grid container, which works fairly well:
/*
gcc -Wall da_resize.c -o da_resize `pkg-config gtk+-3.0 --cflags --libs`
Tested on Ubuntu16.04, GTK3.18.
*/
#include<gtk/gtk.h>
gboolean draw_picture(GtkWidget *da, cairo_t *cr, gpointer data)
{
gint width=gtk_widget_get_allocated_width(da);
gint height=gtk_widget_get_allocated_height(da);
GdkPixbuf *temp=gdk_pixbuf_scale_simple((GdkPixbuf*)data, width, height, GDK_INTERP_BILINEAR);
gdk_cairo_set_source_pixbuf(cr, temp, 0, 0);
cairo_paint(cr);
g_object_unref(temp);
return FALSE;
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Resize Picture");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//Needs a valid picture.
GdkPixbuf *pixbuf=gdk_pixbuf_new_from_file(argc>1 ? argv[1] : "image.jpg", NULL);
GtkWidget *da1=gtk_drawing_area_new();
gtk_widget_set_hexpand(da1, TRUE);
gtk_widget_set_vexpand(da1, TRUE);
g_signal_connect(da1, "draw", G_CALLBACK(draw_picture), pixbuf);
GtkWidget *grid=gtk_grid_new();
gtk_grid_attach(GTK_GRID(grid), da1, 0, 0, 1, 1);
gtk_container_add(GTK_CONTAINER(window), grid);
gtk_widget_show_all(window);
gtk_main();
g_object_unref(pixbuf);
return 0;
}

Resources