获取“Gtk:ERROR”尝试运行 WxRuby

发布于 2024-12-04 08:09:04 字数 3372 浏览 0 评论 0原文

我正在使用ubuntu 10.04,并且正在尝试运行一个wxruby示例,我从此网站 wxrubywiki 。我一直在通过网上寻求帮助,但找不到类似的东西...

我遇到了这个错误...

Gtk:ERROR:/build/buildd/gtk+2.0-2.20.1/gtk/gtkwindow.c:6789:IA__gtk_window_present_with_time: assertion failed: (widget->window != NULL)
Aborted

这些是我正在使用的版本...

ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
gem list
...
wxruby (2.0.1 x86-linux)
...

这是我正在尝试的代码跑...

require 'rubygems' if RUBY_VERSION < '1.9'
require 'wx'

class EventFrame < Wx::Frame
    def initialize()
        super(nil, -1, "Event Frame")
        @idleCounter = 0
        evt_close {|event| on_close(event)}
        evt_idle {|event| on_idle(event)}
        evt_size {|event| on_size(event)}
        evt_key_down {|event| on_key(event)}
        evt_left_down {|event| on_left_down(event)}
        # You can still process these events, you just need to define a separate callback for middle_down and right_down
        # to process them as separate events
        evt_middle_down {|event| on_middle_down(event)}
        evt_right_down {|event| on_right_down(event)}

        button = Wx::Button.new(self, -1, "Push me")
        evt_button(button.get_id()) {|event| on_button(event)}

        show()
    end

    def message(text, title)
        m = Wx::MessageDialog.new(self, text, title, Wx::OK | Wx::ICON_INFORMATION)
        m.show_modal()
    end

    def on_close(event)
        message("This frame will be closed after you push ok", "Close event")
        #close(true) - Don't call this - it will call on_close again, and your application will be caught in an infinite loop
        # Either call event.skip() to allow the Frame to close, or call destroy(), as follows
        destroy()
    end

    def on_idle(event)
        @idleCounter += 1
        if @idleCounter > 15 # Without the counter to slow this down, Idle events would be firing every second
            message("The system is idle right now", "Idle event")
            @idleCounter = 0
        end
        event.request_more() # You must include this, otherwise the Idle event won't occur again
    end

    def on_size(event)
        size = event.get_size()
        x = size.x
        y = size.y
        message("X = " + x.to_s + ", Y = " + y.to_s, "Size event")
    end

    def on_key(event)
        message("Key pressed", "Key Event")
    end

    def on_left_down(event)
        button = ""
        if event.left_down()
            button = "Left"
        end
        message(button + " button was clicked", "Mouse event")
    end

    def on_middle_down(event)
        # This method hasn't been implemented yet...
        #if event.middle_down()
           #button = "Middle"
        #end
        message("Middle button was clicked", "Mouse event")
    end

    def on_right_down(event)
        # This method hasn't been implemented yet...
        #if event.right_down()
            #button = "Right"
        #end
        message("Right button was clicked", "Mouse event")
    end

    def on_button(event)
        message("Button was clicked", "Button event")
    end
end

class MyApp < Wx::App
    def on_init
        EventFrame.new()
    end
end

MyApp.new.main_loop

提前谢谢!

I'm using Ubuntu 10.04 and I'm trying to run a WxRuby example which I copy-pasted from this site WxRubyWiki. I've been looking for help over the net but I couldn't find anything similar...

I'm getting this error...

Gtk:ERROR:/build/buildd/gtk+2.0-2.20.1/gtk/gtkwindow.c:6789:IA__gtk_window_present_with_time: assertion failed: (widget->window != NULL)
Aborted

These are the versions I'm using...

ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
gem list
...
wxruby (2.0.1 x86-linux)
...

And this is the code I'm trying to run...

require 'rubygems' if RUBY_VERSION < '1.9'
require 'wx'

