スポンサーサイト

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

    PyQtでコンテキストメニューを表示する

     今度はPyQtでコンテキストメニュー(右クリックメニュー)を表示します。
    こんな感じ↓

    pyQtContextMenuSample.jpg

     今回も相変わらず色々ややこしかったです。まぁわかればどうと言う事はないのですが。。。
     誰か日本語で詳しく優しく最初から丁寧に解説して下さるサイトはないものか・・・(´ε`;)ウーン…
     正直あってるかどうか不安なんですよねぇ~



     ・・・ま、いっか



    それではソースファイルです。前々回のヤツの改造版です。


    # -*- coding:utf-8 -*-
    import sys
    from PyQt4 import QtGui, QtCore
    
    
    # *****************************************************************************
    # ダイアログクラス*************************************************************
    # *****************************************************************************
    MY_DATA = {
        'taro'  : '1990, 01, 01',
        'hanako': '1990, 02, 01',
        'jiro'  : '1990, 03, 01',
        'takako': '1990, 04, 01',
    }
    
    
    
    class MyDialog( QtGui.QDialog ):
        def __init__( self, parent=None ):
            # 親クラスの初期化。
            super( MyDialog, self ).__init__( parent )
            # ウィンドウ名を設定。
            self.setWindowTitle( 'Tree View Sample' )
            self.index = 0
    
    
            # リストを作成=========================================================
            # QTreeViewを作成。
            self.treeview = QtGui.QTreeView()
            self.treeview.setSortingEnabled( True )     #ソート機能を有効化
            # QTreeViewにコンテキストを追加
            self.treeview.setContextMenuPolicy( QtCore.Qt.CustomContextMenu )
            self.treeview.customContextMenuRequested.connect( self.buildContextMenu )
    
    
            # QStandardItemModel
            self.stdItemModel = QtGui.QStandardItemModel( 0, 2, parent )
            self.stdItemModel.setHeaderData( 0, QtCore.Qt.Horizontal, 'Name' )
            self.stdItemModel.setHeaderData( 1, QtCore.Qt.Horizontal, 'Date' )
    
    
            # QStandardItemModelにアイテムを追加。
            index = 0
            for key in MY_DATA.keys():
                # ローカル8ビットに文字セットを変換してQStandardItemを作成
                nameitem = QtGui.QStandardItem( QtCore.QString.fromLocal8Bit(key) )
                dateitem = QtGui.QStandardItem( QtCore.QString.fromLocal8Bit(MY_DATA[key]) )
                dateitem.setEditable( False )
    
                self.stdItemModel.setItem( index, 0, nameitem )
                self.stdItemModel.setItem( index, 1, dateitem )
                index += 1
    
            # QTreeViewにmodelをセット。
            self.treeview.setModel( self.stdItemModel ) 
    
            # stdItemModelにシグナルを追加し、self.slotメソッドを接続。
            QtCore.QObject.connect(
                self.treeview.selectionModel(),
                QtCore.SIGNAL('selectionChanged(QItemSelection, QItemSelection)'),
                self.slot
            )
            # =====================================================================
    
    
    
            # レイアウトを定義。===================================================
            layout = QtGui.QHBoxLayout()        #レイアウトを作成。
            layout.addWidget( self.treeview )   #レイアウトにQTreeViewを追加。
            self.setLayout( layout )            #ダイアログにレイアウトをセット。
            # =====================================================================
    
        def slot( self, selected, deselected ):
            for item in selected:
                # セレクトされている各アイテムのインデックスを取得する。
                indexes = item.indexes()
    
                # indexesにはセレクトされた列の各種情報が入っているので、
                # それをfor文で全て取得する。
                textlist = list()
                for index in indexes:
                    print( type(index) )
                    # 各インデックスのデータを取得
                    data = index.data()
                    # 取得したデータを文字列に変換して取得
                    textlist.append( str(data.toString()) )
                text = ' - '.join( textlist )
                print( text )
    
    
        def buildContextMenu( self, qPoint ):
            # メニューを作成
            menu = QtGui.QMenu( self.treeview )
            menulabels = ['Copy Data', 'Set Data', 'Delete']
            actionlist = []
            for label in menulabels:
                actionlist.append( menu.addAction( label ) )
    
            action = menu.exec_( self.treeview.mapToGlobal( qPoint ) )
            for act in actionlist:
                if act == action:
                    print( '  - Menu Label is "%s"' % act.text() )
    # *****************************************************************************
    # *****************************************************************************
    # *****************************************************************************
    
    
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication( sys.argv )
        dialog = MyDialog()
    
        sys.exit( dialog.exec_() )
    

     まず、32行目からQTreeViewにコンテキストメニューの設定を記述しています。
    self.treeview.setContextMenuPolicyで、コンテキストメニューのタイプを指定しています。(たぶん)
     今回はカスタムを指定していますが、他にもActionsContextMenuなんかもあるようです。
    参考サイト:Handling context menus
    Custom context menu in QTreeView←こちらはC++でのQtですが、空気はつかめるかと

     self.treeview.customContextMenuRequested.connectでメニューを呼ぶときのコールバックコマンドを関連付けします。
     今回はbuildContextMenuと言う名前のメソッドにしています。91行目に追加されてます。

    buildContextMenuではqPoint(QtCore.QPoint)を引数として渡せるようにしておきましょう。
    QtGui.QMenuでとりあえずメニューのインスタンスを作成し、インスタンスのaddActionメソッドでメニューを追加していきます。


    99行目
    action = menu.exec_( self.treeview.mapToGlobal( qPoint ) )
    でメニューをqPointの位置(つまり右クリックしたときの位置)で表示し、メニューが選択されるまで待機します。(推定だけどね^^;)

     メニューが選択されるとactionに選択されたメニュー項目のインスタンスが渡されるので、100行目より以下
            for act in actionlist:
                if act == action:
                    print( '  - Menu Label is "%s"' % act.text() )
    
    で、メニューの項目によって振り分けます。



     う~む、複雑だべさ。こら理解するまでに時間がかかりそうです。


    因みにQtはメニューや各リストの項目にアイコンつけたりとかも出来ちゃいます♪ 素晴らしい!
    アイコンを追加する方法は97行目のmenu.addActionメソッドの部分で
    menu.addAction( QtGui.QIcon( 'アイコンパス.png' ), 'ラベル' )
    
    でOK
    スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

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

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

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