Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct method to display a large popup menu?

A picture paints a thousand words...:

enter image description here

In my Python 2.7 application I have a button which when clicked pops up a menu.

In some circumstances this list is larger than the screen size.

  • In Ubuntu 12.04 (uses Gtk 3.4.2) this is OK because you get scroll-arrows (as shown on the right of the picture).

  • In Ubuntu 12.10/13.04 and Fedora 17 (uses Gtk 3.6) I get the same menu but with no scroll-arrows and you cannot scroll up or down using the mouse.

The strange part is that if I click the button again - the scroll arrows reappear.

So it looks like some-sort of size-allocation issue - its not been calculated on first-popup but is on subsequent pop-up's

Hence my question

Something obviously has changed with newer GTK libraries - what is now the correct method to display a large popup menu to ensure the scroll arrows are displayed?

Any hints how I should tackle this apparent difference between different GTK versions so that I can get a consistent "show arrows on first click"?

Below is a simple python test program that demonstrates this issue.

I couldn't use GTKParasite to diagnose this because the popup disappears as soon as you click the "Inspect" button on GtkParasite itself.

# -*- Mode: python; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*-

#!/usr/bin/env python

from gi.repository import Gtk

def popupclick(self, *args):
    popup.popup(None, None, None, None, 0,
            Gtk.get_current_event_time())

window = Gtk.Window()
window.connect('delete_event', Gtk.main_quit)
window.set_default_size(200,200)

first_item = None
popup = Gtk.Menu()

for i in range(100):
    label = 'Item %d' % i
    if not first_item:
        new_menu_item = Gtk.RadioMenuItem(label=label)
        first_item = new_menu_item
    else:
        new_menu_item = Gtk.RadioMenuItem.new_with_label_from_widget(
            group=first_item, label=label)

    new_menu_item.show()
    popup.append(new_menu_item)
    
button = Gtk.Button()
button.connect('clicked', popupclick)
mainbox = Gtk.Box()
mainbox.pack_start(button, True, True, 0)
scroller = Gtk.ScrolledWindow()
scroller.add_with_viewport(mainbox)
window.add(scroller)
    
window.show_all()

Gtk.main()
like image 675
fossfreedom Avatar asked Oct 21 '22 19:10

fossfreedom


2 Answers

I browsed around a little in the documentation, and instead of using popup.append(new_menu_item) you could use popup.attach(new_menu_item, left, right, top, bottom) to put your menu items in a grid instead of one long line.

But it seems like you would be better off opening a window with a scrollable list, though!

like image 137
ptomato Avatar answered Nov 15 '22 04:11

ptomato


Use a GtkComboBoxText. But as ptomato said, this kind of presentation isn't adapted to lists of a huge amount of values. Either reduce the number of values to show, or use a GtkTreeView, which will have a scroll bar and won't need an initial click to show values.

like image 39
liberforce Avatar answered Nov 15 '22 05:11

liberforce