class EventFrame < Wx::Frame
    def initialize()
        super(nil, -1, "Event Frame")
        @idleCounter = 0
        evt_close {|event| on_close(event)}
        evt_idle {|event| on_idle(event)}
        evt_size {|event| on_size(event)}
        evt_key_down {|event| on_key(event)}
        evt_left_down {|event| on_left_down(event)}
        # You can still process these events, you just need to define a separate callback for middle_down and right_down
        # to process them as separate events
        evt_middle_down {|event| on_middle_down(event)}
        evt_right_down {|event| on_right_down(event)}

        button = Wx::Button.new(self, -1, "Push me")
        evt_button(button.get_id()) {|event| on_button(event)}

        show()
    end

    def message(text, title)
        m = Wx::MessageDialog.new(self, text, title, Wx::OK | Wx::ICON_INFORMATION)
        m.show_modal()
    end

    def on_close(event)
        message("This frame will be closed after you push ok", "Close event")
        #close(true) - Don't call this - it will call on_close again, and your application will be caught in an infinite loop
        # Either call event.skip() to allow the Frame to close, or call destroy(), as follows
        destroy()
    end

    def on_idle(event)
        @idleCounter += 1
        if @idleCounter > 15 # Without the counter to slow this down, Idle events would be firing every second
            message("The system is idle right now", "Idle event")
            @idleCounter = 0
        end
        event.request_more() # You must include this, otherwise the Idle event won't occur again
    end

    def on_size(event)
        size = event.get_size()
        x = size.x
        y = size.y
        message("X = " + x.to_s + ", Y = " + y.to_s, "Size event")
    end

    def on_key(event)
        message("Key pressed", "Key Event")
    end

    def on_left_down(event)
        button = ""
        if event.left_down()
            button = "Left"
        end
        message(button + " button was clicked", "Mouse event")
    end

    def on_middle_down(event)
        # This method hasn't been implemented yet...
        #if event.middle_down()
           #button = "Middle"
        #end
        message("Middle button was clicked", "Mouse event")
    end

    def on_right_down(event)
        # This method hasn't been implemented yet...
        #if event.right_down()
            #button = "Right"
        #end
        message("Right button was clicked", "Mouse event")
    end

    def on_button(event)
        message("Button was clicked", "Button event")
    end
end

class MyApp < Wx::App
    def on_init
        EventFrame.new()
    end
end

MyApp.new.main_loop

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兔姬 2024-12-11 08:09:04

更多的是了解GTK+2/wx/wxRuby是如何工作的。事实上,上面的代码不适用于我设置来测试的 Virtual Box 机器中的配置,也不适用于我的开发机器的带有 1000Hz 内核编译选项的 Ubuntu 11.10 x86_64 和 ruby​​ 1.9.3 p21。

当 on_size 事件在帧创建期间触发时,会发生 GTK+2 错误。创建尚未完成,因此消息框当时没有父级。您可以通过注释掉(在 def on_size(event): 中

message("X = " + x.to_s + ", Y = " + y.to_s, "Size event")

并尝试:

puts "Size event: X = #{x}, Y = #{y}"

查看标准输出上的事件详细信息来测试这一点。您会注意到在创建过程中触发了两个事件;一个初始大小事件和一个调整大小事件

另一个警告是锁定 Unity 系统的空闲循环 您可以通过更改以下代码来测试空闲事件是否发生而不会锁定:

在 def 初始化中在 show(): 之前添加此内容:

create_status_bar(2)
self.status_text = "Welcome to wxRuby!"

然后在idle_event:

def on_idle(event)
  @idleCounter += 1
  #if @idleCounter > 15 # Without the counter to slow this down, Idle events would be firing every second
  #    message("The system is idle right now", "Idle event")
  #    @idleCounter = 0
  #end
  set_status_text @idleCounter.to_s, 1
  event.request_more() # You must include this, otherwise the Idle event won't occur again
end

关于代码的最后一个警告是你可能会注意到你没有看到这是因为按钮控件会填充客户区域并捕获按键和按钮的框架事件,如果您在应用程序运行时调整框架大小,则默认情况下按钮不会随之调整大小。 (GTK+2 平台)如果您随后单击框架客户区域而不是按钮,您将看到鼠标事件

It is more of an understanding of how GTK+2/wx/wxRuby works. As is, the code above does not work on your configuration in a Virtual Box machine I set to test this nor my development machine's Ubuntu 11.10 x86_64 with 1000Hz kernel compile option and ruby 1.9.3 p21.

The GTK+2 error occurs when the on_size event fires during frame creation. The creation is not yet complete so the message box does not have a parent at that time. You can test this by commenting out (in def on_size(event):

message("X = " + x.to_s + ", Y = " + y.to_s, "Size event")

and trying:

puts "Size event: X = #{x}, Y = #{y}"

to see the event details on standard out. You will notice there are two events fired during creation; an initial size event and a resize event

Another caveat is the idle loop which locks Unity o my system. You can test that the idle event is happening without a lock up by changing the code as below:

in def initialize add this before show():

create_status_bar(2)
self.status_text = "Welcome to wxRuby!"

then in idle_event:

def on_idle(event)
  @idleCounter += 1
  #if @idleCounter > 15 # Without the counter to slow this down, Idle events would be firing every second
  #    message("The system is idle right now", "Idle event")
  #    @idleCounter = 0
  #end
  set_status_text @idleCounter.to_s, 1
  event.request_more() # You must include this, otherwise the Idle event won't occur again
end

A last caveat about the code is you may notice you don't see the key or mouse down events creating their message box. That is because the button control fills the client area and traps the frame events for keys and buttons. If you resize the frame while the app is running the button will not resize with it by default (GTK+2 platform). If you then click inside the frame client area but not on the button you will see mouse events.

Good Luck !

风吹过旳痕迹 2024-12-11 08:09:04

这个问题已修复并可在 ubuntu 11.10 中运行:)

this fixed and works in ubuntu 11.10 :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文