スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    PyQtでシグナルを定義する

     Qtと言えば、インターフェースで何らかしらのアクションが発生した場合、シグナルに紐付けられたスロットが実行される流れが主流ですね!
     そう、何かあればシグナルにコネクトすべし!と言う感じですが、シグナルをコネクトする際に面倒な事もあります。

     例えばボタンをクリックした際に呼ばれたスロットでボタンのラベルを取得したい場合、シグナルには何の手がかりもないため、結局ボタンをクラス内メソッドに持っておかないといけないかったり。
     もしくは各ボタンのclickedシグナルに、別々の関数をコネクトするなど、何かと不細工なコードになりがちです。

     そこで、シグナルを自作して、自分の欲しい情報を引数として渡すようにしてみます。



     とりあえずサンプルコードをば。
    # -*- coding:utf-8 -*-
    
    import sys
    from PyQt4 import QtGui, QtCore
    
    # /////////////////////////////////////////////////////////////////////////////
    # クリック時に予めセットした文字列をシグナルとして送るボタン。               //
    # /////////////////////////////////////////////////////////////////////////////
    class MyPushButton( QtGui.QPushButton ):
    
    	clickedWithText = QtCore.pyqtSignal( str )	# シグナル
    	
    	def __init__( self, *arglist, **argdict ):
    		super( MyPushButton, self ).__init__( *arglist, **argdict )
    
    		# ボタンクリック時に↑で定義したシグナルに信号を送るために
    		# clickedシグナルにコネクトする。
    		self.clicked.connect( self.emitWithText )
    
    	def emitWithText( self ):
    		# クリック時にclickWithTextシグナルにエミットするための中間メソッド。 
    		self.clickedWithText.emit( self.text() )
    # /////////////////////////////////////////////////////////////////////////////
    #                                                                            //
    # /////////////////////////////////////////////////////////////////////////////
    
    
    
    class MainWindow( QtGui.QWidget ):
    	def __init__( self, parent=None ):
    		super( MainWindow, self ).__init__( parent )
    		self.resize( 420, 80 )
    		self.setWindowTitle( 'Signal Exsample' )
    
    		layout = QtGui.QGridLayout( self )
    		
    		# カスタムボタンを作成。-----------------------------------------------
    		button1 = MyPushButton( 'Alphabet' )
    		button1.clickedWithText.connect( self.output )
    
    		button2 = MyPushButton( 'Number' )
    		button2.clickedWithText.connect( self.output )
    
    		button3 = MyPushButton( 'Hoge' )
    		button3.clickedWithText.connect( self.output )
    		# ---------------------------------------------------------------------
    		
    		self.resultText = QtGui.QLineEdit( '' )
    		self.resultText.setReadOnly( True )
    
    		layout.addWidget( button1, 1, 1, 1, 1 )
    		layout.addWidget( button2, 1, 2, 1, 1 )
    		layout.addWidget( button3, 1, 3, 1, 1 )
    		layout.addWidget( self.resultText, 2, 1, 1, 3 )
    		layout.setRowStretch( 3, 1 )
    
    	def output( self, text ):
    		self.resultText.setText( text )
    
    if __name__ == '__main__':
    	app    = QtGui.QApplication( sys.argv )
    	window = MainWindow()
    	window.show()
    	
    	sys.exit( app.exec_() )
    

     出来上がりはこんな感じ。
    signalSample001.png
     各ボタンをクリックすると、下のラインエディットにボタンの名前が表示されます。

     シグナルを自作するには
    QtCore.pyqtSignal

    を使用します。
     引数としてクラスオブジェクト(インスタンスじゃないです)を渡します。引数の数だけEmit時にそれをスロット側に渡す事になります。
     今回のサンプルではstr型をスロットに渡したかったので一つだけ引数として渡していますが、好きな数だけ引数を増やせる模様。


     そして、スロットを実行したいタイミングでこの自作シグナルのemitメソッドに引数を添えて実行すればOK!
     今回の例ですと、ボタンの名前を添えてスロットを呼び出しているので、各ボタンをクラス内変数にしたり、ボタンの数だけメソッドを増やす事なく実装できました。
      う~ん、素晴らしい!!

     もっと早くに気付きたかった~!!
    スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココからアクセスできますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。