PDA

View Full Version : Shortcut



Voldemort
1st May 2007, 16:00
I want this:

When a user pressed enter, the window closes and there will be activated a slot. I have this code:


QLabel *lblUserName = new QLabel(tr("Mailadres:"));
QLabel *lblPass = new QLabel(tr("Wachtwoord:"));
QLabel *lblLogin = new QLabel(tr("Aanmelden:"));

mail = new QLineEdit;

pass = new QLineEdit;
pass->setEchoMode(QLineEdit::Password);

QPushButton *blogin = new QPushButton(tr("&Aanmelden"));

QGridLayout *lay_ok = new QGridLayout;
lay_ok->addWidget(lblUserName,0,0);
lay_ok->addWidget(mail,1,0);
lay_ok->addWidget(lblPass,2,0);
lay_ok->addWidget(pass,3,0);
lay_ok->addWidget(lblLogin,4,0);
lay_ok->addWidget(blogin,5,0);
setLayout(lay_ok);

setMinimumSize(250,175);
setMaximumSize(250,175);

QAction *action = new QAction("&Aanmelden",this);
action->setShortcut(QKeySequence(Qt::Key_Enter));

connect(action,SIGNAL(triggered()),SLOT(close()));
connect(action,SIGNAL(triggered()),SLOT(startLogin ()));

connect(blogin, SIGNAL(clicked()), SLOT(close()));
connect(blogin, SIGNAL(clicked()), SLOT(startLogin()));

But this doesn't work. The clicked() signals works good (when the signal is "blogin"), the triggered() signals (sender is "action") doesn't work.

marcel
1st May 2007, 16:55
You have to attach that action to some widget to make it work.
You can use QWidget::addAction;

For example:


blogin->addAction( action );



Regards

Voldemort
1st May 2007, 17:05
I've changed it to:


QAction *action = new QAction("&Aanmelden",this);
action->setShortcut(QKeySequence(Qt::Key_Enter));
blogin->addAction(action);

connect(action,SIGNAL(triggered()),SLOT(close()));
connect(action,SIGNAL(triggered()),SLOT(startLogin ()));

But it doesn't work. Pressing enter doesn't work.

marcel
1st May 2007, 17:11
Have you tried setting other shortcuts? For example something with a modifier: CTRL + X.
QAbstractButton also has a setShortcut() method. Maybe you have better luck with this one.

Also, tale a look at QAction::setShortcutContext.

The problem is that enter is also used to "click" a button, when it has the focus. So be careful, because it could emit a clicked event, therefore calling your slot twice.

Regards

Voldemort
1st May 2007, 17:29
1) This works:


action->setShortcut(QKeySequence("CTRL+E"));

But how can do the same, but with the enter key?

2) How can I avoid the twice emitted slot?

marcel
1st May 2007, 17:33
I don't think you can this easily... You can think at enter as a reserved key.

You could do it by installing event filters in your main window and in the subsequent parents of the button and redirecting Enter to the button. My guess is that the enter key event is consumed by the main window if it does'nt find any child that has the focus...

Couldn't you settle with any other shortcut?

Voldemort
2nd May 2007, 13:03
I use KDE and Kopete. In a chat window in Kopete, when I press enter, the text is sent, so why can they do it so easy and I not?

marcel
2nd May 2007, 13:20
Probably they made use of the good old event filters :).

Can't you take a look on how it's done in Kopete?

Voldemort
2nd May 2007, 14:39
I've found this (kdenetwork/kopete/kopete/chatwindow/kopetechatwindow.cpp in KDE 3.80.3):


chatSend = new KAction( KIcon("mail_send"), i18n( "&Send Message" ), coll );
coll->addAction( "chat_send", chatSend );
connect( chatSend, SIGNAL( triggered(bool) ), SLOT( slotSendMessage() ) );
//Default to 'Return' for sending messages
chatSend->setShortcut( QKeySequence(Qt::Key_Return) );
chatSend->setEnabled( false );

fullmetalcoder
2nd May 2007, 14:52
Qt::Key_Enter refers to the enter key of the numpad (or to no key on a laptop...) whereas the Qt::Key_Return refers to the return key (what a discovery!!!) which is often considered as the enter key, especially now that numpad-less laptops are so widespread....

