QTextCursorでQTextEditを制す!

    今回はPySideのお話。

    Qtには複数行の文字列を表示・編集する事ができるQTextEditがありますね。
    # -*- coding:utf-8 -*-
    import sys
    from PySide import QtGui, QtCore
    
    class SampleTextEdit(QtGui.QWidget):
        def __init__(self, parent=None):
            super(SampleTextEdit, self).__init__(parent)
            self.setWindowTitle('Sample Text Editor')
    
            self.editor = QtGui.QTextEdit()
            # 文字列をエディタにセットして表示する。
            self.editor.setPlainText('Hellow PySide!!')
    
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.editor)
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        editor = SampleTextEdit()
        editor.show()
    
        sys.exit(app.exec_())
    
    qtextCursor001.png
    QTextEditはリッチテキストも扱えるため、シンプルなテキストをセットする場合はsetPlainTextメソッドを使います。
    QLineEditではsetTextだけで良かったので、ちょっと複雑になってますね。


     さて、QTextEditでは自身のカーソル位置や選択状況などを操作するにはQTextCursorを使用します。
     基本的に自身のQTextCursorを呼びだすにはQTextEditのtextCursorメソッドを使用します。
     それではちょっと変更したコードを。
    # -*- coding:utf-8 -*-
    import sys
    from PySide import QtGui, QtCore
     
    class SampleTextEdit(QtGui.QWidget):
        def __init__(self, parent=None):
            super(SampleTextEdit, self).__init__(parent)
            self.setWindowTitle('Sample Text Editor')
     
            # 出力用のQTextEdit。--------------------------------------------------
            self.outputEditor = QtGui.QTextEdit()
            self.outputEditor.setReadOnly(True) #読み込み専用に変更。
            # ---------------------------------------------------------------------
    
            # 入力・編集用のQTextEdit。--------------------------------------------
            self.editor = QtGui.QTextEdit()
            # エディタの文字に変更があった場合はupdateTextメソッドを呼ぶ。
            self.editor.textChanged.connect(self.updateText)
            # エディタの選択に変更があった場合はupdateFromSelectionメソッドを呼ぶ。
            self.editor.selectionChanged.connect(self.updateFromSelection)
            # 文字列をエディタにセットして表示する。
            self.editor.setPlainText('Hellow PySide!!')
            # ---------------------------------------------------------------------
    
     
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.editor)
            layout.addWidget(self.outputEditor)
    
        def updateText(self):
            # self.editorのテキストをself.outputEditorへコピーする。
            text = self.editor.toPlainText()
            self.outputEditor.setPlainText(text)
    
        def updateFromSelection(self):
            cursor = self.editor.textCursor()     # QTextCursorのインスタンスの取得。
            if not cursor.hasSelection():
                # 選択テキストがない場合は、self.editorの全文を表示。
                self.updateText()
                return
            selected_text = cursor.selectedText() # 選択されたテキストを取得。
            self.outputEditor.setPlainText(selected_text)
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        editor = SampleTextEdit()
        editor.show()
     
        sys.exit(app.exec_())
    
     新たにもう一つQTextEditを追加しました。追加されたQTextEditは出力用にするために編集不可にしています。
    qtextCursor002.png
     上のエディタに文字を入力すると、下のエディタに同じ文字が表示されるようにしました。

    qtextCursor003.png
     また、選択されている場合は選択部分を表示するようにしています。


     updateTextメソッドを以下のように書き換えると、なんちゃって行数表示もできますね。(もっとちゃんと作る場合は、これだけでは不足してる感は否めませんが・・・)
        def updateText(self):
            # 出力用QLineEditの内容をクリアし、QTextCursorを取得する。
            self.outputEditor.clear()
            o_cursor = self.outputEditor.textCursor()
    
            cursor = self.editor.textCursor()
            # 仮想カーソルをドキュメントの先頭へ移動させる。
            cursor.movePosition(QtGui.QTextCursor.Start)
            number = 1
            while(True):
                if cursor.atEnd():
                    # カーソルがドキュメントの末端にある場合は終了。
                    break
                # 仮想カーソルを行の先頭から最後まで移動して選択する。
                cursor.movePosition(QtGui.QTextCursor.StartOfLine)
                cursor.movePosition(
                    QtGui.QTextCursor.EndOfLine, QtGui.QTextCursor.KeepAnchor
                )
                text = '%04d : %s\n' % (number, cursor.selectedText())
                # 次の文字へ移動する。
                cursor.movePosition(QtGui.QTextCursor.NextCharacter)
                
                o_cursor.insertText(text)
                number += 1
    

    ↓とりあえず4桁の行数表示。
    qtextCursor004.png


     QTextCursorは仮想カーソルを動かして、そこからテキストの取得や挿入を行うため覚えれば色々出来そうですね!
     他にもイメージやテーブルの挿入なども出来るので、ちょっと凝ったリッチドキュメントを作りたい場合には必須となります。



     最後に、QTextCursor.selectedText()で複数行のテキストを取ってくる場合、改行コードが通常の"\n"ではなく、"u'\u2029'"になっています。
     そのためselectedTextで取ってきた文字をPython組み込み関数のexec()などに渡すと文字コードの部分でエラーを起こしてしまいます。
     ですので、そう言った場合は
    # 改行コードの変換。
    text = cursor.selectedText().replace(u'\u2029', '\n')
    
     としてやると良いでしょう。(これを一番書いておきたかったと言うのは内緒だ)
    スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

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

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

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR