首先,我不得不說我不是Python的專家。我從例子中收集到的大部分代碼。從tkinter小部件中啓動線程
我做的研究公平一點,並一直沒能找到一個代碼配置就是喜歡什麼,我試圖做的:從自定義窗口小部件類中啓動一個線程。我知道tkinter有多個線程嘗試與單個窗口小部件進行通信的問題,但我沒有在這裏看到這種情況。
我想這樣做的原因是,每個插件可以啓動/停止和更新它自己。通過這種方式,我可以在同一根窗口內查看來自多個來源的數據,並且可以隨意添加/刪除每個來源。我知道我可以用不同的方式進行編碼(全部在一個班級中),但我想用這種方式嘗試。我認爲這會讓事情變得更清潔。在這個
我的思維過程如下:
- 創建一個可重複使用的自定義部件類。
- 能夠將多個小部件添加到根窗口(並且能夠將其刪除)
- 每個小部件都將獲取數據並獨立於其他部件更新數據。
- 使用線程,以便每個小部件都將在後臺執行所需的操作。這樣所有的小部件將同時更新。
我的代碼示例顯示了什麼,我試圖完成的基本知識。在完成的程序中,每個小部件將有一個文本框定義在哪裏獲取數據。
此測試代碼在WindowsXP中使用Python3可以正常工作。每個小部件都可以添加和刪除,並將獨立於其他部件進行更新。
當我在Fedora20中使用Python3運行相同的代碼時,按下開始按鈕時會崩潰。唯一的例外是:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.3/threading.py", line 637, in _bootstrap_inner
self.run()
File "/usr/lib/python3.3/threading.py", line 594, in run
self._target(*self._args, **self._kwargs)
File "dummy.py", line 44, in updlabel
self.label.config(text=number)
File "/usr/lib/python3.3/tkinter/__init__.py", line 1263, in configure
return self._configure('configure', cnf, kw)
File "/usr/lib/python3.3/tkinter/__init__.py", line 1254, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: None
所以,最後,我有2個問題:
- 爲什麼不是在Linux下工作,而它在WindowsXP呢?
- 我的方法是否有效?如果是,我的代碼在哪裏?
代碼示例:
from threading import Thread
import tkinter as tk
import numpy as np
import time
class Widget(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.running = False
self.abort = True
labelfont = ('times', 20, 'bold')
self.label = tk.Label(self, text="---", font=labelfont)
self.startb = tk.Button(self, text="START", command=lambda: self.sbpressed())
self.remove = tk.Button(self, text="-", command=lambda: self.rbpressed())
self.startb.grid(row=0, column=0)
self.label.grid(row=0, column=1)
self.remove.grid(row=0, column=2)
def rbpressed(self):
self.abort = True
while self.running:
self.update()
self.destroy()
def sbpressed(self):
if self.running:
self.abort = True
self.update()
else:
self.startb["text"] = "ABORT"
self.running = True
self.abort = False
self.update()
self.t = Thread(target=self.updlabel, args=())
self.t.start()
def updlabel(self):
while self.abort == False:
number = str(np.random.random_integers(100))
self.label.config(text=number)
time.sleep(1)
self.startb["text"] = "START"
self.running = False
self.abort = False
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.addb = tk.Button(self, text="+", command=lambda: self.addwidget())
self.addb.pack()
Widget(self).pack()
def addwidget(self):
Widget(self).pack()
root = tk.Tk()
app = Application(master=root)
app.mainloop()
對Arch Linux,Python 3.4.2適合我工作 – matsjoyce 2015-01-15 18:02:31
你是什麼意思「我可以查看來自多個來源的數據」?這些來源是什麼?你的例子顯示了隨機的調用,你絕對不需要線程。你在輪詢其他設備或端口嗎? – 2015-01-15 18:41:42
其他來源我的意思是來自互聯網的數據。示例代碼最簡單,只是爲了說明我在Fedora20中遇到的異常。 – Zalpho 2015-01-15 19:02:59