実現したいこと
折りたたまれた行を移動する。
前提
wxPythonでテキストエディタを作っています。マージンのクリックによる階層構造の折りたたみを実装しており、折りたたまれた行をコピー&ペーストやドラッグ&ドロップで移動したいと考えています。
発生している問題・エラーメッセージ
折りたたまれた行を移動すると折りたたまれていた内容が消えます。また行番後の表示も復元されなくなります。
aaaaaaaaaaを6行目にドラッグ&ドロップ。
該当のソースコード
import wx from wx import stc class MyFrame(wx.Frame): def __init__(self, parent, title): super().__init__(parent, title=title, size=(500, 400)) # タブを作成する self.notebook = wx.Notebook(self) self.content_tab = wx.Panel(self.notebook) self.character_tab = wx.Panel(self.notebook) self.notebook.AddPage(self.content_tab, "Text") self.notebook.AddPage(self.character_tab, "Item") # Contentタブのレイアウトを作成する content_sizer = wx.BoxSizer(wx.VERTICAL) # orientationをwx.VERTICALに設定 button_sizer = wx.BoxSizer(wx.HORIZONTAL) # ボタンを横に並べるSizerを作成 self.save_button = wx.Button(self.content_tab, label="Save") self.load_button = wx.Button(self.content_tab, label="Load") button_sizer.Add(self.save_button, 0, wx.ALL, 5) button_sizer.Add(self.load_button, 0, wx.ALL, 5) content_sizer.Add(button_sizer, 0, wx.EXPAND|wx.ALL, 5) # ボタンを追加 self.text_ctrl = stc.StyledTextCtrl(self.content_tab, style=wx.TE_MULTILINE) self.text_ctrl.SetLexer(stc.STC_LEX_PYTHON) self.text_ctrl.SetMarginType(1, stc.STC_MARGIN_NUMBER) self.text_ctrl.SetMarginWidth(1, 32) self.text_ctrl.SetMarginSensitive(1, False) self.text_ctrl.SetMarginType(2, stc.STC_MARGIN_SYMBOL) self.text_ctrl.SetMarginMask(2, stc.STC_MASK_FOLDERS) # フォルダー用マスク self.text_ctrl.SetMarginWidth(2, 16) self.text_ctrl.SetMarginSensitive(2, True) self.text_ctrl.SetFoldFlags(0x10) # 展開しない場合は下に描く self.text_ctrl.SetProperty('fold', '1') # フォールドプロパティを有効にする v = ('white', 'black') self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, *v) self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, *v) self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, *v) self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, *v) self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_TCORNER, *v) self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_TCORNER, *v) self.text_ctrl.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_VLINE, *v) self.text_ctrl.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick) self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.OnContentKeyDown) # KeyEventHandlerをバインド content_sizer.Add(self.text_ctrl, 1, wx.EXPAND|wx.ALL, 5) self.content_tab.SetSizer(content_sizer) # Characterタブのレイアウトを作成する character_sizer = wx.BoxSizer(wx.HORIZONTAL) self.add_button = wx.Button(self.character_tab, label="Add") self.edit_button = wx.Button(self.character_tab, label="Edit") self.delete_button = wx.Button(self.character_tab, label="Delete") character_sizer.Add(self.add_button, 0, wx.ALL, 5) character_sizer.Add(self.edit_button, 0, wx.ALL, 5) character_sizer.Add(self.delete_button, 0, wx.ALL, 5) self.character_tab.SetSizer(character_sizer) # ウィンドウの✕ボタンがクリックされたときにプログラムが終了するようにする self.Bind(wx.EVT_CLOSE, self.OnClose) # フレームを表示する self.Raise() # フレームを前面に表示する self.Show(True) def OnClose(self, event): # プログラムを終了させる self.Destroy() wx.GetApp().ExitMainLoop() def OnContentKeyDown(self, event): # キーが押されたときに呼ばれる関数 keycode = event.GetKeyCode() if keycode == wx.WXK_TAB: # Tabキーが押されたら、現在のカーソル位置にタブ文字を挿入する pos = self.text_ctrl.GetInsertionPoint() self.text_ctrl.WriteText('\t') self.text_ctrl.SetInsertionPoint(pos+1) elif keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER: # Enterキーが押されたら、今の行のインデントを取得し、次の行にも適用する pos = self.text_ctrl.GetInsertionPoint() line_start = self.text_ctrl.GetInsertionPoint() while line_start > 0: line_start -= 1 if self.text_ctrl.GetRange(line_start, line_start+1) == '\n': # 今の行の行頭位置を取得 line_start += 1 break if line_start > 0: # 今の行のインデントを取得 indent = '' while line_start < pos: c = self.text_ctrl.GetRange(line_start, line_start+1) if c != ' ' and c != '\t': break indent += c line_start += 1 # インデントを挿入 self.text_ctrl.WriteText('\n' + indent) self.text_ctrl.SetInsertionPoint(pos + len(indent) +2) else: self.text_ctrl.WriteText('\n') else: event.Skip() # その他のキーイベントはスキップする def OnMarginClick(self, evt): #<wx._stc.StyledTextEvent> lc = self.text_ctrl.LineFromPosition(evt.Position) level = self.text_ctrl.GetFoldLevel(lc) ^ stc.STC_FOLDLEVELBASE ## 注:レベルはインデントヘッダーフラグまたはインデントレベル番号を示す。 if level and evt.Margin == 2: self.text_ctrl.ToggleFold(lc) if __name__ == '__main__': app = wx.GetApp() if not app: app = wx.App() frame = MyFrame(None, "Sample") app.MainLoop()
試したこと
何をいじればいいのかさえ良く分かりません。
補足情報(FW/ツールのバージョンなど)
Windows10
Python3.10.11
wxPython4.2.0
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2023/04/18 06:11
2023/04/18 06:43