svineet
svineet

Reputation: 1889

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?

Upvotes: 5

Views: 4219

Answers (3)

Zelphir Kaltstahl
Zelphir Kaltstahl

Reputation: 6189

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.

Upvotes: -1

Tristan Brindle
Tristan Brindle

Reputation: 16824

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.

Upvotes: 7

svineet
svineet

Reputation: 1889

You can check if a window is visible or not using this -

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

Upvotes: 9

Related Questions