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()
Cœur
  • 37,241
  • 25
  • 195
  • 267
G. Esel
  • 31
  • 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. – Chiheb Nexus Mar 01 '17 at 13:57
  • @ChihebNexus Yes here is the spirit of the code i would do – G. Esel Mar 01 '17 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? – theGtknerd Mar 02 '17 at 03: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. – G. Esel Mar 02 '17 at 07:37
  • Is it not sufficient for you to decouple the data from the UI elements? Like having two treeviews for one treestore for example – elya5 Mar 02 '17 at 12:52
  • elya5 has given you the answer to multiple treeviews with identical data. And if you really want less code, try Glade https://glade.gnome.org/ for designing your UI. Are we missing something? – theGtknerd Mar 02 '17 at 16:36

3 Answers3

1

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.)

andlabs
  • 11,290
  • 1
  • 31
  • 52
  • 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. – G. Esel Mar 01 '17 at 22:12
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 !

G. Esel
  • 31
  • 6
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()
Chiheb Nexus
  • 9,104
  • 4
  • 30
  • 43
  • 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) – G. Esel Mar 01 '17 at 20:25
  • 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 ? – G. Esel Mar 02 '17 at 07:40