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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

317閲覧

wxとwx.stcを組み合わせて使いたい。

takoyaki280

総合スコア4

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/04/17 18:49

実現したいこと

wxで作ったフレームの中にwx.stcで作ったエディタをくみこみたいです。

前提

Python3のwxPythonを使って次のようにフレームを作りました。

python3

1import wx 2 3class MyFrame(wx.Frame): 4 def __init__(self, parent, title): 5 super().__init__(parent, title=title, size=(500, 400)) 6 7 # タブを作成する 8 self.notebook = wx.Notebook(self) 9 self.content_tab = wx.Panel(self.notebook) 10 self.character_tab = wx.Panel(self.notebook) 11 self.notebook.AddPage(self.content_tab, "Text") 12 self.notebook.AddPage(self.character_tab, "Item") 13 14 # Contentタブのレイアウトを作成する 15 content_sizer = wx.BoxSizer(wx.VERTICAL) # orientationをwx.VERTICALに設定 16 button_sizer = wx.BoxSizer(wx.HORIZONTAL) # ボタンを横に並べるSizerを作成 17 self.save_button = wx.Button(self.content_tab, label="Save") 18 self.load_button = wx.Button(self.content_tab, label="Load") 19 button_sizer.Add(self.save_button, 0, wx.ALL, 5) 20 button_sizer.Add(self.load_button, 0, wx.ALL, 5) 21 content_sizer.Add(button_sizer, 0, wx.EXPAND|wx.ALL, 5) # ボタンを追加 22 self.text_ctrl = wx.TextCtrl(self.content_tab, style=wx.TE_MULTILINE) 23 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.OnContentKeyDown) # KeyEventHandlerをバインド 24 content_sizer.Add(self.text_ctrl, 1, wx.EXPAND|wx.ALL, 5) 25 self.content_tab.SetSizer(content_sizer) 26 27 # Characterタブのレイアウトを作成する 28 character_sizer = wx.BoxSizer(wx.HORIZONTAL) 29 self.add_button = wx.Button(self.character_tab, label="Add") 30 self.edit_button = wx.Button(self.character_tab, label="Edit") 31 self.delete_button = wx.Button(self.character_tab, label="Delete") 32 character_sizer.Add(self.add_button, 0, wx.ALL, 5) 33 character_sizer.Add(self.edit_button, 0, wx.ALL, 5) 34 character_sizer.Add(self.delete_button, 0, wx.ALL, 5) 35 self.character_tab.SetSizer(character_sizer) 36 37 # ウィンドウの✕ボタンがクリックされたときにプログラムが終了するようにする 38 self.Bind(wx.EVT_CLOSE, self.OnClose) 39 40 # フレームを表示する 41 self.Raise() # フレームを前面に表示する 42 self.Show(True) 43 44 def OnClose(self, event): 45 # プログラムを終了させる 46 self.Destroy() 47 wx.GetApp().ExitMainLoop() 48 49 def OnContentKeyDown(self, event): 50 # キーが押されたときに呼ばれる関数 51 keycode = event.GetKeyCode() 52 if keycode == wx.WXK_TAB: 53 # Tabキーが押されたら、現在のカーソル位置にタブ文字を挿入する 54 pos = self.text_ctrl.GetInsertionPoint() 55 self.text_ctrl.WriteText('\t') 56 self.text_ctrl.SetInsertionPoint(pos+1) 57 elif keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER: 58 # Enterキーが押されたら、今の行のインデントを取得し、次の行にも適用する 59 pos = self.text_ctrl.GetInsertionPoint() 60 line_start = self.text_ctrl.GetInsertionPoint() 61 while line_start > 0: 62 line_start -= 1 63 if self.text_ctrl.GetRange(line_start, line_start+1) == '\n': 64 # 今の行の行頭位置を取得 65 line_start += 1 66 break 67 if line_start > 0: 68 # 今の行のインデントを取得 69 indent = '' 70 while line_start < pos: 71 c = self.text_ctrl.GetRange(line_start, line_start+1) 72 if c != ' ' and c != '\t': 73 break 74 indent += c 75 line_start += 1 76 # インデントを挿入 77 self.text_ctrl.WriteText('\n' + indent) 78 self.text_ctrl.SetInsertionPoint(pos + len(indent) +2) 79 else: 80 self.text_ctrl.WriteText('\n') 81 else: 82 event.Skip() # その他のキーイベントはスキップする 83 84if __name__ == '__main__': 85 app = wx.GetApp() 86 if not app: 87 app = wx.App() 88 frame = MyFrame(None, "Sample") 89 app.MainLoop()

イメージ説明
概ね狙い通りのものができたのですが、エディタ部分をもう少しリッチにしたいと思い、wc.stcで実装しようとしましたが上手くいきません。

発生している問題・エラーメッセージ

wxでの設定が反映されません。
イメージ説明

該当のソースコード

python3

