2012-11-15 176 views
3

访问类变量(的Qt::Action秒的阵列)当我已经具有分割故障的问题,以及我一直在试图以削减下来到复制问题的最小代码例如:为什么我会出现分段错误(qtruby)?

#!/usr/bin/ruby 

require 'Qt4' 
require 'rufus/scheduler' 

app = Qt::Application.new(ARGV) 

class ManagerWidget < Qt::Widget 
    signals 'changed(int)' 

    def initialize 
     super(nil) 

     max_index = 2 
     next_index = 0 

     scheduler = Rufus::Scheduler.start_new 
     scheduler.every '10s' do 
      emit changed(next_index) 
      if next_index < max_index - 1 
       next_index += 1 
      else 
       next_index = 0 
      end 
     end 
    end 
end 

class Tray < Qt::Widget 
    def initialize 
     super(nil) 

     tray = Qt::SystemTrayIcon.new 
     manager_widget = ManagerWidget.new 
     menu = Qt::Menu.new 

     tray_icon = Qt::Icon.new("./icons/Gnome-Preferences-Desktop-Wallpaper-64.png") 

     actions = [] 
     manager_widget.connect(SIGNAL('changed(int)')) do |i| 
      puts "changed #{i}" 
      actions[i].text = '...' if actions && actions[i] 
     end 

     2.times do |i| 
      sub_menu = Qt::Menu.new("#{i + 1}") 
      actions[i] = sub_menu.add_action('x') 
      menu.add_menu(sub_menu) 
     end 

     tray.icon = tray_icon 
     tray.context_menu = menu 

     tray.show 
    end 
end 

Tray.new 
app.exec 

上面的代码输出:

"sni-qt/12147" WARN 14:35:48.326 void StatusNotifierItemFactory::connectToSnw() Invalid interface to SNW_SERVICE 
changed 0 
changed 1 
changed 0 
changed 1 
changed 0 
changed 1 
changed 0 
changed 1 
./min-code-example.rb:42: [BUG] Segmentation fault 
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux] 
[... snipped due to character limits on posting ...] 
[NOTE] 
You may have encountered a bug in the Ruby interpreter or extension libraries. 
Bug reports are welcome. 
For details: http://www.ruby-lang.org/bugreport.html 

Aborted (core dumped) 
Failed (134) 

这似乎是必要使用子菜单来触发这个问题 - 至少加入行动,托盘菜单本身运行相当长一段时间没有问题(我只要使用上面的代码获取错误,就将其保留10次以上)。

红宝石版本:ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]

Qt的版本:4.8.1

绑定版本:qtbindings (4.8.3.0)

Linux版本的:Ubuntu 12.04

另一个奇数行为是从puts调用的输出有时会显示立即在控制台中,其他时候,只有当我将鼠标悬停在托盘图标上时才会打印。

我甚至不知道从哪里开始,因此需要对其进行跟踪,因此您所输入的任何内容都将非常感谢。

更新:我已经离开了这一段时间,因为我无法进一步。我试着重新开始,但我仍然遇到同样的问题。我深入研究了这个问题,并且由于它说'missing_method',我开始打印类以确保我确实在查看Qt :: Action(我是),然后根据actions[0].methods

.methods输出:

[:setShortcut, :shortcut=, :qobject_cast, :inspect, :pretty_print, :className, 
:class_name, :inherits, :findChildren, :find_children, :findChild, :find_child, 
:connect, :method_missing, :const_missing, :dispose, :isDisposed, :disposed?, 
:qVariantValue, :qVariantFromValue, :**, :+, :~, :[email protected], :-, :*, :/, :%, :>>, 
:<<, :&, :^, :|, :<, :<=, :>, :>=, :==, :is_a?, :kind_of?, :methods, 
:protected_methods, :public_methods, :singleton_methods, :qDebug, :qFatal, 
:qWarning, :SIGNAL, :SLOT, :emit, :QT_TR_NOOP, :QT_TRANSLATE_NOOP, :nil?, :===, 
:=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, 
:initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust, 
:untrusted?, :trust, :freeze, :frozen?, :to_s, :private_methods, 
:instance_variables, :instance_variable_get, :instance_variable_set, 
:instance_variable_defined?, :instance_of?, :tap, :send, :public_send, 
:respond_to?, :respond_to_missing?, :extend, :display, :method, :public_method, 
:define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, 
:instance_eval, :instance_exec, :__send__, :__id__, "blockSignals", "children", 
"connect", "deleteLater", "disconnect", "dumpObjectInfo", "dumpObjectTree", 
"dynamicPropertyNames", "event", "eventFilter", "inherits", "installEventFilter", 
"widgetType?", "killTimer", "metaObject", "moveToThread", "objectName", "parent", 
"property", "qt_metacall", "qt_metacast", "removeEventFilter", "objectName=", 
"parent=", "setProperty", "setUserData", "signalsBlocked", "startTimer", 
"thread", "userData", "actionGroup", "activate", "associatedGraphicsWidgets", 
"associatedWidgets", "autoRepeat", "data", "font", "hover", "icon", "iconText", 
"checkable?", "checked?", "enabled?", "iconVisibleInMenu?", "separator?", 
"visible?", "menu", "menuRole", "parentWidget", "priority", "actionGroup=", 
"autoRepeat=", "checkable=", "checked=", "data=", "disabled=", "enabled=", 
"font=", "icon=", "iconText=", "iconVisibleInMenu=", "menu=", "menuRole=", 
"priority=", "separator=", "shortcut=", "shortcutContext=", "shortcuts=", 
"softKeyRole=", "statusTip=", "text=", "toolTip=", "visible=", "whatsThis=", 
"shortcut", "shortcutContext", "shortcuts", "showStatusText", "softKeyRole", 
"statusTip", "text", "toggle", "toolTip", "trigger", "whatsThis"] 

