Как установить гравитацию в окне GTK3+ в python

Я запускаю python 2.7.13 в Windows 7. Я создаю окно с Gtk (из pygobject 3.18.2).

Я использую Windows 7 с пользовательской оболочкой и пытаюсь сделать панель инструментов внизу экрана.

Я использую сетку, чтобы разделить окно на верхнюю и нижнюю части.

Нижняя часть всегда видна. Верхняя часть должна отображаться над нижней частью при входе мыши и скрываться при выходе из мыши, не перемещая нижнюю часть.

Позиционирование окна по умолчанию использует верхний левый угол окна, но это приведет к тому, что нижняя часть сместится вверх до положения верхней части, когда верхняя часть скрыта.

Я думаю, я понимаю, что я должен использовать

set_gravity(Gdk.Gravity.SOUTH_WEST)

изменить это поведение

Я не получаю ошибок, но кажется, что этот параметр игнорируется. Расположение окна никак не влияет.

Что я упускаю?
Что-то не так в том, как я вызываю set_gravity()?
Подходит ли set_gravity для достижения этой цели?

Я прочитал Установить гравитацию окна в 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 и enter-notify.

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. Возможно, проблема с оконным менеджером. я расследую

Кто-нибудь успешно использовал set_gravity() в Windows?


person bbuggy    schedule 07.07.2017    source источник
comment
Запуск этого против Python 3 под MSYS2, кажется, дает желаемый результат, Py2 v Py3 не должен здесь отличаться, но есть ли какая-то конкретная причина для запуска нового проекта в Python 2?   -  person Zander Brown    schedule 07.07.2017
comment
@AlexB Я использую Eventghost в качестве оболочки. Eventghost работает на Python 2.7. Мне нравится все упрощать и использовать один язык   -  person bbuggy    schedule 07.07.2017


Ответы (1)


В документации указано, что это может работать или не работать, в зависимости от оконного менеджера. Это не для меня на Xubuntu 18.04

person gerardw    schedule 19.02.2020