0
votes

I have connected a callback function to the realize event of a widget.

The widget is a treeview and when it is realized it will fill the table from the database. When I open up an entry from the table, it opens a window where I can edit the data. Then I save the data, the window closes and the table might be refreshed.

So I call treeview.emit('realize') to call the function that fills the treeview again. But the treeview is corrupted, no column headers and the callback function is not called.

I tried also:

treeview.unrealize()
treeview.realize()

some code:

from gi.repository import Gtk
b = Gtk.Builder()
b.add_from_file('file.glade')

def fill_table(treeview, table_name):
    'fills the treeview from database (select * from table_name ...)'
    ...

def open_entry(treeview, row ...):
    'opens the window of the entry'
    w = b.get_object('entry_window')
    ...

def save_and_fill(button):
    'when the SAVE button in the entry_window is clicked, it saves the data, closes the entry_window and fills the treeview'
    #update table1 set column=....
    b.get_object('treeview').emit('realize') #here it might call the fill_table funcion
    b.get_object('entry_window').hide()

signals = {'realize' : lambda *args: fill_table('table1'),
           'row-activated' : open_entry,
           'clicked' : save_and_fill}

b.connect_signals(signals)
b.get_object('main_window').show_all()
Gtk.main()

or just treeview.realize() but it doesn't work.

Is it posible to call the callback function witch is connected to the realize event of widget without destroying the widget?

1
Can you add more code, this is not sufficient to diagnose your issue. - drahnr
First, you seem to have hijacked the realize-signal for your own purpose... If you want to call fill_table() from the button press handler, then call fill_table() from there: don't emit a totally unrelated signal of another object. Second, the way a treeview works is that it should automatically update whenever the data in the model (like ListStore) changes: there should be no reason to call any functions that touch the treeview from the button press handler: you should just modify data in the model. - Jussi Kukkonen
I edited the code above. What if the function, which is connected to the realize event, is dynamically created at connection time? I want to get the function and call it or emit the realize event to call the function. - microo8
You really have no business emitting the realize signal. You can call fill_table() in the realize handler if you want (but like ebassi says, and idle handler would be better), and you can call fill_table() from the clicked handler. - Jussi Kukkonen

1 Answers

1
votes

you should not emit the GtkWidget::realize yourself directly. you can only emit signals with g_signal_emit() (or equiavlent in the language binding) in two cases:

  • it's inside the class installing the signal
  • the signal is marked with the G_SIGNAL_ACTION flag

see: https://developer.gnome.org/gobject/stable/gobject-Signals.html#GSignalFlags

also, you're misusing the GtkWidget::realize in the first place. the realize signal should only be used to allocate windowing system resources, like GdkWindow instances, not to build your widget. if you want to fill the model used by a GtkTreeView, either do that in a specific callback, or use a idle/timeout source inside the main loop.