在这种情况下,我试图做actions[0].enabled = true当分段错误发生,这是在输出据我所知(从底部6号线,enabled=)。我也试过setEnabled(true),set_enabled(true),几乎可以想到任何事情。

即使在动作对象上调用inspect正在导致分段错误,尽管在最初将动作放在数组中的循环中这样做是很好的。我真的不明白哪里出了问题。

编辑:为了回应使用QTimer的建议,我尝试了这个,我仍然遇到同样的问题。该代码是目前一个公平位比上面列出更复杂,所以我会在这里写一些简单的伪代码来说明流量:

def init_tray 
    actions = [] 
    2.times do |i| 
     actions[i] = ... # init and add to systray, store reference in array 
    end 
    update = Proc.new do |i| 
     actions[i].setText('...') # update the text on one of the actions defined above 
    end 
    listener = ... # create a listener that can be called by Manager on certain events - will call the update Proc among other things. 
    manager = Manager.new(..., listener) 
end 

的呼叫Manager.new该对象并初始化end用状态改变调用监听器,这又调用update Proc,它访问actions数组。在这个阶段,这应该全都在同一个线程中,除了实际创建Qt::Action之外,这些线都不依赖于QT。我已经删除了Rufus调度,并用QTimer替换了它,但它只是远远不够,因此成为问题。

+2

你确定你可以使用像这样的qtbindings吗? qtbindings是否线程安全?你知道Rufus创建了一个新的Ruby线程吗?我想,一旦你进入Qt世界,你需要使用Qt定时器而不是Ruby定时器。即为了触发'emit',你可能需要使用'QTimer'而不是Rufus。 – Casper

+0

@Casper,我不知道,我不知道Rufus创建了一个新的Ruby线程,不。即使它不是线程安全的,它仍然是一种非常奇怪的失败方式(仍然只有一个线程可以随时访问它,并且参考看起来很好,因为我可以打印出关于它的一些信息)。我仍然只是想学习QT,并没有意识到我可以使用QTimer,我会给它一个去,谢谢。 – Thor84no

+0

@Casper这毕竟看起来不是问题,Rufus调度器根本没有运行失败的代码(因为它在初始化过程中失败了,应该仍然是主线程)。我已经添加了一些关于它的详细信息,以帮助澄清这个问题。 – Thor84no

回答

0

我在这方面花了太多时间,却无法弄清楚为什么会发生这种情况(感谢那些试图提供帮助的人,但不幸未能解决问题)。因此,我把这里的工作放在这里作为一个答案,以防别人有类似的问题:

我已经取消了数组,而不是包装在Proc中使用它的代码我在先前填充数组的循环内创建。由于在这个循环中创建的Proc可以直接访问有问题的变量,因此不再需要将其存储在数组中并在以后检索它。由于Proc中的代码现在每执行一次SIGNAL就会执行一次,而不是让一个代码块执行所有相关操作,但它们明显更易于处理,因此它引发了一两个自己的问题。

1

有一件事,我没有看到你已经尝试过使用更新的ruby版本。 p0似乎可能充满问题。

Ruby 1.9.3-p392是1.9.3的最新版本。

+0

当我使用Mint软件包管理器安装ruby时,它不时更新,它目前在'1.9.3p194'上。不是我想的最新版本,但是在我一直在搞这个的时候,我已经试过了至少几个不同的补丁版本。不过好的建议,我会看看是否可以在某些时候手动安装最新版本。 – Thor84no

相关问题