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 ) ... アンカーは移動せずにカーソルだけ移動する。
◎ QWebViewの表示位置を変えたいのだけど。 :
QTextEdit で修正している箇所に合わせて、QWebView のページ表示位置も変更したい・ページをスクロールしたいのだけど。どうすればいいのやら…。
最低限、QTextEdit で文末を編集中に、QwebView の一番下を表示するようにしたい。カーソルが文末(文書の末尾)にあるかどうかは、QTextCursor.atEnd() で調べることができるので、QTextEdit 内が変更されるたびにカーソルが文末にあるか調べて、あるなら、QwebViewの表示を一番下にすればいい…はずなのだけど。QWebView の表示状態を変更する方法が分からない。
QWebView.triggerPageAction() を使えばできるかなと思ったけれど、そういうわけでもないようで。さて、どうすれば…。
とりあえず分かった部分をメモ。
スクロールバー関連を操作するには、QWebView.page().mainFrame() からアクセスするらしい。
表示しているページの縦横サイズ(ウインドウからはみ出ている部分も含む?)を取得するなら、QWebView.page().mainFrame().contentsSize() を使う。ただし、そのまま呼ぶと (0,0) が返ってきてしまう時がほとんどで。値をちゃんと取得したいなら、mainFrame() が contentsSizeChanged() のシグナル?を出してきたときに処理をする。
QWebFrame.geometry() というのもあるらしいのだけど…。
最低限、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 日分です。