Hope this helps :)

Voldemort
2nd May 2007, 15:57
1) I use a laptop. I now changed my code to this:


action->setShortcut(QKeySequence(Qt::Key_Return));And it works fine.

2) I'll use in the slot function a code that disables the action (http://doc.trolltech.com/snapshot/qaction.html#enabled-prop) and in the function where the connect is one which enables it. So I'll get never a slot which emitted twice?

3) What will happen when someone with a non-laptop keyboard presses the Enter key at the numeric part? Will my slot work or won't it?

fullmetalcoder
2nd May 2007, 16:26
Good :)
I don't quite get you... Whatever the enabled status, a slot shouldn't be emitted twice... What will change is the possibility for your slot ot be emitted at a given time.
It won't... You can't set several shortcuts to an action. At least no using QAction::setShortcut() (http://doc.trolltech.com/4.2/qaction.html#shortcut-prop). You'll have to play with QShortcut (http://doc.trolltech.com/latest/qshortcut.html) or mess with events if your shortcuts are specific to a single widgetEdit : If you are using Qt 4.2, a new function has been introduced which will certainly make your life easier : QAction::setShortcuts()

jpn
2nd May 2007, 16:31
Since Qt 4.2 one can set multiple shortcuts (http://doc.trolltech.com/4.2/qaction.html#setShortcuts) to an action.

Voldemort
2nd May 2007, 20:37
1) My code currently is:


QPushButton *blogin = new QPushButton(tr("&Aanmelden"));

action->setShortcut(QKeySequence(Qt::Key_Return));
blogin->addAction(action);

connect(action,SIGNAL(triggered()),SLOT(close()));
connect(action,SIGNAL(triggered()),SLOT(startLogin ()));

connect(blogin, SIGNAL(clicked()), SLOT(close()));
connect(blogin, SIGNAL(clicked()), SLOT(startLogin()));
This works fine, but what wil happen when a user sets the focus on the QPushButton and presses Enter? Then will action sending the signal triggered and blogin the signal clicked => the close and startLogin() function will be emited twice.

marcel said this some post above this:


The problem is that enter is also used to "click" a button, when it has the focus. So be careful, because it could emit a clicked event, therefore calling your slot twice.How can I solve this? A bool which will say the slot is emited or not?

2) Can I do this:


action->setShortcut(Qt::Key_Return);
action->setShortcut(Qt::Key_Enter);

Or is the function setShortcuts required? Can someone give an example (when I do it wrong I can't test it will work because I can only press "Return" (have no "Enter" on a laptop))?

fullmetalcoder
2nd May 2007, 20:42
This works fine, but what wil happen when a user sets the focus on the QPushButton and presses Enter? Then will action sending the signal triggered and blogin the signal clicked => the close and startLogin() function will be emited twice.

I'd tend to think that the signal will be emitted only once either because the button will catch the event or, more probably (but depends on internal event handling of QPushButton (http://doc.trolltech.com/latest/qpushbutton.html)), because the shortcut will be triggered and stop event propagation... Have you tried it or are you making assumptions on potential problems??? ;)

Mutliples shortcuts, provided that you use Qt 4.2 or newer, can be assigned this way :


QList<QKeySequence> shortcuts;
shortcuts
<< Qt::Key_Return // this is the primary shortcut
<< Qt::Key_Enter // this is another valid shortcut but won't appear on a menu for exmple
<< Q::Key_F7 // yet another shortcut, just to show that you can go beyond two...
;

action->setShortcuts(shortcuts);Hope this helps. :)

marcel
2nd May 2007, 20:43
Have you verified this? Is the signal emitting twice?
I'm not sure, never tried it. Also, when you press space on a button that has the focus causes the button to be clicked :).

If the signals does get emitted twice, you might wanna try setFocusPolicy( Qt::NoFocus ) on the QPushButton.

Voldemort
2nd May 2007, 20:51
When I tried it, the new window isn't opened twice (the slot shows a new window and closes the current). I think it won't be a problem, but maybe in the future (newer Qt versions)?