Python 2.7 Python gtk3窗口侦听输入事件

Python 2.7 Python gtk3窗口侦听输入事件,python-2.7,gtk,gtk3,Python 2.7,Gtk,Gtk3,PythonGTK3窗口是否有任何方法可以捕获其中键盘和/或鼠标的每个输入 基本上,我正在创建一个应用程序,它会在空闲时启动类似屏幕保护程序的东西,为此,我需要知道在我的窗口(应用程序)内发生键盘或鼠标事件的时间 我试图将按键事件连接到我的窗口,但当我单击它的子窗口(如按钮)时,窗口无法获取事件 感谢您提供的任何解决方案 更新 根据公认的答案,我将信号后的事件连接到主窗口,并确定是否需要接收信号。按键事件仅适用于键盘。按钮创建一个按钮按下事件。看 始终记住,*-press事件在操作完成之前运行。

PythonGTK3窗口是否有任何方法可以捕获其中键盘和/或鼠标的每个输入

基本上,我正在创建一个应用程序,它会在空闲时启动类似屏幕保护程序的东西,为此,我需要知道在我的窗口(应用程序)内发生键盘或鼠标事件的时间

我试图将
按键事件
连接到我的窗口,但当我单击它的子窗口(如按钮)时,窗口无法获取事件

感谢您提供的任何解决方案

更新
根据公认的答案,我将信号后的
事件连接到主窗口,并确定是否需要接收信号。

按键事件仅适用于键盘。按钮创建一个
按钮按下事件
。看


始终记住,
*-press事件在操作完成之前运行。我建议您使用
*-release事件
,如果您意外单击按钮,可以在释放前滑出按钮。这在您的案例中并不是那么重要,但仍然…

请首先回忆一下存在信号和事件。可能有些过于简化,事件是“原始的”:例如,它们来自键盘或鼠标。最顶端的小部件(考虑到窗口位于底部)接收这些事件并决定它是否对事件感兴趣

如果小部件对事件感兴趣,例如对按钮按下事件和按钮释放事件感兴趣的按钮,则小部件随后创建信号,例如在本例中的“单击”、“双击”信号。在事件处理程序内部,返回值(True或False)确定事件是否将“向下”传播到下一个小部件(“在顶部的小部件下方”)

因此,我怀疑您无法在事件到达目标之前直接监视底层窗口上的所有事件

也许您的解决方案是连接到窗口的“事件之后”。它独立于其他处理程序的返回值进行调用。下面是一个小程序,您可以在其中测试以下内容:

此时会出现一个带有标签、按钮和旋转按钮的GtkGrid。右下角的单元格为空:

  • 单击标签,事件会慢慢流到窗口,因为标签不会捕获任何事件

  • 单击按钮,事件(如“按下”)由处理程序捕获,并生成“单击”等信号

  • 我连接到“事件之后”,并报告在任何位置按下按钮

#/usr/bin/env蟒蛇3
#-*-编码:utf-8-*-
#
#test_events.py
#
#版权所有2017约翰·科彭斯
#
#这个程序是自由软件;您可以重新分发和/或修改它
#它是根据GNU通用公共许可证的条款发布的
自由软件基金会;许可证的第2版,或
#(由您选择)任何更高版本。
#
#这个节目的发布是希望它会有用,
#但无任何保证;甚至没有任何关于
#适销性或适合某一特定目的。见
#有关更多详细信息,请参阅GNU通用公共许可证。
#
#您应该已经收到GNU通用公共许可证的副本
#与此同时,;如果没有,请写信给自由软件
波士顿基金会51楼富兰克林街第五楼
#MA 02110-1301,美国。
#
#
从gi.repository导入Gtk
类事件测试(Gtk.Grid):
定义初始化(自):
super(EventsTest,self)。\uuuu init\uuuuu()
btn=Gtk.按钮(“右上”)
btn.connect(“点击”,lambda x:print(“点击按钮”))
自贴(Gtk标签(“左上”),0,0,1,1)
自我连接(btn,1,0,1,1)
self.attach(Gtk.SpinButton(),0,1,1,1)
类主窗口(Gtk.Window):
定义初始化(自):
超级(主窗口,自我)。\uuuu初始化
self.connect(“销毁”,lambda x:Gtk.main_quit())
自连接(“按钮按下事件”,自启动按钮按下)
self.connect(“事件之后”,self.on\u事件之后)
evtest=EventsTest()
self.add(evtest)
self.show_all()
def on_按钮按下(自身、btn、事件):
打印(“按下主窗口按钮”)
返回真值
事件后的def(自身、wdg、事件):
打印(“事件之后”)
def运行(自):
Gtk.main()
def主(args):
mainwdw=MainWindow()
mainwdw.run()
返回0
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
导入系统
系统出口(主(系统argv))

我刚刚尝试了一个简单的例子(在Vala中),窗口一直在接收信号。我有一个窗口,有一个垂直的盒子,里面有一个入口和一个按钮。信号总是在窗户上发出。必须在python上尝试,但行为将是相同的。你能发布代码吗(如果小的话)?很抱歉,但是这个应用程序相当大,超过30个文件(类)。我确实尝试了一些代码测试,是的,窗口确实收到了信号。在我的例子中,我不知道如何解释,它有时接收到信号,有时不接收,点击同一个按钮。可能不是这样,但有时只是返回一些回调来停止信号的传播。是的,这会将我需要通知
事件
用户活动
的信号发送到主窗口。谢谢。我认为还有一种方法是注册回调,而不是将Gtk.Window子类化。也就是说,您将实例化一个窗口,比如
window=Gtk.window()
执行
window.connect('button-press-event',…)
之类的操作,而不是将代码封装在子类Gtk.window中。可能很快就会遇到正反两面。是的,当然。这是多年来的一个长期争论。实例化(有时称为组合)而不是子类化——关于这一点,在堆栈溢出和其他方面已经有很多讨论。
#!/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))