Seite 1 von 1
Taste abfragen ohne Fokus
Verfasst: 28. Januar 2010 14:45
von MTW
Hallo,
ich habe ein Programm mit einem Tray Icon. Jetzt soll das Programm angezeigt werden wenn ich eine Taste drücke. Wie bekomme ich es aber hin dass die Taste auch ohne Fokus abgefragt wird??
Danke für die Hilfe

Verfasst: 28. Januar 2010 15:41
von Robin
Du kannst in deiner Betriebsumgebung (Windows, Gnome, KDE, ...) einen Shortcut (Hotkey) definieren, der Dein Programm startet.
Beim Programmstart kannst Du dann einfach abfragen, ob bereits eine Instanz Deines Programms läuft und ggf. das entsprechende Fenster aktivieren.
Verfasst: 28. Januar 2010 15:56
von MTW
Danke schon mal, aber gibt es keine andere Möglichkeit?
Diese Lösung scheint mir nicht so befriedigend zu sein, Qt kann doch das sicher besser...

Verfasst: 29. Januar 2010 17:36
von hasu
Hi, also ich habe derzeit ein aehnliches Problem, deshalb klink ich mir hier mal ein.
Ziel ist ebenso wie bei dir das abfangen eines globalen Hotkeys, auch wenn andere Fenster im Vordergrund sind.
Folgendes habe ich mir bisher überlegt und in einem Konsolenprogramm auch schon zum laufen bekommen (Windows!):
Anlegen eines globalen Hotkeys über RegisterHotKey, dann Abfrage über eine Mainloop in der GetMessage aufgerufen wird (jeweils Win-Api).
Das wollte ich nun eigentlich auch in Qt so umsetzen, da allerdings die Mainloop fehlt müsste man anders auf das Event reagieren können.
Hatte an eine Reimplementierung von
QWidget::winEvent gedacht.
Folgender Code (ich benutze Python/PyQt) führt jedoch leider nicht zum Erfolg:
Code: Alles auswählen
def winEvent( self, message ):
if message.message == WC.WM_HOTKEY:
print "Hotkey!"
return True, 0
else:
print message
return False, 0
Es werden alle möglichen Events erzeugt, jedoch keine WM_HOTKEY, obwohl selbiger korrekt registriert wurde.
Insbesondere kommen keine Events mehr an wenn ein anderes Fenster den Fokus hat.
Soviel zur Idee, vielleicht hilfts dir ja. Dann könnten wir versuchen gemeinsam rauszufinden (oder nachzufragen) wie man das in Qt korrekt realisiert.
Derselbe Code nochmal in C++ falls man damit mehr anfangen kann:
Code: Alles auswählen
bool winEvent( MSG *message, long *result )
{
*result = 0;
if (message.message == WM_HOTKEY)
{ cout << "Hotkey!" << endl; return true; }
return false;
}
Verfasst: 29. Januar 2010 18:20
von Christian81
Ich glaube QCoreApplication::winEventFilter() ist da eher das was Du suchst...
Verfasst: 31. Januar 2010 21:12
von hasu
Funktioniert leider ebenfalls nicht, da kommen auch alle möglichen Events rein aber keine WM_HOTKEY.
Verfasst: 31. Januar 2010 22:01
von Christian81
Aufgrund von
The message procedure calls this function for every message received
würde ich sagen das RegisterHotkey wurde nicht korrekt aufgerufen. Denn winEventFilter wird in der Qt-Eventloop (also genau da was Du willst) aufgerufen.
Also bitte Beispielcode (c++, pyqt habe ich nicht)
Verfasst: 31. Januar 2010 22:36
von hasu
Ich bin mir ziemlich sicher dass RegisterHotKey funktioniert, aus zwei Gründen: Erstens ohne Aenderung aus der bisherigen Konsolenversion des Programmes übernommen in der das ganze tadellos funktioniert hat.
Zweitens hab ich bspw. Backspace als Hotkey festgelegt, und wenn ich während das Programm läuft woanders diese Taste benutze tut sich nichts.
Kann/will jetzt leider nicht das ganze Projekt in C++ abtippen, aber mal die relevanten Passagen (bitte nicht allzu kleinlich bei Syntaxfehlern, ich tipp das jetzt on-the-fly ein):
Code: Alles auswählen
void RegisterHotkeys( bool unregister=false )
{
if (!unregister)
{
RegisterHotKey( NULL, 1, 0, VK_F9 );
....
RegisterHotKey( NULL, 5, 0, VK_BACK );
}
else
{
for(int i=0; i<6; i++)
UnregisterHotKey( NULL, i );
}
}
wird jeweils beim Start bzw. Beenden des Programms aufgerufen.
Application sieht in Python so aus:
Code: Alles auswählen
class Application(QtGui.QApplication):
def __init__( self, argv ):
QtGui.QApplication.__init__(self, argv)
def winEventFilter( self, msg ):
if msg.message == WC.WM_HOTKEY:
print "Hotkey!"
return True, 0
return False, 0
entspricht also in C++ etwa
Code: Alles auswählen
class Application : public QApplication
{
public:
Application( int & argc, char ** argv ) : QApplication(argc, argv) {;};
bool winEventFilter( MSG *msg, long * result )
{
*result = 0;
if (MSG.message == WM_HOTKEY)
{ cout << "Hotkey!" << endl; return true; }
return false;
}
};
Edit: Habe noch bisschen weiter recherchiert und bin auf QCoreApplication::setEventFilter gestoßen was eigentlich vielversprechend klingt, leider ist genau das in PyQt nicht implementiert.
(Vgl.
http://www.mail-archive.com/pyqt@riverb ... 08041.html)
Nur um das schonmal vorwegzunehmen, auch wenn ich befürchte dass sich die meisten C++-treuen damit jetzt hier verabschieden werden :/
Verfasst: 1. Februar 2010 17:38
von MTW
Hi,
bei mir funktioniert es dank der guten Tipps von hasu und Christian81, vielen Dank an dieser Stelle!
Aber jetzt zu meiner Lösung des Problems:
Ich habe wie hasu einen Hotkey registriert mit RegisterHotKey, aber habe als hWnd nicht NULL verwendet sondern das Fensterhandle, also in meinem Falle this->winId(). Dann eine App-Klasse gemacht, von QApplication abgeleitet und darin die winEventFilter funktion überschrieben.
also mit
Code: Alles auswählen
RegisterHotKey(this->winId(),1,MOD_CONTROL | MOD_ALT,'M');
hotkey registrieren, dann funktioniert das QApplication::winEventFilter:
Code: Alles auswählen
bool MPHapp::winEventFilter(MSG *message, long *result){
*result = 0;
if(message->message == WM_HOTKEY){
this->aboutQt();
return true;
}
else return false;
}
Ich hoffe bei dir klappt es jetzt auch.

Verfasst: 2. Februar 2010 11:34
von hasu
Oh man, danke für den Hinweis, damit funktioniert es tatsächlich.
Wär ich wohl nie drauf gekommen...