2017-05-25 63 views
1

有什麼辦法可以讓python gtk3窗口捕捉來自鍵盤和/或鼠標的每一個輸入嗎?Python gtk3窗口監聽輸入事件

基本上我創建一個應用程序,它會推出類似屏保閒置的時候,這樣做,我需要知道的時候,鍵盤或鼠標事件我的窗口(應用程序)內發生。

我試圖key-press-event連接到我的窗口,但是當我在它的子點擊,就像一個按鈕,窗口沒有得到該事件。

謝謝你的任何解決方案。

UPDATE 作爲公認的答案表明,我連接event-after信號到主窗口,並確定如果我需要接收到的信號。

+0

我剛剛嘗試了一個簡單的例子(在Vala中),窗口一直在接收信號。我有一個帶有一個入口和一個按鈕的垂直盒子容器的窗口。信號始終發射到窗戶上。必須嘗試蟒蛇,但行爲將是相同的。你可以發佈代碼(如果很小)? –

+0

對不起,但應用程序相當大,超過30個文件(類)。我確實嘗試了一些代碼測試,並且YES,窗口確實收到了信號。就我而言,我不知道如何解釋,它有時會收到信號,有時候它不會,點擊同一個按鈕。 – Lee

+1

可能不是這種情況,但有時它只是一些callbackt的返回,它會阻止信號的傳播。 –

回答

1

也許首先回憶一下,有信號和事件。也許有些過度簡化,事件是'生'的:例如,它們來自鍵盤或鼠標。最頂層的窗口小部件(考慮窗口在底部)接收這些事件並決定事件是否有趣。

如果小部件對該事件感興趣,例如對按鈕按下事件和按鈕釋放事件感興趣的按鈕,則小部件然後創建信號,例如,在這種情況下,'點擊', '雙擊'信號。在事件處理程序內部,返回值(True或False)確定事件是否向下傳播到下一個小部件(在頂部之下)。

所以,我懷疑你不能直接監視底層窗口上的所有事件,然後才能到達目標。

也許你的解決方案將連接到該窗口的「事件後」。這會從其他處理程序的返回值中獨立調用。下面是一個小程序,在那裏你可以測試以下內容:

一個GtkGrid出現一個標籤,一個按鈕和一個數值調節鈕。右下單元格爲空:

  • 單擊該標籤上的事件涓滴的窗口,因爲標籤不捕獲任何事件

  • 點擊按鈕,事件(例如作爲「按下」)被處理程序捕獲,併產生諸如「點擊」之類的信號。

  • 我連接到'event-after',並且任何地方都有一個按鈕被按下。

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
# 
# test_events.py 
# 
# Copyright 2017 John Coppens <john*at*jcoppens*dot*com> 
# 
# This program is free software; you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation; either version 2 of the License, or 
# (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
# MA 02110-1301, USA. 
# 
# 


from gi.repository import Gtk 

class EventsTest(Gtk.Grid): 
    def __init__(self): 
     super(EventsTest, self).__init__() 

     btn = Gtk.Button("Top right") 
     btn.connect("clicked", lambda x: print("Button clicked")) 

     self.attach(Gtk.Label("Top left"), 0, 0, 1, 1) 
     self.attach(btn, 1, 0, 1, 1) 
     self.attach(Gtk.SpinButton(), 0, 1, 1, 1) 


class MainWindow(Gtk.Window): 
    def __init__(self): 
     super(MainWindow, self).__init__() 
     self.connect("destroy", lambda x: Gtk.main_quit()) 
     self.connect("button-press-event", self.on_button_pressed) 
     self.connect("event-after", self.on_event_after) 

     evtest = EventsTest() 

     self.add(evtest) 
     self.show_all() 

    def on_button_pressed(self, btn, event): 
     print("Main window button pressed") 
     return True 

    def on_event_after(self, wdg, event): 
     print("Event after") 

    def run(self): 
     Gtk.main() 


def main(args): 
    mainwdw = MainWindow() 
    mainwdw.run() 

    return 0 

if __name__ == '__main__': 
    import sys 
    sys.exit(main(sys.argv)) 
+0

是的,這發送我需要通知'事件'或'用戶活動'到主窗口的信號。謝謝。 – Lee

1

key-press-event僅適用於鍵盤。一個按鈕會創建一個button-press-event。請參閱docs

永遠記住,做動作之前,*-press-event獲取運行。如果您偶然點擊該按鈕,我會建議您使用*-release-event,您可以在釋放之前從按鈕上滑下。這不是你的情況至關重要,但仍...

+0

謝謝先生,爲您的建議。 – Lee