hakeの日記

Windows環境でプログラミングの勉強をしています。

ウィジェットに名前をつける

Ruby/Qteの勉強 その38
りなざうテクノウさんの掲示板に話題があったので実験。
個々のウィジェットにはsetName(string)で名前をつけることができる、名前を読むにはnameメソッドを使用する。トップレベルのfocusWidget.nameで現在フォーカスのあるウィジェット名を取得できる。
下のプログラムではLineEdit(@e1,@e2,@e3)にフォーカスが当たった場合にその名前と書かれている内容を@e4に表示する、内容が空白の場合はnilを表示。ボタンにフォーカスがあるときには何もしない。

QLineEditを継承したクラスEditは、フォーカスがあたるとクラス変数@@focusNameに自分の名前を代入してシグナルfocusInを発生させる。メイン側ではこのシグナルを受けて@@focusNameの内容表示。さらにハッシュを使用して名前からEditのインスタンス変数名を引き、そこに書かれている内容も表示させる。

#!/usr/bin/env ruby

require "qte"
require "qpe"
include Qte
include Qpe

class SampleWindow < QMainWindow
   def initialize()
      super()
      setCaption(tr("サンプル"))
      @l1 = QLabel.new(self)
      @l1.setText(tr("フォーカスのあるLineEditの名前と内容を表示"))
      @l1.setGeometry(0, 0, 600, 35)

      @l1 = QLabel.new("@e1", self)
      @l1.setGeometry(10, 40, 50, 35)
      @e1 = Edit.new(self)
      @e1.setName("LineEdit01")               # @e1に名前をつける
      @e1.setGeometry(60, 40, 440, 35)
      connect(@e1.focusIn, self, 'dispName')  # フォーカスがあたったら名前表示
      @p1 = QPushButton.new("btn01", self)    # ダミーボタン作成
      @p1.setGeometry(500, 40, 100, 35)

      @l2 = QLabel.new("@e2", self)
      @l2.setGeometry(10, 80, 50, 35)
      @e2 = Edit.new(self)
      @e2.setName("LineEdit02")
      @e2.setGeometry(60, 80, 440, 35)
      connect(@e2.focusIn, self, 'dispName')
      @p2 = QPushButton.new("btn02", self)
      @p2.setGeometry(500, 80, 100, 35)

      @l3 = QLabel.new("@e3", self)
      @l3.setGeometry(10, 120, 50, 35)
      @e3 = Edit.new(self)
      @e3.setName("LineEdit03")
      @e3.setGeometry(60, 120, 440, 35)
      connect(@e3.focusIn, self, 'dispName')
      @p3 = QPushButton.new("btn03", self)
      @p3.setGeometry(500, 120, 100, 35)

      @l4 = QLabel.new("@e4", self)
      @l4.setGeometry(10, 160, 50, 35)
      @e4 = QMultiLineEdit.new(self)         # 名前表示用エリア
      @e4.setName("LineEdit04")
      @e4.setGeometry(60, 160, 440, 240)
      @e4.setFocusPolicy(QWidget::NoFocus)   # フォーカス対象外

      @h = { 'LineEdit01' => '@e1',          # 名前と変数名の対応
             'LineEdit02' => '@e2',
             'LineEdit03' => '@e3' }

      @line = 0
      @e1.setFocus                           # @e1にフォーカス
      dispName
   end

   # Editオブジェクトの名前と書かれている内容を表示
   def dispName
      name = Edit.readFocusName              # Editのクラス変数読み出し
      if name == 'noname'                    # クラス変数に名前が設定されていない場合
         str2 = 'nil'
      else
         str1 = "#{@h[name]}\.text.to_str"   # 名前をキーにしてインスタンス変数名を取得
         str2 = eval("#{str1}")              #   更に書かれているテキスト値を取得
         str2 = 'nil' if str2 == ''          # テキストが空の場合
      end
      @e4.insertAt("#{name} = #{str2}\n" , @line, 0)   # @e4に表示
      @line += 1                             # 表示位置更新
   end
end

# Editクラスの定義
class Edit < QLineEdit
   def initialize(parent)
      super(parent)
      @@focusName = "noname"     # クラス変数初期化
      @focusIn = RSignal.new     # シグナル作成
      catchEvent                 # イベントの取得
   end

   attr_reader :focusIn

   def Edit.readFocusName        # クラス変数読み出しメソッド
      @@focusName
   end

   def focusInEvent(e)           # フォーカスがあたったら
      @@focusName = self.name    # クラス変数に名前を代入して
      @focusIn.send              # シグナル発生
   end
end

$defaultCodec = QTextCodec.codecForName("utf8")
app = QPEApplication.new([$0]+ARGV)
app.setDefaultCodec($defaultCodec)
QApplication.setFont(QFont.new("lcfont", 18))
app.showMainWidget(SampleWindow.new)
app.exec