Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中正确显示和隐藏GTK窗口_Python_Gtk - Fatal编程技术网

如何在python中正确显示和隐藏GTK窗口

如何在python中正确显示和隐藏GTK窗口,python,gtk,Python,Gtk,因此,我有以下代码(Python2.7),用于检查按键组合,并显示/隐藏带有几个gtk输入框的gtk窗口。“显示/隐藏”将一直工作,直到窗口锁定并停止响应,并且窗口的内部变为黑色。一旦窗口变黑,我必须停止进程并重新启动它。我尝试了show_all()和在隐藏窗口后返回True的所有不同组合,但均无效。我不确定我做错了什么 最后,我希望能够按下此组合键,并显示/隐藏此窗口,而不会使内容消失 #!/usr/bin/python import gi gi.require_version('Gtk',

因此,我有以下代码(Python2.7),用于检查按键组合,并显示/隐藏带有几个gtk输入框的gtk窗口。“显示/隐藏”将一直工作,直到窗口锁定并停止响应,并且窗口的内部变为黑色。一旦窗口变黑,我必须停止进程并重新启动它。我尝试了show_all()和在隐藏窗口后返回True的所有不同组合,但均无效。我不确定我做错了什么

最后,我希望能够按下此组合键,并显示/隐藏此窗口,而不会使内容消失

#!/usr/bin/python

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import pyxhook

class MyWindow(Gtk.Window):

    def __init__(self):
    Gtk.Window.__init__(self, title="Configurator")

    self.box = Gtk.Box(spacing=6)
    self.add(self.box)

    self.ipEntry = Gtk.Entry()
    self.ipEntry.set_text("IP Address")

    self.maskEntry = Gtk.Entry()
    self.maskEntry.set_text("NetMask")

    self.gatewayEntry = Gtk.Entry()
    self.gatewayEntry.set_text("gatewayEntry")

    self.button1 = Gtk.Button(label="Save")
    self.button1.connect("clicked", self.on_button1_clicked)
    self.box.pack_start(self.ipEntry, True, True, 0)
    self.box.pack_start(self.maskEntry, True, True, 0)
    self.box.pack_start(self.gatewayEntry, True, True, 0)
    self.box.pack_start(self.button1, True, True, 0)

    #catch window destroy event and stop it from happening
    self.connect('delete-event', self.on_destroy)

    def on_button1_clicked(self, widget):
    print("Hello")
    def on_destroy(self, widget=None, *data):
    print("tried to destroy")
    self.hide()
    return True

#list of ascii keypresses to test if a certain combination of keys is pressed
keypresses = []

win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
win.set_keep_above(True)

def OnKeyboardEvent(event):
#ascii 227 is l_control, ascii 225 is l_shift, ascii 120 is x
#bring the following external variables into the scope of this function
    global keypresses
    global win
#check if gtk window is hidden or visible
    isVisible = win.get_property("visible")

    #store our keypress if it is worthy of being stored (we started with a control character)
    if event.Ascii == 227 or ( len(keypresses) >= 1 and keypresses[0] == 227 ):
            print("here" + str(len(keypresses)))
            keypresses.append(event.Ascii)
    #check if we have three items in keypresses to compare, then see if it's the right combination
    if len(keypresses) == 3 and keypresses[0] == 227 and keypresses[1] == 225 and keypresses[2] == 120:
        #show/hide our window
            if isVisible:
            win.hide()
            del keypresses[:]
            keypresses = []
        else:
            win.show_all()
            #clear out our list to compare again
            del keypresses[:]
            keypresses = []
    elif len(keypresses) >= 3:
            del keypresses[:]
            keypresses = []

#create instance of hook manager
HookManager = pyxhook.HookManager()
#define our callback to fire when a key is pressed
HookManager.KeyDown = OnKeyboardEvent
#hook the keyboard
HookManager.HookKeyboard()
#start our listener
HookManager.start()

Gtk.main()
#close the hook listener when gtk main loop exits
HookManager.cancel()

下面是一个小技巧,测试按下F5时窗口的显示/隐藏。当你按下它第二个窗口将显示或隐藏,我已经测试了一段时间没有问题。也许是HookManager以某种方式干扰了Gtk/Glib主循环。尽管如此,我的方法仅在有窗口抓取按键时有效,因此如果您的目标是没有GUI,则确实需要某种形式的抓取按键:

#!/usr/bin/python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
#import pyxhook

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Configurator")

        self.box = Gtk.Box(spacing=6)
        self.add(self.box)

        self.ipEntry = Gtk.Entry()
        self.ipEntry.set_text("IP Address")

        self.maskEntry = Gtk.Entry()
        self.maskEntry.set_text("NetMask")

        self.gatewayEntry = Gtk.Entry()
        self.gatewayEntry.set_text("gatewayEntry")

        self.button1 = Gtk.Button(label="Save")
        self.button1.connect("clicked", self.on_button1_clicked)
        self.box.pack_start(self.ipEntry, True, True, 0)
        self.box.pack_start(self.maskEntry, True, True, 0)
        self.box.pack_start(self.gatewayEntry, True, True, 0)
        self.box.pack_start(self.button1, True, True, 0)

        #catch window destroy event and stop it from happening
        self.connect('delete-event', self.on_destroy)
        self.connect('key-press-event', self.on_keypress)

    def on_keypress(self, widget, event):
        global w
        if event.keyval == Gdk.KEY_F5:
            isVisible = w.get_property("visible")
            if (isVisible):
                w.hide()
            else:
                w.show()
        print("Keypress")

    def on_button1_clicked(self, widget):
        print("Hello")

    def on_destroy(self, widget=None, *data):
        print("tried to destroy")
        self.hide()
        return False

w = MyWindow()

win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
win.set_keep_above(True)


Gtk.main() 

检查你的代码缩进,它似乎不对。我粘贴时Stackoverflow把它搞砸了。这是它的一个容器。虽然我对Python不感兴趣,但我还是要看看。我看到的第一件事是delete事件信号回调返回True。如果返回True,信号将停止传播,并且不会调用Gtk.main\u quit。将其更改为False以正确退出。因此,如果是hookmanager(pyxhook)可能会干扰主循环,我是否应该使用线程并为hookmanager创建一个新线程?同样,在销毁方法的
中使用
返回False
,窗口实际上会被销毁。是的,它会被销毁,因为它被相应地编程。类内的回调隐藏了窗口,但允许信号传播,然后在程序上,您再次添加了删除事件信号处理程序(回调),它将调用Gtk.main_quit,它将退出程序,窗口将被破坏。无论如何,您必须优雅地退出,否则应用程序将无法退出到控制台。关于线程,除非您知道自己在做什么,否则我不建议使用UI主循环,至少那些“从外部”自己更新UI的线程(循环方式)。我现在正在研究各种线程选项,因为很明显hookmanager会干扰gtk主线程。如果需要全局绑定,请查看Keybinder库。谢谢tingping!我已经放弃了用python来做这件事,而是用nodejs来做,这可能会100%解决我的问题。