前提
●開発環境
・Python 3.10.2
┗(ライブラリ)matplotlib Version: 3.3.4
┗(ライブラリ)tkinter Version: 8.6.6
・OS:Windows10 64bit
tkinterで作成した同一画面上に
・自動スクロールするテキストボックス(TkinterのTextウィジェットを継承して作成した独自のウィジェット)を10個
・matplotlibで作成したグラフを10枚
を表示するアプリを作成しています。
実現したいこと
tkinterとmatplotlibを用いて
・各テキストボックスにそれぞれ異なる1文字以上の文字列を表示する
・テキストボックスは常に一定速度で自動スクロールする
・各グラフは一定時間毎に同じタイミングで画面更新する
という動作をかくつくことなく実現させたいです。
可能でしょうか?
可能であれば該当のソースコードをどのように修正すればよいか教えてください。
発生している問題・エラーメッセージ
グラフが更新するタイミングでテキストボックスのスクロール動作がかくつきます
該当のソースコード
python
1import tkinter as tk 2from tkinter import Text 3import matplotlib.pyplot as plt 4from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 5 6class Sample(tk.Tk): 7 def __init__(self, aGraphNum, aTextBarNum): 8 """_summary_ 9 10 Args: 11 aGraphNum (int): 表示するグラフの数(1以上) 12 aTextBarNum (int): 表示するスクロールバーの数(1以上) 13 """ 14 super().__init__() 15 16 # グラフ 17 self.__mGraph = Graph(self,aGraphNum) 18 19 # テキストバー 20 self.__mTxtB = TextBar(self,aTextBarNum) 21 22 # Threadによる画面更新 23 self.__mGraphUpdIntvl = 5000 24 self.__mGraphUpdCnt = 0 25 26 # tk.Tk.after()による画面更新 27 self.__mTextUpdIntvl = 50 28 29 self.after(self.__mTextUpdIntvl,self.__AfterFnc) 30 31 def __AfterFnc(self): 32 """_summary_ 33 after()による画面更新 34 """ 35 self.__mTxtB.updScreen() 36 self.__mGraphUpdCnt = self.__mGraphUpdCnt + self.__mTextUpdIntvl 37 if self.__mGraphUpdCnt % self.__mGraphUpdIntvl == 0: 38 self.__mGraphUpdCnt = 0 39 self.__mGraph.updScreen() 40 self.after(self.__mTextUpdIntvl,self.__AfterFnc) 41 42class Graph(tk.Frame): 43 """_summary_ 44 グラフ領域管理 45 """ 46 def __init__(self, aMaster, aGraphNum): 47 super().__init__(master=aMaster) 48 49 self.__mFig = plt.figure() 50 self.__mAxes = [] 51 for tNum in range(aGraphNum): 52 # グラフ生成 53 self.__mAxes.append(self.__mFig.add_subplot(1,aGraphNum,tNum+1)) 54 # グラフをtkinterに表示 55 self.__mCanvas = FigureCanvasTkAgg(self.__mFig, self) 56 self.__mCanvas.get_tk_widget().pack(fill=tk.BOTH, expand=True) 57 self.pack() 58 59 def updScreen(self): 60 """_summary_ 61 グラフを更新する 62 """ 63 self.__mCanvas.draw_idle() 64 65class TextBar(tk.Frame): 66 """_summary_ 67 スクロール表示領域管理 68 """ 69 def __init__(self, aMaster, aTextBarNum): 70 super().__init__(master=aMaster) 71 72 # 表示領域作成 73 self.__mCanvas = tk.Canvas(self.master) 74 self.__mText = [] 75 for tNum in range(aTextBarNum): 76 # スクロールバー生成 77 self.__mText.append(Custom_Text(0,(tNum)*20,self.__mCanvas)) 78 self.__mText[tNum].insert("1.0","abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz") 79 80 self.__mCanvas.pack() 81 82 def updScreen(self): 83 """_summary_ 84 スクロールする 85 """ 86 for tTxt in self.__mText: 87 tViewSE = tTxt.xview() 88 tIntv = 0.005 89 tPos:float = tViewSE[0] + tIntv 90 if tViewSE[1] >= 1: 91 # 最後尾なら先頭に戻る 92 tPos = 0.0 93 elif tViewSE[1] + tIntv >= 1.0: 94 # 1以上なら最後尾に移動する 95 tPos = 1.0 96 tTxt.xview_moveto(tPos) 97 98class Custom_Text(Text): 99 """_summary_ 100 テキストボックス 101 """ 102 def __init__(self, aX, aY, aMaster=None): 103 Text.__init__(self, aMaster,width=10,height=1,wrap=tk.NONE) 104 self.place(x=aX, y=aY) 105 106if __name__ == "__main__": 107 tSmpl = Sample(10,10) 108 tSmpl.mainloop()
試したこと
・グラフ(Graph)またはテキストボックス(TextBar)をSampleクラス内に配置したThreadとtk.Tk.after()により更新していたが、tk.Tk.after()でのみ更新するよう変更しました。
⇒グラフ更新のタイミングでカクつき、変更前から変化なし

回答1件
あなたの回答
tips
プレビュー