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 日分です。