Code that causes the problem:
def delete_pages(self, *_) -> None:
self.main_stk.set_visible_child_name("main_page")
# remove all pages from stack1
for page in self.pages:
page_id = self.get_page_id(page)
page_child = self.stack1.get_child_by_name(page_id)
self.stack1.remove(page_child)
can someone suggest a better way to remove all pages from a stack
ebassi
(Emmanuele Bassi)
October 14, 2023, 12:41pm
2
If self.pages
is a list model of Gtk.StackPage
instances in stack1
then it’s not safe to remove items while iterating over a list.
You have to collect all pages into a separate list, and then remove them:
def delete_pages(self):
pages = [self.get_page_id(x) for x in self.pages]
for page_id in pages:
w = self.stack1.get_child_by_name(page_id)
self.stack1.remove(w)
in the console I still get is it normal or should I ignore it
/Users/panda/sshfs/bakery-gui.py:1599: Warning: instance with invalid (NULL) class pointer
self.stack1.remove(w)
/Users/panda/sshfs/bakery-gui.py:1599: Warning: g_signal_handlers_disconnect_matched: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
self.stack1.remove(w)
/Users/panda/sshfs/bakery-gui.py:1599: Warning: instance of invalid non-instantiatable type '(null)'
self.stack1.remove(w)
ebassi
(Emmanuele Bassi)
October 14, 2023, 1:13pm
4
That’s coming from GTK itself; which version of GTK are you using?
ebassi
(Emmanuele Bassi)
October 14, 2023, 1:24pm
6
Could you try this example, and see if it emits the same warning:
import gi
gi.require_version("Gtk", "4.0")
from gi.repository import GLib, Gtk
stack = Gtk.Stack()
stack.add_named(Gtk.Button(label="Hello"), "foo")
stack.add_named(Gtk.Button(label="World"), "bar")
stack.add_named(Gtk.Button(label="Goodbye"), "baz")
pages = stack.get_pages()
assert len(pages) == 3
names = [x.get_name() for x in pages]
assert len(names) == len(pages)
print(names)
for name in names:
w = stack.get_child_by_name(name)
stack.remove(w)
assert len(pages) == 0
Do you use a Gtk.StackSideBar with the Stack?
If yes, then I’m pretty sure the crash is related to this issue .
is there any fix it still happens
ebassi
(Emmanuele Bassi)
October 25, 2023, 9:50am
9
You haven’t answered the question from me or @gwillems , so “is there any fix” isn’t really something we can answer.
yes I do its called stack1_sidebar in my code
OK, so I’m quite sure it’s the same issue I reported.
There is a fix under review, may take a little bit of time till it gets reviewed/integrated/released…
In the meantime, you could tweak your code to keep a reference to the page, to avoid the use-after-free crash.
Maybe something like this should be enough:
for page in self.pages:
page_id = self.get_page_id(page)
page_child = self.stack1.get_child_by_name(page_id)
self.stack1.remove(page_child)
page # does nothing, just here to keep an active reference during remove()
Thanks will try this when I can
Is there a issue/merge I can track
It still seg faults even when calling page
hmm, now I’m confused…
What about this?
for page in list(self.pages):
page_child = page.get_child()
self.stack1.remove(page_child)
Traceback (most recent call last):
File "/home/panda/Bakery/bakery-gui.py", line 278, in delete_pages
page_child = page.get_child()
^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'get_child'
self.next_btn.set_sensitive(self.current_page < num_pages - 1)
self.back_btn.set_sensitive(self.current_page > 0)
def on_cancel_clicked(self, button) -> None:
# connect the yes button to the delete_pages function
self.cancel_dialog.present()
def delete_pages(self, dialog, resp) -> None:
if resp == "yes":
self.main_stk.set_visible_child(self.main_page.get_child())
# remove all pages from stack1
pages = [self.get_page_id(x) for x in self.pages]
for page_id in pages:
w = self.stack1.get_child_by_name(page_id)
self.stack1.remove(w)
self.cancel_dialog.hide()
def get_page_id(self, page_name) -> str:
return page_name
here’s the code if u wanna take a deeper look
Ah OK, thanks, I see, I thought self.pages
was a list model of Gtk.StackPages
…
Can you please try this?
for page in self.pages:
page_id = self.get_page_id(page)
page_child = self.stack1.get_child_by_name(page_id)
stackpage = self.stack1.get_page(page_child)
self.stack1.remove(page_child)
stackpage # does nothing, just used to keep an active reference during remove()
it does not, on another note now i have a segfault in a different place
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.832: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.832: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
malloc(): unaligned fastbin chunk detected
Fatal Python error: Aborted
Thread 0x0000ffff53fff120 (most recent call first):
File "/home/panda/Bakery/./bakery-gui.py", line 671 in run
File "/usr/lib/python3.11/threading.py", line 1038 in _bootstrap_inner
File "/usr/lib/python3.11/threading.py", line 995 in _bootstrap
Thread 0x0000ffff51fbf120 (most recent call first):
File "/usr/lib/python3.11/concurrent/futures/thread.py", line 81 in _worker
File "/usr/lib/python3.11/threading.py", line 975 in run
File "/usr/lib/python3.11/threading.py", line 1038 in _bootstrap_inner
File "/usr/lib/python3.11/threading.py", line 995 in _bootstrap
Thread 0x0000ffff957bf120 (most recent call first):
File "/usr/lib/python3.11/concurrent/futures/thread.py", line 81 in _worker
File "/usr/lib/python3.11/threading.py", line 975 in run
File "/usr/lib/python3.11/threading.py", line 1038 in _bootstrap_inner
File "/usr/lib/python3.11/threading.py", line 995 in _bootstrap
Current thread 0x0000ffff99017020 (most recent call first):
File "/usr/lib/python3.11/site-packages/gi/overrides/Gio.py", line 42 in run
File "/home/panda/Bakery/./bakery-gui.py", line 1042 in <module>
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.832: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.833: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.833: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.833: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.833: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.833: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
Extension modules: gi._gi
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.834: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.834: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(bakery-gui.py:67328): Pango-CRITICAL **: 11:21:21.835: pango_layout_line_unref: assertion 'private->ref_count > 0' failed
(total: 1)
fish: Job 1, 'python ./bakery-gui.py' terminated by signal SIGABRT (Abort)
when trying to present a dialog im doing it from a different thread
class InstallThread(threading.Thread):
def __init__(self, window, install_window):
threading.Thread.__init__(self)
self.window = window
self.install_window = install_window
def run(self):
install_data = self.window.collect_data()
lp("Starting install with data: " + str(install_data))
res = bakery.install(install_data, do_deferred=False)
if res == 0:
# Change to finish page
.... *Code here works*
else:
sleep(2.5)
self.window.err_dialog.present()
Hi,
don’t call Gtk APIs outside of the main thread, they’re not thread-safe.
Instead of:
sleep(2.5)
self.window.err_dialog.present()
better do:
GLib.timeout_add(2500, self.window.err_dialog.present)
that will call “present” asynchronously from the main gtk thread.
system
(system)
Closed
January 24, 2024, 1:32pm
19
This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.