Difference between revisions of "Archive:Development/Tutorials/Qt4 Ruby Tutorial/Chapter 07 (zh CN)"

Jump to: navigation, search
m (Text replace - "</code>" to "</syntaxhighlight>")
 

Latest revision as of 16:49, 23 June 2013

Template:I18n/Language Navigation Bar (zh CN)

Template:TutorialBrowser (zh CN)

Contents

[edit] One Thing Leads to Another

Qt4 Ruby Tutorial Screenshot 7.png

档案:

[edit] 概览

这个范例展示如何建立具有讯号和槽的自定义 widget,以及如何用更复杂的方式将它们连接起来。这是第一次,原始码被分割在几个档案中。

[edit] 一行一行的浏览

lcdrange.rb

这个档案主要是抄袭自第6章,这里只提出比较特别的改变。

signals 'valueChanged(int)'
slots 'setValue(int)'
def value()
  @slider.value()
end
 
def setValue(value)
  @slider.setValue(value)
end

这些构成了这个 widget 和程序中其他组件之间的接口。到目前为止,LCDRange 还没真的拥有一个 API。

value() 是一个存取 LCDRange 值的公开(public)函式、setValue() 是我们第一个自定义槽,而 valueChanged()是我们第一个自定义讯号。

Slot 必须用正规方式实作(槽也是一个 Ruby 成员函式)。讯号会被自动实作。讯号遵循 Ruby 保护(protected)函式的存取规则(换言之,只有定义他们的类别或继承的类别可以发出它们)。

LCDRange 的值发生改变时,valueChanged() 讯号就会被使用。

value() 的实作非常简单。它只是返回 slider 的值。

setValue() 的实作也同样简单。请注意,因为 slider 和 LCD number 连接,设定 slider 的值时,LCD number 也会自动更新。此外,如果超出规定范围,slider 会自动调整值。

connect(@slider, SIGNAL('valueChanged(int)'),
        lcd, SLOT('display(int)'))
connect(@slider, SIGNAL('valueChanged(int)'),
        self, SIGNAL('valueChanged(int)'))

第一个 QObject::connect() 呼叫与前几章看到的相同。第二个是新的,它连接 QAbstractSlider::valueChanged() 讯号到这个对象的 valueChanged() 讯号。是的,没错。讯号也可以连接到其他的讯号。当第一个讯号被发出时,第二个讯号也被发出。

让我们看看当使用者操作 slider 时,会发生什么事。当 slider 发现它的值已经改变,就会发出QAbstractSlider::valueChanged() 讯号。这个讯号连接到 Qt::LCDNumberQLCDNumber::display() 槽和 LCDRangevalueChanged() 讯号。

因此,当这个讯号发出时,LCDRange 也发出自己的 valueChanged() 讯号。此外,QLCDNumber::display() 被呼叫并显示新的数字。

请注意,你不能确定任何执行的特定顺序,LCDRange::valueChanged() 可能会在QLCDNumber::display() 被呼叫之前或之后发出。

t7.rb

previousRange = nil
 
for row in 0..2
  for column in 0..2
    lcdRange = LCDRange.new()
    grid.addWidget(lcdRange, row, column)
    unless previousRange.nil?
      connect(lcdRange, SIGNAL('valueChanged(int)'),
              previousRange, SLOT('setValue(int)'))
    end
    previousRange = lcdRange
  end
end

当我们建立9个 LCDRange 对象时,我们使用讯号与槽机制将它们连接在一起。每一个 LCDRangevalueChanged() 讯号都会连接到前一个的 setValue() 槽。因为每当 LCDRange 的值改变时,都会发出 valueChanged() 讯号,所以我们在这里建立一个讯号与槽的连锁反应。

[edit] 执行应用程序

在启动时,这支程序的外观和前一章的一模一样。尝试操作右下角的 slider。

[edit] 练习

使用右下角的 slider 来设定所有 LCD 为50。然后单击底部中间 slider 把手的左侧,设定除了最后一个所有的 LCD 为40。现在,使用左下角的 slider 来设定前七个 LCD 回到50。

按下右下角 slider 把手的左侧。会发生什么事?为什么这是正确的行为?


This page was last modified on 23 June 2013, at 16:49. This page has been accessed 2,130 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal