3

我是 QT 新手,在尝试创建自定义绘制事件时在 Windows 7 x64 上发生崩溃。我正在使用 Ruby 1.9.3p125 和 qtbindings-4.8.3.0-x86-mingw32。在我的工作机器 Redhat Linux 上使用 Ruby 1.9.2p180 和 qtbindings-4.6.3.4 时不会出现此崩溃

我最初在遵循“C++ Gui Programming with QT 4”(移植到 Ruby)中的 IconEditor 示例时遇到了这个问题,但在下面的示例中简化了这个问题。

此示例代码创建了一个计时器,用于在子类 QWidget 中重复绘制一条简单的线。在 Windows 上,在 Ruby 给出分段违规之前,paintEvent 会触发约 440 次。这是代码:

#!/usr/bin/env ruby

require 'Qt'

class Painter < Qt::Widget
  slots :startTimer

  def initialize(parent=nil)
    super(parent)
    setAttribute Qt::WA_StaticContents
    setSizePolicy(Qt::SizePolicy::Minimum, Qt::SizePolicy::Minimum)

    @counter = 0
    @timer = Qt::Timer.new(self)
    connect(@timer, SIGNAL('timeout()'), self, SLOT(:startTimer))
    startTimer
  end

  def sizeHint
    Qt::Size.new(200,200)
  end

  def paintEvent(event)
    puts "DEBUG: paintEvent #{@counter += 1} #{event.inspect}"
    painter = Qt::Painter.new(self)
    painter.setPen(palette.foreground.color)
    painter.drawLine(0, 0, 200, 200)
  end

  def startTimer
    @timer.start(5)
    update
  end

end


app = Qt::Application.new(ARGV)
painter = Painter.new
painter.show
app.exec

这是回溯:

DEBUG: paintEvent 440 #<Qt::PaintEvent:0x3328938>
DEBUG: paintEvent 441 #<Qt::PaintEvent:0x3327de0>
DEBUG: paintEvent 442 #<Qt::PaintEvent:0x3327420>
DEBUG: paintEvent 443 #<Qt::PaintEvent:0x3326928>
./main.rb:27: [BUG] Segmentation fault
ruby 1.9.3p125 (2012-02-16) [i386-mingw32]

-- Control frame information -----------------------------------------------
c:0008 p:---- s:0024 b:0024 l:000023 d:000023 CFUNC  :method_missing
c:0007 p:0107 s:0022 b:0022 l:000021 d:000021 METHOD ./main.rb:27
c:0006 p:---- s:0017 b:0017 l:000016 d:000016 FINISH
c:0005 p:---- s:0015 b:0015 l:000014 d:000014 CFUNC  :method_missing
c:0004 p:0013 s:0011 b:0011 l:000010 d:000010 METHOD C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/Qt/qtruby4.rb:469
c:0003 p:0098 s:0008 b:0008 l:001aec d:0023bc EVAL   ./main.rb:41
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:001aec d:001aec TOP

-- Ruby level backtrace information ----------------------------------------
./main.rb:41:in `<main>'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/Qt/qtruby4.rb:469:in `exec'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/Qt/qtruby4.rb:469:in `method_missing'
./main.rb:27:in `paintEvent'
./main.rb:27:in `method_missing'

-- C level backtrace information -------------------------------------------
C:\Windows\SysWOW64\ntdll.dll(ZwWaitForSingleObject+0x15) [0x77d5f8b1]
C:\Windows\syswow64\kernel32.dll(WaitForSingleObjectEx+0x43) [0x76c01194]
C:\Windows\syswow64\kernel32.dll(WaitForSingleObject+0x12) [0x76c01148]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_vm_bugreport+0xf9) [0x62e5c61d]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_name_err_mesg_new+0x17a) [0x62d3a6fa]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_bug+0x2f) [0x62d3b45b]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_check_safe_str+0x1a4) [0x62dee1a0]
 [0x004011e6]
C:\Windows\syswow64\kernel32.dll(GetProfileStringW+0x12aa3) [0x76c4003f]
C:\Windows\SysWOW64\ntdll.dll(RtlKnownExceptionFilter+0xb7) [0x77db74df]

-- Other runtime information -----------------------------------------------

* Loaded script: ./main.rb

* Loaded features:

    0 enumerator.so
    1 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/encdb.so
    2 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/iso_8859_1.so
    3 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/trans/transdb.so
    4 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/defaults.rb
    5 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/rbconfig.rb
    6 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/deprecate.rb
    7 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/exceptions.rb
    8 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/defaults/operating_system.rb
    9 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
   10 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems.rb
   11 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/version.rb
   12 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/requirement.rb
   13 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/platform.rb
   14 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb
   15 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/path_support.rb
   16 C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/Qt/qtruby4.rb
   17 C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/1.9/qtruby4.so
   18 C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/Qt4.rb
   19 C:/Ruby193/lib/ruby/gems/1.9.1/gems/qtbindings-4.8.3.0-x86-mingw32/lib/Qt.rb
   20 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/utf_16le.so
   21 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/trans/single_byte.so
   22 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/trans/utf_16_32.so

编辑:: 没有什么比回答你自己的问题...

paintEvent 类需要包含“painter.end”语句。我找不到这方面的文档,但它在 qtbindings 包含的示例中,我只是错过了它。毫无疑问,这会调用 QPainter 对象析构函数来防止内存泄漏导致程序崩溃。

这是更正后的代码:

def paintEvent(event)
  puts "DEBUG: paintEvent #{@counter += 1} #{event.inspect}"
  painter = Qt::Painter.new(self)
  painter.setPen(palette.foreground.color)
  painter.drawLine(0, 0, 200, 200)
  painter.end
end
4

0 回答 0