質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

5524閲覧

【wxpython】二つのテキスト画面のスクロールを同期させたい

tei

総合スコア12

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/03/09 12:57

編集2017/03/09 16:23

GUIで二つのテキスト画面を表示して、スクロールを同期させれず苦戦しています。
wxpythonのTextCtrl(style=wx.TE_MULTILIN)を二つ用意して、
スクロールイベントを利用して、スクロールの挙動を同期させようとしていますが
こちらは可能なのでしょうか。

grid.Scrollを利用するとスクロールのpositionを移動でき、
実現できそうだったのですが、TextCtrlに適用することができませんでした。

※追記
コメントを受けてShowPositionを利用して作ってみましたが、
スクロールが同期できませんでした。
スクロールイベントにGetPositionをつけて座標を確認しましたが
スクロールしても(0,0)のままでした。
こちらが原因で同期できないのでしょうか。

python

1import wx 2 3class MyForm(wx.Frame): 4 # ---------------------------------------------------------------------- 5 def __init__(self): 6 wx.Frame.__init__(self, None, wx.ID_ANY,"RT_diff") 7 8 splitter = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_LIVE_UPDATE) 9 splitter.SetMinimumPaneSize(100) 10 self.panel1 = wx.Panel(splitter, wx.ID_ANY, style=wx.BORDER_SUNKEN) 11 self.panel2 = wx.Panel(splitter, wx.ID_ANY, style=wx.BORDER_SUNKEN) 12 self.text_1 = wx.TextCtrl(self.panel1, wx.ID_ANY, style=wx.TE_MULTILINE|wx.VSCROLL) 13 self.text_2 = wx.TextCtrl(self.panel2, wx.ID_ANY, style=wx.TE_MULTILINE|wx.VSCROLL) 14 self.text_1.Bind(wx.EVT_SCROLLWIN, self.onScrollWin1) 15 self.text_2.Bind(wx.EVT_SCROLLWIN, self.onScrollWin2) 16 17 f = open("ip-test01.txt","r") 18 line = f.readlines() 19 a = "" 20 for line_list in line : 21 a = a + line_list 22 self.text_1.SetValue(a) 23 self.text_2.SetValue(a) 24 25 lbox_layout = wx.BoxSizer(wx.VERTICAL) 26 lbox1 = wx.BoxSizer(wx.HORIZONTAL) 27 lbox1.Add(self.text_1, -1,wx.EXPAND) 28 lbox_layout.Add(lbox1,-1,wx.EXPAND) 29 30 rbox_layout = wx.BoxSizer(wx.VERTICAL) 31 rbox1 = wx.BoxSizer(wx.HORIZONTAL) 32 rbox1.Add(self.text_2, -1,wx.EXPAND) 33 rbox_layout.Add(rbox1,-1,wx.EXPAND) 34 35 36 self.panel1.SetSizer(lbox_layout) 37 self.panel2.SetSizer(rbox_layout) 38 39 splitter.SplitVertically(self.panel1,self.panel2) 40 41 def onScrollWin1(self, event): 42 self.text_2.ShowPosition(event.Position) 43 print(self.text_1.GetPosition()) 44 def onScrollWin2(self, event): 45 self.text_1.ShowPosition(event.Position) 46 print(self.text_2.GetPosition()) 47 event.Skip() 48# ---------------------------------------------------------------------- 49# Run the program 50if __name__ == "__main__": 51 app = wx.App(False) 52 frame = MyForm() 53 frame.Show() 54 app.MainLoop()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2017/03/09 13:17

試行されたコードを提示すると回答得られやすいかと思います。
guest

回答1

0

ベストアンサー

TextCtrlShowPosition(self, pos)で目的の動作ができないでしょうか?

2017/03/10 検証コード書いてみました。

ポイントはevent.Positionは行位置だがShowPositionは先頭からの文字列位置で指定しなければいけないというところです。
ただし、スクロールバーをマウスでつまんで動かすとうまく動作しますが、マウスホイールやテキストコントロール内での上下キーでの位置更新にはスクロールイベント発生しないようで、同期しません。
おそらくもっと正しい方法があると思います。残念。

Python

1 2import sys 3import wx 4 5class MyForm(wx.Frame): 6 # ---------------------------------------------------------------------- 7 def __init__(self): 8 wx.Frame.__init__(self, None, wx.ID_ANY,"RT_diff") 9 10 splitter = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_LIVE_UPDATE) 11 splitter.SetMinimumPaneSize(100) 12 self.panel1 = wx.Panel(splitter, wx.ID_ANY, style=wx.BORDER_SUNKEN) 13 self.panel2 = wx.Panel(splitter, wx.ID_ANY, style=wx.BORDER_SUNKEN) 14 self.text_1 = wx.TextCtrl(self.panel1, wx.ID_ANY, style=wx.TE_MULTILINE|wx.VSCROLL) 15 self.text_2 = wx.TextCtrl(self.panel2, wx.ID_ANY, style=wx.TE_MULTILINE|wx.VSCROLL) 16 self.text_1.Bind(wx.EVT_SCROLLWIN, self.onScrollWin1) 17 self.text_2.Bind(wx.EVT_SCROLLWIN, self.onScrollWin2) 18 19 # ダミーデータ 20 a = "" 21 for i in range(100): 22 a = a + ("%03d_abcde\n" %(i)) 23 self.text_1.SetValue(a) 24 self.text_2.SetValue(a) 25 26 lbox_layout = wx.BoxSizer(wx.VERTICAL) 27 lbox1 = wx.BoxSizer(wx.HORIZONTAL) 28 lbox1.Add(self.text_1, -1,wx.EXPAND) 29 lbox_layout.Add(lbox1,-1,wx.EXPAND) 30 31 rbox_layout = wx.BoxSizer(wx.VERTICAL) 32 rbox1 = wx.BoxSizer(wx.HORIZONTAL) 33 rbox1.Add(self.text_2, -1,wx.EXPAND) 34 rbox_layout.Add(rbox1,-1,wx.EXPAND) 35 36 37 self.panel1.SetSizer(lbox_layout) 38 self.panel2.SetSizer(rbox_layout) 39 40 splitter.SplitVertically(self.panel1,self.panel2) 41 42 # src,dst : 同期元、先のTextCtrl 43 # srcYPos : 行位置 44 def syncScroll(self, src, dst, srcYPos): 45 dstTxtPos = dst.XYToPosition( 0, srcYPos) # 行列位置→文字列長位置に 46 dst.ShowPosition( dstTxtPos) # 文字列長基準の位置を指定しなければいけないようだ 47 print( "srcYPos[%d] -> dstTxtPos(%d)" % (srcYPos,dstTxtPos)) 48 49 def onScrollWin1(self, event): 50 print("on1:" + repr(event.Position)) # event.Positionは行位置のようだ 51 self.syncScroll( self.text_1, self.text_2, event.Position) 52 event.Skip() 53 54 def onScrollWin2(self, event): 55 print("on2:" + repr(event.Position)) 56 self.syncScroll( self.text_2, self.text_1, event.Position) 57 event.Skip() 58 59# ---------------------------------------------------------------------- 60# Run the program 61if __name__ == "__main__": 62 app = wx.App(False) 63 frame = MyForm() 64 frame.Show() 65 app.MainLoop()

投稿2017/03/09 13:17

編集2017/03/10 10:34
can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tei

2017/03/16 12:12

返信遅れてすみません。 検証コードまで書いていただきありがとうございます。 スクロールの同期については別のGUIモジュールも検討してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問