3

在访问类变量(s 数组)时,我一直遇到分段错误问题Qt::Action,我一直在尝试将其缩减为复制该问题的最小代码示例:

#!/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, :**, :+, :~, :-@, :-, :*, :/, :%, :>>,
:<<, :&, :^, :|, :<, :<=, :>, :>=, :==, :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 的调用初始化该对象,最后调用具有状态更改的侦听器,这反过来又调用访问数组的updateProc 。actions在这个阶段这应该都在同一个线程中,除了实际创建Qt::Action. 我已经删除了 Rufus 调度并将其替换为QTimer,但它还远远不足以解决这个问题。

4

2 回答 2

1

我没有看到您尝试过的一件事是使用较新的 ruby​​ 版本。p0 似乎可能充满问题。

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

于 2013-03-13T19:21:37.053 回答
0

我在这方面花了太长时间,但无法弄清楚为什么会发生这种情况(感谢那些试图提供帮助的人,但不幸的是它没有解决问题)。因此,我将我的解决方法放在这里作为答案,以防其他人遇到类似问题:

I've done away with the array, instead wrapping the code that was to use it in a Proc that I create inside the loop that was previously populating the array. Since a Proc created within this loop has direct access to the variable in question, there is no longer any need to store it in an array and retrieve it later. It brought up one or two issues of it's own since the code in the Proc is now executed once per action per SIGNAL rather than having one code block going through all relevant actions, but they were significantly easier to handle.

于 2013-03-18T17:39:19.403 回答