Frage

What is wrong with my program? It works fine until it tries to show the dialog box and then it segfaults.

Forgive me if the solution is obvious, this is only my second GTK+ program.

import time, threading
from sys import exit
from gi.repository import Gtk, GObject


def run_core_engine():
    time.sleep(2)
    window.switchToMainFrame()
    time.sleep(2.5)
    window.failDialog("The window said hello")


class CoreThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True
        super(CoreThread, self).start()
    def run(self):
        run_core_engine()


class GettingInfoFrame(Gtk.Frame):
    def __init__(self):
        Gtk.Frame.__init__(self)
        self.connect("delete-event", Gtk.main_quit)
        self.set_shadow_type(Gtk.ShadowType.NONE)
        self.set_border_width(45)

        vbox = Gtk.VBox(spacing=10)
        hbox = Gtk.HBox(spacing=10)

        text = Gtk.Label()
        text.set_markup("<b><big>Doing stuff...</big></b>")
        self.spinner = Gtk.Spinner()
        self.spinner.set_size_request(30, 30)
        self.spinner.start()

        hbox.pack_start(text, True, True, 10)
        hbox.pack_start(self.spinner, True, True, 10)
        vbox.pack_start(hbox, True, True, 10)

        self.add(vbox)


class TheMainFrame(Gtk.Frame):
    def __init__(self):
        Gtk.Frame.__init__(self)
        self.set_shadow_type(Gtk.ShadowType.NONE)
        self.set_border_width(150)

        label = Gtk.Label("Hello")
        box = Gtk.VBox()
        box.pack_start(label, True, True, 0)
        self.add(box)


class Window(Gtk.Window):
    def __init__(self):
        ## Setup Main Window
        Gtk.Window.__init__(self, title="Fred the window")
        self.connect("delete-event", Gtk.main_quit)
        self.set_resizable(False)

        self.gettingInfoFrame = GettingInfoFrame()
        self.add(self.gettingInfoFrame)

    def switchToMainFrame(self):
        print("Displaying information in window")
        self.theMainFrame = TheMainFrame()
        self.remove(self.get_child())
        self.add(self.theMainFrame)
        self.show_all()

    def failDialog(self, message):
        dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, "INFO:")
        dialog.format_secondary_text(message)
        dialog.run()  **# <-- Where the error occurs**

        Gtk.main_quit()


GObject.threads_init()

core_thread = CoreThread()

window = Window()
window.show_all()

Gtk.main()

The error jargon:

Displaying information in window

(2ndgtk+.py:32073): Gtk-WARNING **: GtkMessageDialog 0x7ff51400a040: widget tried to gtk_widget_get_width inside GtkWidget ::get_width implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_width directly rather than using gtk_widget_get_width

(2ndgtk+.py:32073): Gtk-WARNING **: GtkBox 0x7ff514004080: widget tried to gtk_widget_get_width inside GtkWidget ::get_width implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_width directly rather than using gtk_widget_get_width

(2ndgtk+.py:32073): Gtk-WARNING **: GtkButtonBox 0x2170620: widget tried to gtk_widget_get_width inside GtkWidget ::get_width implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_width directly rather than using gtk_widget_get_width

(2ndgtk+.py:32073): Gtk-WARNING **: GtkButton 0x7ff514010050: widget tried to gtk_widget_get_height inside GtkWidget ::get_height implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height

(2ndgtk+.py:32073): Gtk-WARNING **: GtkAlignment 0x7ff514014070: widget tried to gtk_widget_get_height inside GtkWidget
::get_height implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height

(2ndgtk+.py:32073): Gtk-WARNING **: GtkBox 0x7ff514004320: widget tried to gtk_widget_get_height inside GtkWidget ::get_height implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height

(2ndgtk+.py:32073): Gtk-WARNING **: GtkLabel 0x22a2ac0: widget tried to gtk_widget_get_height inside GtkWidget ::get_height implementation. Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height Segmentation fault

War es hilfreich?

Lösung

I figured it out. The problem was calling "window.failDialog" directly instead of with GLib.idle_add. I added some other slight changes.

Here is the new code:

import time, threading
from sys import exit
from gi.repository import Gtk, GObject, GLib


def run_core_engine():
    time.sleep(2)
    window.switchToMainFrame()
    time.sleep(2.5)
    GLib.idle_add(window.failDialog, "The window said hello")


class CoreThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True
        super(CoreThread, self).start()
    def run(self):
        run_core_engine()


class GettingInfoFrame(Gtk.Frame):
    def __init__(self):
        Gtk.Frame.__init__(self)
        self.connect("delete-event", Gtk.main_quit)
        self.set_shadow_type(Gtk.ShadowType.NONE)
        self.set_border_width(45)

        vbox = Gtk.VBox(spacing=10)
        hbox = Gtk.HBox(spacing=10)

        text = Gtk.Label()
        text.set_markup("<b><big>Doing stuff...</big></b>")
        self.spinner = Gtk.Spinner()
        self.spinner.set_size_request(30, 30)
        self.spinner.start()

        hbox.pack_start(text, True, True, 10)
        hbox.pack_start(self.spinner, True, True, 10)
        vbox.pack_start(hbox, True, True, 10)

        self.add(vbox)


class TheMainFrame(Gtk.Frame):
    def __init__(self):
        Gtk.Frame.__init__(self)
        self.set_shadow_type(Gtk.ShadowType.NONE)
        self.set_border_width(150)

        label = Gtk.Label("Hello")
        box = Gtk.VBox()
        box.pack_start(label, True, True, 0)
        self.add(box)


class Window(Gtk.Window):
    def __init__(self):
        ## Setup Main Window
        Gtk.Window.__init__(self, title="Fred the window")
        self.connect("delete-event", Gtk.main_quit)
        self.set_resizable(False)

        self.gettingInfoFrame = GettingInfoFrame()
        self.add(self.gettingInfoFrame)

    def switchToMainFrame(self):
        print("Displaying information in window")
        self.theMainFrame = TheMainFrame()
        self.remove(self.get_child())
        self.add(self.theMainFrame)
        self.show_all()

    def failDialog(self, errorMessage):
        dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, "INFO:")
        dialog.format_secondary_text(errorMessage)
        dialog.run()

        Gtk.main_quit()


GObject.threads_init()

core_thread = CoreThread()

window = Window()
window.show_all()

Gtk.main()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top