I have a pop-up window (created using the WINDOW_POPUP type) which contains some widgets on it, including a text entry. The problem is that the entry doesn't get the focus when I click on it, so I can't type anything. Is there any flag I have to set to allow the window to get the keyboard focus?
You can not use WINDOW_POPUP for gtk-windows that require the focus. Instead you should use a GtkWindow with type GTK_WINDOW_TOPLEVEL and call the next functions (or methods)
GtkWindow *result = g_object_new(GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, NULL);
gtk_widget_set_can_focus(result, TRUE);
gtk_window_set_decorated(GTK_WINDOW(result), FALSE);
gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
gtk_window_set_transient_for(GTK_WINDOW(result), main_top_level_window);
This worked for me ... unfortunately the icon in the window-list blinks short when this 'popup' is destroyed
Despite the previous answers and the GTK Reference, it is possible to grab the keyboard focus when using a GTK_WINDOW_POPUP. You need to connect to the "show" event...
GtkWindow *w = gtk_window_new(GTK_WINDOW_POPUP);
g_signal_connect(G_OBJECT(w), "show", G_CALLBACK(on_window_show), NULL);
... with a callback that tries to grab the keyboard:
static void on_window_show(GtkWidget *w, gpointer user_data) {
/* grabbing might not succeed immediately... */
while (gdk_keyboard_grab(w->window, FALSE, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS) {
/* ...wait a while and try again */
sleep(0.1);
}
}
That works for me pretty well.
#include <gtk/gtk.h>
static gboolean delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
g_print ("delete event occurred\n");
gtk_main_quit ();
return TRUE;
}
static void destroy( GtkWidget *widget,
gpointer data )
{
gtk_main_quit ();
}
int main( int argc,
char *argv[] )
{
GtkWidget *window;
GtkWidget *windowpopup;
GtkWidget *button;
gtk_init (&argc, &argv);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
windowpopup = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_transient_for(GTK_WINDOW(windowpopup),GTK_WINDOW(window));
gtk_window_set_destroy_with_parent(GTK_WINDOW(windowpopup),TRUE);
gtk_widget_show (windowpopup);
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (destroy), NULL);
/* Creates a new button with the label "Hello World". */
button = gtk_button_new_with_label ("Hello World");
g_signal_connect_swapped (G_OBJECT (button), "clicked",
G_CALLBACK (gtk_widget_destroy),
G_OBJECT (window));
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main ();
return 0;
}
Related
How can I set the font name and size for a text_view? Or do I have to set the font information at the buffer or at the window? Do I have to create some sort of style-sheet?
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *view;
GtkTextBuffer *buffer;
gtk_init(&argc, &argv);
view = gtk_text_view_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_window_set_default_size(GTK_WINDOW(window), 350, 300);
gtk_container_add(GTK_CONTAINER(window), view);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
The following code works.
my.c
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *view;
GtkTextBuffer *buffer;
GtkWidget *window;
GdkDisplay *display;
GdkScreen *screen;
GtkCssProvider *provider;
GError *error;
gtk_init(&argc, &argv);
view = gtk_text_view_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
provider = gtk_css_provider_new();
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
error = NULL;
gtk_css_provider_load_from_file (provider, g_file_new_for_path("my.css"), &error);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_window_set_default_size(GTK_WINDOW(window), 350, 300);
gtk_container_add(GTK_CONTAINER(window), view);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
my.css
GtkTextView
{
font:Monospace 10;
}.
I know it is 2 years old question but in case someone encounter any issues.
Note, that Pango syntax for the font is deprecated in Gtk+3.
If you want to use GtkSourceView:
#include <gtksourceview/gtksource.h>
must be installed separately and compiled with
`pkg-config --cflags --libs gtksourceview-3.0`
or use regular GtkTextView
GtkCssProvider *cssProvider;
GtkSourceView *view;
GError *error = NULL;
GtkStyleContext *context;
/* new css provider */
cssProvider = gtk_css_provider_new();
view = GTK_SOURCE_VIEW(gtk_source_view_new ());
/* widget name for css syntax */
gtk_widget_set_name (GTK_WIDGET(view), "cssView");
/* load css file */
gtk_css_provider_load_from_path (cssProvider, "main.css", &error);
/* get GtkStyleContext from widget */
context = gtk_widget_get_style_context(GTK_WIDGET(view));
/* finally load style provider */
gtk_style_context_add_provider(context,
GTK_STYLE_PROVIDER(cssProvider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
and "main.css" file in the same directory
#cssView {
font: 15px "Monospace";
color: #ff0000; /*in case you need red color*/
}
Actually in Gtk+3 you can add and remove CSS classes in very easy way:
in one callback you need to call:
gtk_style_context_add_class(context, "redFonts");
then in another one:
gtk_style_context_remove_class(context, "redFonts");
your "main.css" should be like:
#tab1Content {
font: 15px "Monospace";
}
.redFonts{
color: #ff0000;
}
How to get slider value in GTK?
#include <gtk/gtk.h>
#include <stdio.h>
#include <string.h>
GtkWidget *speed_sld,*speed_label;
static void transmit (GtkWidget *widget,gint *data)
{
float val = gtk_scale_get_digits(data);
g_print("Val is %f \n",val);
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *window;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "./ECU.glade", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
//g_signal_connect (window, "destroy", G_CALLBACK (on_window_destroy), NULL);
speed_sld = GTK_WIDGET (gtk_builder_get_object (builder, "scale1"));
speed_label = GTK_WIDGET (gtk_builder_get_object (builder, "label1"));
g_signal_connect (speed_sld, "value-changed", G_CALLBACK (transmit), NULL);
gtk_widget_show_all (window);
gtk_main ();
}
How can i print slider value in transmit function?I tried printing data,*data etc how can i get the values inside function
data is a pointer to whatever data was provided in g_signal_connect (you provided NULL), so that doesn't make sense.
I'm guessing you got confused by looking at GtkScale documentation: remember that you also need to look at the parent widgets API, in this case GtkRange. This should work:
static void transmit (GtkRange *range, gpointer data)
{
g_print ("current value is %f\n", gtk_range_get_value (range));
}
Everybody, Hello.
I'm new to gtk+ and want to ask a newbie question.
I want make a software of gtk2.10 in arm. My code is followed.
GtkWidget *windowmain = NULL;
GtkWidget *thebox = NULL;
GtkWidget *boxmain = NULL;
GtkWidget *boxtreeviewlist = NULL;
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
boxmain = createmain();
thebox = boxmain;
boxtreeviewlist = createtreeviewlist();
g_object_ref_sink(boxmain);
g_object_ref_sink(boxtreeviewlist);
windowmain = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(windowmain), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(windowmain), WINDOW_DEFAULT_WIDTH_SIZE, WINDOW_DEFAULT_HEIGTH_SIZE);
g_signal_connect(G_OBJECT(windowmain), "delete_event", G_CALLBACK(on_delete_event), NULL);
gtk_container_add(GTK_CONTAINER(windowmain), boxmain);
gtk_widget_show_all(windowmain);
gtk_main();
return TRUE;
}
GtkWidget* createmain()
{
GtkWidget *box = NULL;
GtkWidget *framestatus = NULL;
GtkWidget *framebutton = NULL;
GtkWidget *scroll = NULL;
GtkWidget *textview = NULL;
box = gtk_vbox_new(FALSE, 10);
framestatus = create_frame_status(TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), framestatus, FALSE, TRUE, 0);
scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
textview = gtk_text_view_new();
gtk_container_add(GTK_CONTAINER(scroll), textview);
framebutton = main_create_button_box(GTK_BUTTONBOX_EDGE, "");
gtk_box_pack_start(GTK_BOX(box), framebutton, FALSE, TRUE, 0);
return box;
}
GtkWidget* createtreeviewlist()
{
GtkWidget *box = NULL;
GtkWidget *framebutton = NULL;
GtkCellRenderer* renderer = NULL;
GtkTreeViewColumn* column = NULL;
box = gtk_vbox_new(FALSE, 0);
list_store = gtk_list_store_new(STANDARD_LIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
gtk_box_pack_start(GTK_BOX(box), treeview, TRUE, TRUE, 0);
framebutton = treeviewlist_create_button_box(GTK_BUTTONBOX_EDGE, "");
gtk_box_pack_start(GTK_BOX(box), framebutton, FALSE, TRUE, 0);
return box;
}
void show_box(GtkWidget *box)
{
gtk_container_remove(GTK_CONTAINER(windowmain), thebox);
gtk_container_add(GTK_CONTAINER(windowmain), box);
thebox = box;
gtk_widget_show_all(windowmain);
}
In the Ubuntu10.0.04, it's work well. Use X11.
But in the arm, when show boxmain, in other words,use (show_box) to switch boxtreeviewlist to boxmain, in the windowmain I can look image of boxtreeviewlist. Use Directfb.
Can anybody help me? Thanks.
You never add boxtreeviewlist to a container. Use a GtkVBox or GtkHBox as intermediate container to add two items to a single parent.
Then you can just use gtk_widget_set_visible() to change visibility of the two items.
I have GTK+ working in a vs2010 c++ windows app.
It uses the builder to load a gui template from glade.
However when I close the window using the cross icon or right click close at the taskbar,
the process for my app is not killed.
How do I ensure that the process is killed nicely?
Closing the window does not kill the process unless you set up a callback that quits the Gtk+ main loop on the window delete event. Application will exit only after you call gtk_main_quit() which terminates the mainloop.
Don't know how the C++ binding to GTK+ works, but in C it would be something like this (taken from GNOME website):
int main( int argc,
char *argv[] )
{
GtkWidget * window;
gtk_init (&argc,&argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (window, "delete-event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (window, "destroy",
G_CALLBACK (destroy), NULL);
gtk_widget_show (window);
gtk_main ();
}
And then the callbacks:
static gboolean delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
g_print ("delete event occurred\n");
return FALSE;
}
static void destroy( GtkWidget *widget,
gpointer data )
{
gtk_main_quit ();
}
I am working with the MusicPlayer API and I am trying to solve a problem I am having with user callback.
I have user events that are placed at every note event of a MIDI. When the notes are played, these user events pass the integer value of the note to a user callback function as *inEventData:
void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
{
UserEvent* event = (UserEvent *)inEventData;
UInt32 size = event->length;
UInt32 note = event->playedNote;
UInt32 timestamp = event->tStamp;
NSLog(#"Size: %lu Note: %lu, Timestamp: %lu", size, note, timestamp);
switch (note) {
case 60:
[whiteKey60 setImage:highlightA];
break;
default:
break;
}
}
Based upon these notes, I would like to makes changes to the UI. Namely, I have a number of UIImageViews that I would like to be able to update with different images based upon the value of the note (see above in switch statement).
The user callback function is associated with the sequence like this:
MusicSequenceSetUserCallback(sequence, noteUserCallback, NULL);
The third parameter of the above function connected with the void *inClientData parameter of the user callback function.
My problem is, that when I try to access the IBOutlets of my view from within the user callback function, I cannot. To fix this, I tried to pass the view controller into the MusicSequenceSetUserCallback function like this:
MusicSequenceSetUserCallback(sequence, noteUserCallback, self);
The problem I am having is that this inClientData parameter is of type void and I cannot pass in a ViewController* object. I tried simply creating a bridge when I set the callback function and then bridging back again within the user callback function but it didn't seem to work.
If anyone has any thoughts on how I could accomplish this. Even if it's a completely different methods, I would really appreciate it.
Thanks.
EDIT
I tried the following:
MusicSequenceSetUserCallback(sequence, noteUserCallback, (__bridge_retained void *)self);
and
void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
{
PracticeViewController* pvc = (__bridge_transfer PracticeViewController *)inClientData;
[pvc.whiteKey21 setImage:pvc.highlightA];
UserEvent* event = (UserEvent *)inEventData;
UInt32 size = event->length;
UInt32 note = event->playedNote;
UInt32 timestamp = event->tStamp;
NSLog(#"Size: %lu Note: %lu, Timestamp: %lu", size, note, timestamp);
switch (note) {
case 60:
break;
default:
break;
}
}
Unfortunately, it gives me this error: Thread 13 AURemoteIO::IOThread: EXC_BAD_ACCESS (code=2, address=0x10)
EDIT
Changing both bridges to __bridge silences the error but it is still not working properly; the call to change in the image in whiteKey60 does not work. It isn't a problem with the UIImageView connection because doing the same in viewDidLoad works fine.
What seems to be going on, to me anyways, is that self isn't making it to the function or perhaps its breaking the connection when it's passed?
Take a look at the declaration for MusicSequenceSetUserCallback again:
OSStatus MusicSequenceSetUserCallback (
MusicSequence inSequence,
MusicSequenceUserCallback inCallback,
void *inClientData
);
inClientData's type isn't void -- that wouldn't make sense, variables in C can never have a type of void. Rather, it's void * -- roughly, a pointer to something unspecified.
You need to cast the variable to a void * on the way in, and from a void * on the way out. Assuming that self is a MyClass *, then:
MusicSequenceSetUserCallback(sequence, noteUserCallback, (void *)self);
and in the callback:
void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
{
MyClass* self = (MyClass *)inClientData;
...
}