0

I'm currently using gtk on Python to create some graphical interfaces. And I'm struggling with a little issue : I want to display a gtk.widget (HBox or Button for example) on several pages of a notebook but I can't succeed. The widget is only displayed on the first page where it is used but never on the following ones. I've tried the reparenting method but inverted problem, the widget is only displayed on the last one.

import gtk
w = gtk.Window(gtk.WINDOW_TOPLEVEL)
w.connect("destroy", gtk.main_quit)
w.set_title("Some tests")
legnth = 850
width = 700
w.set_size_request(length, width)

VBoxWindow = gtk.HBox()

hbox1 = gtk.HBox()
notebook1 = gtk.Notebook()
page1 = gtk.Notebook()
page12 = gtk.VBox()
page13 = gtk.VBox()
page14 = gtk.VBox()

page1.append_page(page12, gtk.Label(' PAGE1 ')
page1.append_page(page13, gtk.Label(' PAGE2 ')
page1.append_page(page14, gtk.Label(' PAGE3 ')

box1 = gtk.VBox()
button1 = gtk.Button("BTN 1")
box1.pack_start(button1, True, True, 5)
page12.pack_start(box1, False, False, 5)

box2 = gtk.VBox()
box2.pack_start(button1, True, True, 5)
page13.pack_start(box2, False, False, 5)

# reparenting method test
#box3 = gtk.VBox()
#button1.reparent(box3)
#box3.pack_start(button1, True, True, 5)
#page13.pack_start(box3, False, False, 5)

page1.props.border_width = 12
page1.add(page12)
page1.add(page13)
notebook1.append_page(page1, gtk.Label('Some MAIN Page'))
VBoxWindow.add(notebook1)
w.add(VBoxWindow)
displayReady = True
w.show_all()
gtk.main()
6
  • Please add what you have done so far. Don't pay attention if it's wrong. All what i need is an overview of what you're trying to do. Commented Mar 1, 2017 at 13:57
  • @ChihebNexus Yes here is the spirit of the code i would do Commented Mar 1, 2017 at 18:06
  • @G.Esel And what are you doing exactly? Why does it not work in your case to create duplicate widgets? Less code maybe? Commented Mar 2, 2017 at 3:08
  • @theGtknerd Yes less code and also the widget that I want to created once in different pages is a really really heavy tree (list of things) that I can't load N times for N pages because it would take minutes for the app to launch. Moreover it has to be the same on every pages and not independent copies. Commented Mar 2, 2017 at 7:37
  • Is it not sufficient for you to decouple the data from the UI elements? Like having two treeviews for one treestore for example Commented Mar 2, 2017 at 12:52

3 Answers 3

2

No, a widget can only have one parent at a time. If you want the same controls to appear on all pages of the tab, you'll have to either create duplicate controls, dynamically move them when tab pages are changed, or put them outside the tab control entirely.

Moving controls around is done by calling remove() on the old parent and add() (or a control-specific variant, such as push_start()) on the new parent. (I forget if you need to manage reference counts in Python; if so, you also have to ref() the widget being moved first and unref() it later; otherwise, remove() will destroy the widget.)

Sign up to request clarification or add additional context in comments.

1 Comment

Okay thank you ! And how is it possible to detect the change of the pages ? I'm rather new to gtk and an example of your technique would be lovely.
1

Sorry for the wait but I completely forgot to share my solution with you guys !

Here's what I found :

def reparent_on_switch(self, widget, page):
    for p in range(widget.get_n_pages()):
        container = widget.get_nth_pages(p)
        if not (p == page):
            pass
        else:
            self.foo.reparent(container)
            container.pack_start(self.foo)

It works like a charm !

Comments

0

You can follow this tutorial within pyGObject and python3 in order to solve your issue.

Try, to follow each step:

# This is a test application within PyGObject version 3.0+
import gi
# Test if gi version is 3.0+ 
gi.require_version('Gtk', '3.0')

from gi.repository import Gtk

class TestNoteBook(Gtk.Window):
    def __init__(self):
        # Initialize Gtk.Window
        Gtk.Window.__init__(self)
        # Add title to this app
        self.set_title("Test Note Book")
        # Connect the close button to self.quit_app() method
        self.connect("delete-event", self.quit_app)

        # Create a new Gtk.Widget with type Gtk.Notebook()
        notebook = Gtk.Notebook()
        # Add notebook to the current app class
        self.add(notebook)
        # Create a Gtk.HBox() in which we can add widgets
        page1 = Gtk.HBox()
        # Create button1
        button1 = Gtk.Button("I'm in the page 1")
        # Connect button1 to a signal
        button1.connect("clicked", self.button_clicked, "button1")
        # Add a Button to page1
        page1.add(button1)
        # Add page1 to the notebook with label page-1
        notebook.append_page(page1, Gtk.Label("page-1"))
        # Create new Gtk.HBox()
        page2 = Gtk.HBox()
        # Create button2
        button2 = Gtk.Button("I'm in the page 2")
        # Add a signal to button2
        button2.connect("clicked", self.button_clicked, "button2")
        # Add a button to page2
        page2.add(button2)
        # Add pag2e to the notebook with label page-2
        notebook.append_page(page2, Gtk.Label("page-2"))

    def run(self):
        # Show all the widgets
        self.show_all()
        # Run the Gtk.main loop
        Gtk.main()

    def quit_app(self, widget, args):
        # Print a message with the ID of the widget and its argument
        print("Exit this current window...", widget, args)
        # Exit from the window
        Gtk.main_quit()

    def button_clicked(self, widget, args):
        if args == "button1":
            print("Button 1 clicked!")
        else:
            print("Button2 clicked!")


# test
if __name__ == '__main__':
    app = TestNoteBook()
    app.run()

2 Comments

Yeah but in this example your created 2 different buttons linked on the same signal but the main problem was that I wanted to have one single button either displayed on the both the pages of the notebook. My issue is to find a way either to have the exactly same button (or widget) at the same time on different pages of the notebook (as if it exists on the both pages) or a way like to switch the unique button in function of the current page used of the notebook (to have the impression that the same button exists on both pages)
I just read the tutorial you've recommended but there is anything about a way to maybe reparent a widget depending on the current page used in the notebook. Would you aware of any technique for that ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.