2016-07-11 1 views
2

私はTkinterを使ってPythonでGUIを作っていて、多くのウィジェットを画面に詰め込むときにいくつかのパフォーマンス上の問題がありました。多くのウィジェットをパックするときのTkinterのパフォーマンス

時間がかかる画面にウィジェットを描画(または配置)するプロセスのようです。グリッドマネージャとプレースメントマネージャの両方を使ってみました。

マルチプロセッシングを使用するとスピードアップすることができますか?私はこれが大幅にスピードアップできるどんな方法についても他の提案を歓迎するでしょう。コメントで示唆したように

import Tkinter as tk 

root = tk.Tk() 
frame = tk.Frame(root) 
for i in range(50): 
    for j in range(50): 
     widget = tk.Frame(frame, bd=2, relief='raised', height=10, width=10) 
     widget.grid(row=i, column=j) # using place is barely quicker 
tk.Button(root, text='pack', command=frame.pack).pack() 
root.mainloop() 
+0

Tkinterにはスレッドセーフではありませんので、マルチプロセッシングは、ほぼ確実に助けにはなりません、個人的に私はいくつかのケースではそのキャンバス上のウィジェットを置く[ 'canvas.create_window'](HTTPを見つけました。 edu/tcc/help/pubs/tkinter/web/create_window.html)は、再描画が速くなりましたが、サイズ変更/操作が難しくなりました。 –

+0

@ TadhgMcDonald-Jensen私は上記の例でこれを試しましたが、違いがあれば最小です。 – Siwel

+1

私は、インスタンス化が必要な2500個のオブジェクトをインスタンス化しています。固有の鍵を生成し、Tclインタプリタに伝達し、そこでインスタンス化し、前後に束縛して配置します。 GUIがある限り、2500個のオブジェクトは通常、ある解釈された言語から別のものへとラッパーを通過するのに少ししかありません。あなたの目標は何ですか?あなたがグリッドのような構造をしたいのであれば、2500フレームを使用せず、キャンバスを使っていくつかの四角形を描きます(より単純で単純なオブジェクト) – Delioth

答えて

0

は、最善の解決策は、キャンバスを使用し、その速度に絶対的な制限があるようですので、多くのウィジェットを、パックするのではなく、その上に描画することになってしまうんでした。

クリックしていない状態とクリックした状態の画像を作成するために、スクリーンショットを効果的に取り込んでビルトインボタンを使用しました。イメージファイルがim_up.pngim_down.pngという名前で格納されていると仮定すると、下のコードはキャンバスソリューションを示しています。 //infohost.nmt:

import Tkinter as tk 
# Uses Python Imaging Library. 
from PIL import Image as ImagePIL, ImageTk 

root = tk.Tk() 
canvas = tk.Canvas(root, height=500, width=500, highlightthickness=0) 
canvas.pack() 
images = dict() 
for name in ['up', 'down']: 
    im = ImagePIL.open('im_{}.png'.format(name)) 
    # Resize the image to 10 pixels square. 
    im = im.resize((10, 10), ImagePIL.ANTIALIAS) 
    images[name] = ImageTk.PhotoImage(im, name=name) 
def set_cell_image(coord, image): 
    # Get position of centre of cell. 
    x, y = ((p + 0.5) * 10 for p in coord) 
    canvas.create_image(x, y, image=image) 
for i in range(50): 
    for j in range(50): 
     set_cell_image((i, j), images['up']) 
def click(event): 
    coord = tuple(getattr(event, p)/10 for p in ['x', 'y']) 
    set_cell_image(coord, images['down']) 
canvas.bind('<Button-1>', click) 
root.mainloop() 
関連する問題