简体   繁体   English

Gtk MessageDialog导致段错误(PYGObject)

[英]Gtk MessageDialog causes segfault (PYGObject)

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. 如果解决方案显而易见,请原谅我,这只是我的第二个GTK +程序。

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. (2ndgtk + .py:32073):Gtk-警告**:GtkMessageDialog 0x7ff51400a040:小部件尝试在GtkWidget :: get_width实现内进行gtk_widget_get_width。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_width directly rather than using gtk_widget_get_width 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_width,而不要使用gtk_widget_get_width

(2ndgtk+.py:32073): Gtk-WARNING **: GtkBox 0x7ff514004080: widget tried to gtk_widget_get_width inside GtkWidget ::get_width implementation. (2ndgtk + .py:32073):Gtk警告**:GtkBox 0x7ff514004080:小部件尝试在GtkWidget :: get_width实现内进行gtk_widget_get_width。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_width directly rather than using gtk_widget_get_width 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_width,而不要使用gtk_widget_get_width

(2ndgtk+.py:32073): Gtk-WARNING **: GtkButtonBox 0x2170620: widget tried to gtk_widget_get_width inside GtkWidget ::get_width implementation. (2ndgtk + .py:32073):Gtk-警告**:GtkButtonBox 0x2170620:小部件尝试在GtkWidget :: get_width实现内进行gtk_widget_get_width。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_width directly rather than using gtk_widget_get_width 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_width,而不要使用gtk_widget_get_width

(2ndgtk+.py:32073): Gtk-WARNING **: GtkButton 0x7ff514010050: widget tried to gtk_widget_get_height inside GtkWidget ::get_height implementation. (2ndgtk + .py:32073):Gtk-警告**:GtkButton 0x7ff514010050:小部件尝试在GtkWidget :: get_height实现内进行gtk_widget_get_height。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_height,而不要使用gtk_widget_get_height

(2ndgtk+.py:32073): Gtk-WARNING **: GtkAlignment 0x7ff514014070: widget tried to gtk_widget_get_height inside GtkWidget (2ndgtk + .py:32073):Gtk警告**:GtkAlignment 0x7ff514014070:小部件尝试在GtkWidget中进行gtk_widget_get_height
::get_height implementation. :: get_height实现。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_height,而不要使用gtk_widget_get_height

(2ndgtk+.py:32073): Gtk-WARNING **: GtkBox 0x7ff514004320: widget tried to gtk_widget_get_height inside GtkWidget ::get_height implementation. (2ndgtk + .py:32073):Gtk-警告**:GtkBox 0x7ff514004320:小部件尝试在GtkWidget :: get_height实现内进行gtk_widget_get_height。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_height,而不要使用gtk_widget_get_height

(2ndgtk+.py:32073): Gtk-WARNING **: GtkLabel 0x22a2ac0: widget tried to gtk_widget_get_height inside GtkWidget ::get_height implementation. (2ndgtk + .py:32073):Gtk警告**:GtkLabel 0x22a2ac0:小部件尝试在GtkWidget :: get_height实现内进行gtk_widget_get_height。 Should just invoke GTK_WIDGET_GET_CLASS(widget)->get_height directly rather than using gtk_widget_get_height Segmentation fault 应该只直接调用GTK_WIDGET_GET_CLASS(widget)-> get_height,而不要使用gtk_widget_get_height分段错误

I figured it out. 我想到了。 The problem was calling "window.failDialog" directly instead of with GLib.idle_add. 问题是直接调用“ window.failDialog”,而不是使用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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM