mieki256's diary



2012/09/29() [n年前の日記]

#1 [python] まだQTextCursorを勉強中

PyQt勉強中。

選択範囲を複製したい。 :

QTextCursor を使って選択範囲を複製しようとして悩んだり。文字列を挿入すると、複製前と複製後の文字列の両方が選択状態になってしまう。挿入後に選択範囲を作り直さないといかんような気がするけど、どうすれば…。

こんな感じになった。
    def duplicate_line(self):
        """行を複製"""
        self.textEdit = self.ui.editor_window
        c = self.textEdit.textCursor()
        if c.hasSelection():
            # 選択範囲有り
            c.beginEditBlock()          # Undo履歴の制御
            s = c.selectedText()        # 選択範囲の文字列を取得

            sel_s = c.selectionStart()  # 選択範囲の開始位置を取得
            sel_e = c.selectionEnd()    # 選択範囲の終了位置を取得

            c.clearSelection()          # 選択範囲を解除
            c.setPosition(sel_e)        # 元選択範囲の終了位置にカーソル移動
            c.insertText(s)             # 文字列挿入

            # 選択状態を復元する。
            # アンカー変更を伴うカーソル移動後に、
            # アンカー変更をしないカーソル移動をして、選択状態にする。
            sel_s = sel_e
            sel_e = c.position()
            c.setPosition(sel_s, QtGui.QTextCursor.MoveAnchor)
            c.setPosition(sel_e, QtGui.QTextCursor.KeepAnchor)

            c.endEditBlock()                # Undo履歴の制御
            self.textEdit.setTextCursor(c)  # QTextEdit上でカーソル位置反映

        else:
            # 選択範囲無し
            qb = c.block()              # QTextBlock を取得
            qs = qb.text()              # QTextBlock内の文字列を取得
            c.beginEditBlock()
            if not c.atBlockStart():
                # Block頭(行頭)にカーソルが無い。
                # (内部的に)カーソルを行頭に移動
                c.movePosition(QtGui.QTextCursor.StartOfBlock)
            c.insertText(qs + "\n")     # Block文字列を挿入
            c.endEditBlock()

            # QTextEdit上ではカーソル位置を反映させてないので、
            # カーソル位置は以前のまま

  • 選択範囲の開始位置を知りたい。 → QTextCursor.selectionStart()
  • 選択範囲の終了位置を知りたい。 → QtextCursor.selectionEnd()
  • カーソル位置を変更したい。 → QTextBlock.setPosition()
選択範囲を作りたいときは、アンカーというものが関係してくるらしい。アンカーがある場所から、現在のカーソル位置までが、選択範囲になるようで。ただ、QtextCursor.setPosition() を使ってカーソル移動した際、デフォルトではカーソル移動と同時にアンカーも移動するモードになっているので、選択範囲は作られない。選択範囲を作りたいなら、アンカーを動かさずにカーソル位置だけ変えないといけない。その場合、QTextCursor.setPosition() に、QtGui.QTextCursor.KeepAnchor を指定する。
  • QtextCursor.setPosition( 位置情報 ) ... カーソルとアンカーを移動する。
  • QtextCursor.setPosition( 位置情報, QtGui.QTextCursor.KeepAnchor ) ... アンカーは移動せずにカーソルだけ移動する。

QWebViewの表示位置を変えたいのだけど。 :

QTextEdit で修正している箇所に合わせて、QWebView のページ表示位置も変更したい・ページをスクロールしたいのだけど。どうすればいいのやら…。

最低限、QTextEdit で文末を編集中に、QwebView の一番下を表示するようにしたい。カーソルが文末(文書の末尾)にあるかどうかは、QTextCursor.atEnd() で調べることができるので、QTextEdit 内が変更されるたびにカーソルが文末にあるか調べて、あるなら、QwebViewの表示を一番下にすればいい…はずなのだけど。QWebView の表示状態を変更する方法が分からない。

QWebView.triggerPageAction() を使えばできるかなと思ったけれど、そういうわけでもないようで。さて、どうすれば…。

とりあえず分かった部分をメモ。

スクロールバー関連を操作するには、QWebView.page().mainFrame() からアクセスするらしい。

表示しているページの縦横サイズ(ウインドウからはみ出ている部分も含む?)を取得するなら、QWebView.page().mainFrame().contentsSize() を使う。ただし、そのまま呼ぶと (0,0) が返ってきてしまう時がほとんどで。値をちゃんと取得したいなら、mainFrame() が contentsSizeChanged() のシグナル?を出してきたときに処理をする。
        # QWebView内サイズが変更された際に呼ばれる処理を指定
        self.mainframe = self.ui.my_webview.page().mainFrame()
        self.mainframe.contentsSizeChanged.connect(self.chg_contents_size)

        ....

    def chg_contents_size(self):
        """QWebView内のサイズが変更された際に呼ばれる処理"""
        c_size = self.ui.my_webview.page().mainFrame().contentsSize()
        self.mainframe_w = c_size.width()
        self.mainframe_h = c_size.height()
        print "frame w,h=%d,%d" % (self.mainframe_w, self.mainframe_h)

QWebFrame.geometry() というのもあるらしいのだけど…。

以上、1 日分です。

過去ログ表示

Prev - 2012/09 - Next
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project