1import wx 2from wx import stc 3 4class MyFrame(wx.Frame): 5 def __init__(self, parent, title): 6 super().__init__(parent, title=title, size=(500, 400)) 7 8 # タブを作成する 9 self.notebook = wx.Notebook(self) 10 self.content_tab = wx.Panel(self.notebook) 11 self.character_tab = wx.Panel(self.notebook) 12 self.notebook.AddPage(self.content_tab, "Text") 13 self.notebook.AddPage(self.character_tab, "Item") 14 15 # Contentタブのレイアウトを作成する 16 content_sizer = wx.BoxSizer(wx.VERTICAL) # orientationをwx.VERTICALに設定 17 button_sizer = wx.BoxSizer(wx.HORIZONTAL) # ボタンを横に並べるSizerを作成 18 self.save_button = wx.Button(self.content_tab, label="Save") 19 self.load_button = wx.Button(self.content_tab, label="Load") 20 button_sizer.Add(self.save_button, 0, wx.ALL, 5) 21 button_sizer.Add(self.load_button, 0, wx.ALL, 5) 22 content_sizer.Add(button_sizer, 0, wx.EXPAND|wx.ALL, 5) # ボタンを追加 23 self.text_ctrl = wx.TextCtrl(self.content_tab, style=wx.TE_MULTILINE) 24 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.OnContentKeyDown) # KeyEventHandlerをバインド 25 content_sizer.Add(self.text_ctrl, 1, wx.EXPAND|wx.ALL, 5) 26 self.content_tab.SetSizer(content_sizer) 27 28 # Characterタブのレイアウトを作成する 29 character_sizer = wx.BoxSizer(wx.HORIZONTAL) 30 self.add_button = wx.Button(self.character_tab, label="Add") 31 self.edit_button = wx.Button(self.character_tab, label="Edit") 32 self.delete_button = wx.Button(self.character_tab, label="Delete") 33 character_sizer.Add(self.add_button, 0, wx.ALL, 5) 34 character_sizer.Add(self.edit_button, 0, wx.ALL, 5) 35 character_sizer.Add(self.delete_button, 0, wx.ALL, 5) 36 self.character_tab.SetSizer(character_sizer) 37 38 # ウィンドウの✕ボタンがクリックされたときにプログラムが終了するようにする 39 self.Bind(wx.EVT_CLOSE, self.OnClose) 40 41 def OnClose(self, event): 42 # プログラムを終了させる 43 self.Destroy() 44 wx.GetApp().ExitMainLoop() 45 46 def OnContentKeyDown(self, event): 47 # キーが押されたときに呼ばれる関数 48 keycode = event.GetKeyCode() 49 if keycode == wx.WXK_TAB: 50 # Tabキーが押されたら、現在のカーソル位置にタブ文字を挿入する 51 pos = self.text_ctrl.GetInsertionPoint() 52 self.text_ctrl.WriteText('\t') 53 self.text_ctrl.SetInsertionPoint(pos+1) 54 elif keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER: 55 # Enterキーが押されたら、今の行のインデントを取得し、次の行にも適用する 56 pos = self.text_ctrl.GetInsertionPoint() 57 line_start = self.text_ctrl.GetInsertionPoint() 58 while line_start > 0: 59 line_start -= 1 60 if self.text_ctrl.GetRange(line_start, line_start+1) == '\n': 61 # 今の行の行頭位置を取得 62 line_start += 1 63 break 64 if line_start > 0: 65 # 今の行のインデントを取得 66 indent = '' 67 while line_start < pos: 68 c = self.text_ctrl.GetRange(line_start, line_start+1) 69 if c != ' ' and c != '\t': 70 break 71 indent += c 72 line_start += 1 73 # インデントを挿入 74 self.text_ctrl.WriteText('\n' + indent) 75 self.text_ctrl.SetInsertionPoint(pos + len(indent) +2) 76 else: 77 self.text_ctrl.WriteText('\n') 78 else: 79 event.Skip() # その他のキーイベントはスキップする 80 81class Panel(stc.StyledTextCtrl): 82 def __init__(self, *args, **kwargs): 83 super().__init__(*args, **kwargs) 84 85 self.SetLexer(stc.STC_LEX_PYTHON) 86 87 self.SetMarginType(1, stc.STC_MARGIN_NUMBER) 88 self.SetMarginWidth(1, 32) 89 self.SetMarginSensitive(1, False) 90 91 self.SetMarginType(2, stc.STC_MARGIN_SYMBOL) 92 self.SetMarginMask(2, stc.STC_MASK_FOLDERS) # フォルダー用マスク 93 self.SetMarginWidth(2, 16) 94 self.SetMarginSensitive(2, True) 95 96 self.SetFoldFlags(0x10) # 展開しない場合は下に描く 97 98 self.SetProperty('fold', '1') # フォールドプロパティを有効にする 99 100 v = ('white', 'black') 101 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, *v) 102 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, *v) 103 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, *v) 104 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, *v) 105 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_TCORNER, *v) 106 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_TCORNER, *v) 107 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_VLINE, *v) 108 109 self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick) 110 111 def OnMarginClick(self, evt): #<wx._stc.StyledTextEvent> 112 lc = self.LineFromPosition(evt.Position) 113 level = self.GetFoldLevel(lc) ^ stc.STC_FOLDLEVELBASE 114 ## 注:レベルはインデントヘッダーフラグまたはインデントレベル番号を示す。 115 if level and evt.Margin == 2: 116 self.ToggleFold(lc) 117 118if __name__ == '__main__': 119 app = wx.App() 120 frame = MyFrame(None,"Sample") 121 editor = Panel(frame) 122 frame.Raise() 123 frame.Show() 124 app.MainLoop()

試したこと

MyFrameとPanelの合体も試みましたが駄目でした。

Python3

1文字数制限のため省略

イメージ説明

補足情報(FW/ツールのバージョンなど)

Windows11
Python3.10.11
wxPython4.2.0

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

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

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

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

guest

回答1

1

ベストアンサー

配置場所が間違ってます。

テキストエディタを置き換えたい場合は、wx.TextCtrl を置き換えます。

diff

1# __init__ 内 2- self.text_ctrl = wx.TextCtrl(self.content_tab, style=wx.TE_MULTILINE) 3+ self.text_ctrl = Panel(self.content_tab) 4 5# if __name__ == "__main__": 内 6- editor = Panel(frame)

投稿2023/04/18 03:16

teamikl

総合スコア8651

leaf1832👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.68%

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

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

質問する

同じタグがついた質問を見る

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。