【问题标题】:How to set the gravity on a GTK3+ window in python如何在 python 中的 GTK3+ 窗口上设置重力
【发布时间】:2017-07-07 09:52:09
【问题描述】:

我在 Windows 7 上运行 python 2.7.13。 我正在使用 Gtk 创建一个窗口(来自 pygobject 3.18.2)。

我正在运行带有自定义外壳的 Windows 7,并且我正在尝试在屏幕底部制作一个工具栏。

我使用网格将窗口分为顶部和底部。

底部始终可见。 顶部必须在鼠标进入时显示在底部上方,在鼠标离开时隐藏而不移动底部。

窗口的默认定位使用窗口的左上角,但是当顶部隐藏时,这会导致底部向上移动到顶部的位置。

我想我明白我必须使用

set_gravity(Gdk.Gravity.SOUTH_WEST)

改变这种行为

我没有收到错误,但似乎此设置被忽略了。窗口的位置完全不受影响。

我错过了什么?
我调用 set_gravity() 的方式有什么问题吗?
set_gravity 是实现这一目标的正确方法吗?

我看了Set window gravity in PyGObject?,但这个问题还是没有答案

这是我尝试使用的代码

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

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Test")
        self.set_decorated(0)
        self.screen = Gdk.Screen.get_default()
        self.connect("destroy", self.destroy)
        self.connect("enter-notify-event", self.mouseenter)
        self.connect("leave-notify-event", self.mouseleave)

        self.label1 = Gtk.Label("Label1\n    line1\n    line2")
        self.label2 = Gtk.Label("Label2")

        self.label1.set_hexpand(True)
        self.label2.set_hexpand(True)

        self.maingrid = Gtk.Grid()
        self.add(self.maingrid)

        self.maingrid.attach(self.label1, 0, 0, 1, 1)
        self.maingrid.attach(self.label2, 0, 1, 1, 1)

        self.set_gravity(Gdk.Gravity.SOUTH_WEST)  # looks like this is ignored
        print self.get_gravity()

    def mouseleave(self, widget, data=None):
        print "mouse leave"

        self.label1.hide()
        label2_height = self.label2.get_allocation().height
        self.resize(self.screen.width(), label2_height)

    def mouseenter(self, widget, data=None):
        print "mouse enter"

        label1_height = self.label1.get_allocation().height
        label2_height = self.label2.get_allocation().height
        self.resize(self.screen.width(), label1_height + label2_height)

        self.label1.show()

        # Here I expect label2 to stay where it is at the bottom of the screen and label1 to be drawn above label2.
        # But label2 is pushed down to make space for label1
        # (normal behaviour if Gdk.Gravity.SOUTH_WEST is not set)

    def destroy(self, widget, data=None):
        print "destroy signal occurred"
        Gtk.main_quit()

win = MyWindow()
win.show_all()
win.label1.hide()

height = win.label2.get_allocation().height
win.resize(win.screen.width(), height)

#win.move(0, win.screen.height())           # I expect this to place the window at the bottom of the screen
                                            # if Gdk.Gravity.SOUTH_WEST is set, but it is placed offscreen
                                            # (normal behaviour if Gdk.Gravity.SOUTH_WEST is not set)

win.move(0, win.screen.height() - 200)      # shift it up 200 pixels to see what is happening


Gtk.main()

这是一个工作版本,我在调整大小后将窗口移动到适当的位置。移动窗口会使窗口闪烁,同时也会产生 leave-notify-event 和 enter-notify-event。

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

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Test")
        self.set_decorated(0)
        self.screen = Gdk.Screen.get_default()
#        self.set_gravity(Gdk.Gravity.SOUTH_WEST)
        self.connect("destroy", self.destroy)
        self.connect("enter-notify-event", self.mouseenter)
        self.connect("leave-notify-event", self.mouseleave)

        self.label1 = Gtk.Label("Label1\n    line1\n    line2")
        self.label2 = Gtk.Label("Label2")

        self.label1.set_hexpand(True)
        self.label2.set_hexpand(True)

        self.maingrid = Gtk.Grid()
        self.add(self.maingrid)

        self.maingrid.attach(self.label1, 0, 0, 1, 1)
        self.maingrid.attach(self.label2, 0, 1, 1, 1)
        self.ismoving = 0

    def mouseleave(self, widget, data=None):
        print "mouse leave"

        if self.ismoving:
            print "window is moving"
        else:
            self.label1.hide()
            label2_height = self.label2.get_allocation().height
            self.resize(self.screen.width(), label2_height)
            self.move(0, self.screen.height() - label2_height)

    def mouseenter(self, widget, data=None):
        print "mouse enter"

        if self.ismoving:           # moving the window generates a leave-notify-event and a enter-notify-event
            self.ismoving = 0       # ignore these events when moving the window
        else:
            self.ismoving = 1

            label1_height = self.label1.get_allocation().height
            label2_height = self.label2.get_allocation().height
            self.resize(self.screen.width(), label1_height + label2_height)

            self.move(0, self.screen.height()-label1_height - label2_height)

            self.label1.show()

    def destroy(self, widget, data=None):
        print "destroy signal occurred"
        Gtk.main_quit()

win = MyWindow()
win.show_all()
win.label1.hide()

height = win.label2.get_allocation().height
win.resize(win.screen.width(), height)
win.move(0, win.screen.height() - height)


Gtk.main()

根据 AlexB 的评论,我认为我的代码是正确的,但它对我不起作用。我看不出它不能在 python 2 下运行的任何原因。可能是窗口管理器有问题。我会调查的

有人在 Windows 上成功使用 set_gravity() 吗?

【问题讨论】:

  • 在 MSYS2 下对 Python 3 运行这个似乎产生了预期的结果,Py2 v Py3 在这里应该没有什么不同,但是在 Python 2 中启动一个新项目有什么特别的原因吗?
  • @AlexB 我使用 Eventghost 作为我的外壳。 Eventghost 在 python 2.7 上运行。我喜欢保持简单并使用一种语言

标签: windows python-2.7 gtk3 pygobject


【解决方案1】:

文档表明它可能工作也可能不工作,具体取决于窗口管理器。 Xubuntu 18.04 不适合我

【讨论】:

    猜你喜欢
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多