GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Oct 24, 2014 11:29 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Can I assign a key to a button?
PostPosted: Wed Mar 10, 2010 3:07 am 
Offline

Joined: Wed Mar 10, 2010 2:22 am
Posts: 2
I've decided to tackle the project of writing a calculator program that uses Reverse Polish Notation ( mainly because once you start using a calc like the HP48g you don't like to go back, and all the RPN calc programs I've found have little annoyances, like comma separated decimal places or stacks that are too small, that I'd like to eliminate). Here's what I have completed so far:

- Set up Glade 3 on my Linux box
- created an XML file and connected it with libglade (GTK+ toolkit version in the Glade properties box defaulted to 2.12)
- programmed all the functionality of the calculator in C

So basically, I have a working program that has a GTKTextview to show my data stack, an GTKEntry where I feed in my data, and a series of buttons which perform the various calculations. It all works perfectly with a mouse to run the buttons and a keyboard to supply the Entry text. What I don't have is the convenience of running the basic calculator functions, + - * / Enter, etc., by just pressing those keys on the keyboard. Is there a way to assign an individual key to a button?

I've read a little bit about the key press signals that can be handled by my choice of code, but I'm confused about how they work. Would I be forced to write code for every key that could be entered, even though I only want to change the way 4 or 5 of them work?

I've answered all of my newbie questions to this point using the docs online, but for these questions I think I need an expert to tell me the general direction I need to head and which parts of the documentation will be most helpful. Thanks in advance for the guidance.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 10, 2010 4:37 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello and welcome to the GTK+ forums.

GtkWidget::key-press-event is the right thing to use here and setting it up should be really simple. Just create switch that will react upon selected keys.

Sample implementation would look something like this:
Code:
#include <gdk/gdkkeyssyms.h>

static gboolean
cb_key_press( GtkWidget   *widget,
           GdkEventKey *event,
           gpointer     data )
{
   switch( event->key )
   {
      case GDK_plus:
         /* DO something */
         return( TRUE );
         break;

      /* More character specifics here */

      default:
         return( FALSE );
         break;
   }
}

Tadej


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 12, 2010 11:17 pm 
Offline

Joined: Wed Mar 10, 2010 2:22 am
Posts: 2
Firstly, I must say thanks to Tadej. With just a few minor tweaks, I was able to add the keyboard functionality I was looking to use. Here's my notes on the process:

1) I had to change the following line:
#include <gdk/gdkkeyssyms.h>

to read:
#include <gdk/gdkkeysyms.h>


2) The event structure in my version of Gtk renamed key to keyval so I change this:
switch( event->key )

to the following:
switch( event->keyval )


3) I have my program set up so the callback functions are stored in callbacks.c and their definitions (not sure if that's the correct term) are stored in callbacks.h. When I tried using the static keyword as listed I received the following 2 errors:

callbacks.c:1538: warning: ‘on_main_window_key_press_event’ defined but not used
callbacks.h:81: warning: ‘on_main_window_key_press_event’ declared ‘static’ but never defined

I tried fixing these errors using a method akin to using an ax to trim your fingernails: I changed it from static gboolean to void and removed all the return calls. It compiled warning-free but my program then would respond only to the keys I had listed in my switch statement block. If the GTKEntry widget had the focus, the code I had programmed for a particular key would run correctly but it would also add the character for that key to the entry string.

My final and less drastic solution to those warnings was to put back in the return calls and change the type from void to just gboolean, simply dropping the static keyword from the original code. That got me the result I needed. The keys I include in my switch statement block respond to my code and are not passed through to the entry field, and all other keys perform their normal functions.

So I have just a couple of follow-up questions: First, why was the function defined as static? Am I likely to have unseen troubles by removing it? Second, what happens if you return (FALSE) after the character specific code rather than return (TRUE)? (I might test that last question myself someday, but I thought I would ask in case someone has already tested and can just reply.)

-Dave


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 13, 2010 8:11 am 
Offline
GTK+ Geek

Joined: Fri May 23, 2008 7:13 am
Posts: 73
super_dave_42 wrote:
Second, what happens if you return (FALSE) after the character specific code rather than return (TRUE)?


See http://library.gnome.org/devel/gtk/stab ... ress-event


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 13, 2010 11:28 am 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello.

super_dave_42 wrote:
1) I had to change the following line:
#include <gdk/gdkkeyssyms.h>

to read:
#include <gdk/gdkkeysyms.h>


2) The event structure in my version of Gtk renamed key to keyval so I change this:
switch( event->key )

to the following:
switch( event->keyval )

I'm really sorry for this. I should get into habit of proof-reading my posts before clicking "Submit" button.

super_dave_42 wrote:
3) I have my program set up so the callback functions are stored in callbacks.c and their definitions (not sure if that's the correct term) are stored in callbacks.h. When I tried using the static keyword as listed I received the following 2 errors:

callbacks.c:1538: warning: ‘on_main_window_key_press_event’ defined but not used
callbacks.h:81: warning: ‘on_main_window_key_press_event’ declared ‘static’ but never defined

I tried fixing these errors using a method akin to using an ax to trim your fingernails: I changed it from static gboolean to void and removed all the return calls. It compiled warning-free but my program then would respond only to the keys I had listed in my switch statement block. If the GTKEntry widget had the focus, the code I had programmed for a particular key would run correctly but it would also add the character for that key to the entry string.

My final and less drastic solution to those warnings was to put back in the return calls and change the type from void to just gboolean, simply dropping the static keyword from the original code. That got me the result I needed. The keys I include in my switch statement block respond to my code and are not passed through to the entry field, and all other keys perform their normal functions.

So I have just a couple of follow-up questions: First, why was the function defined as static? Am I likely to have unseen troubles by removing it? Second, what happens if you return (FALSE) after the character specific code rather than return (TRUE)? (I might test that last question myself someday, but I thought I would ask in case someone has already tested and can just reply.)

First, static/non-static functions. Static symbols (functions, variables) are not exported from objects and are thus hidden from linker. This is why you've got those errors. Simply removing 'static' keyword from function declaration and definition (declarations are placed inside header file, definitions are placed inside C file) should resolve this linking problem.

I declared function as static simply because most of the sample code I write for this forum is composed of single C file and thus no exported symbols are needed (apart from main() function, that is). Omitting static keyword will not get you into any trouble at all and is actually required for your code to work correctly.

Now about those return values. If you look at the GtkWidget's signals, you'll notice that there is quite a few of them named <something>-event. This signals are wrappers around underlying windowing system events and their callback functions should have prototypes like this:
Code:
gboolean
cb_func( GtkWidget *w,
         GdkEvent<type> *e,
         gpointer  d );

Return value of callback is really important here, since it controls propagation of this event further down the widget tree. Returning FALSE indicates that you didn't handle this event and so event should be propagated further. Returning TRUE will tell GTK+ that you handled this event and propagation stops.

For example, let's say that you handle '+' and '-' inside your switch. Focus is inside your entry and you press '7'. This triggers 'key-press-event' of your window. You check for '7' in your switch and since you don't need to handle it, your callback returns FALSE. Because event hasn't been handled, it's propagated further down to GtkEntry, whose 'key-press-event' is now emitted and default handler will insert character.

Now you press '+'. Again, 'key-press-event' of your window is triggered and because now your switch statement will handle it and return TRUE. Since you indicated that you handled this event, no propagation happens and signal chain stops. GtkEntry doesn't receive this event and thus '+' is not inserted.

Hopefully, you'll be able to make some sense out of my post (I'm having some troubles concentrating right now thanks to my 2 moths old son and his "everything is eatable" philosophy).

Tadej


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group