简体   繁体   中英

How to detect if a Gtk widget is shown or not

This is a pretty straightforward question.

How can I know if a widget has already been shown? Is there a function?

您可以使用此检查窗口是否可见 -

if mywindow.props.visible: pass # do stuff here

The visible property on a GtkWidget will only tell you whether a widget "should" appear in the UI. It doesn't tell you whether it actually has been yet.

This is important because when you first create a widget, it won't actually be displayed until GTK reenters the main loop. Until it is displayed, things like size negotiation haven't happened yet, and backend storage (GDK resources and so forth) hasn't been allocated. For example, in Python:

Gtk.Window w
w.show_all() # sets "visible" property to True
alloc = w.get_allocation() # Error -- size hasn't been allocated yet!
gdk_window = w.get_window() # Error -- no GDK window yet!

To find out if a widget has actually been shown yet, you need to use the realized property. You can connect to the realize signal to do things that can only be done after the widget has actually been displayed, like the example above.

Based on a few other answers here on SO and some experimenting, I am using this code as a pytest:

import pytest as pytest

from gi.repository import Gtk
from gi.repository import Wnck

from GTKGUITestHelper import GTKGUITestHelper
import GTKSignal
from gui.XLDMainWindow import XLDMainWindow


class TestTemplate:

    xld_main_window = None

    def test_window_created(self, create_xld_main_window):
        """This test tests, whether or not the Gtk.Window has been created.
        """

        screen = Wnck.Screen.get_default()
        screen.force_update() # recommended per Wnck documentation

        window_found = False

        # loop all windows
        for window in screen.get_windows():
            if window.has_name():
                if window.get_name() == self.xld_main_window.get_title():
                    window_found = True
        assert window_found, 'The Gtk.Window named {window_name} has not been found.'.format(window_name=self.xld_main_window.get_title())

        # clean up Wnck (saves resources, check documentation)
        window = None
        screen = None
        Wnck.shutdown()

    @pytest.fixture()
    def create_xld_main_window(self):
        self.xld_main_window = XLDMainWindow()
        self.xld_main_window.connect(GTKSignal.DELETE, Gtk.main_quit)
        self.xld_main_window.show_all()
        GTKGUITestHelper.refresh_gui()

Here is the GTKGUITestHelper :

from gi.repository import Gtk
import time


class GTKGUITestHelper():
    def __init__(self):
        pass

    @classmethod
    def refresh_gui(cls, delay=0):
        #print('delay', delay)
        while Gtk.events_pending():
            Gtk.main_iteration_do(blocking=False)
        time.sleep(float(delay))

This code is from apparently from the insides of Kivy , if sourced correctly on one blog I read. That's where I took it from.

GTKSignal is only a Python file with some signal string constants in it, helping me remembering the signal names and avoiding any typos.

XLDMainWindow can be your Gtk.Window, just exchange it.

This solution uses Wnck , but I guess because it's also imported from gi.repository , it does not hurt to add this dependency. I might be wrong though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM