我一直在用Python / Tkinter程序绘制一些图形。该程序有一个主菜单,菜单项用于绘制不同的数字。它工作得很好,但我遇到了一个问题。如果程序是绘制一个图形的一部分并且用户单击以绘制第二个图形,则程序绘制第二个图形,但是当它完成绘制第二个图形时,它返回并完成绘制第一个图形。我想要它做的是停止绘制第一个数字,即使第二个数字完成绘制,也不回去绘制第一个数字。我创建了一个更简单的示例程序来演示该场景。要在此程序中查看问题,请单击“绘图 - >红色”,然后在红色完成绘制之前单击“绘制 - >>蓝色”。如何让程序中止任何以前的绘图?以下是示例程序:
from tkinter import *
import random
import math
def line(canvas, w, h, p, i):
x0 = random.randrange(0, w)
y0 = random.randrange(0, h)
x1 = random.randrange(0, w)
y1 = random.randrange(0, h)
canvas.create_line(x0, y0, x1, y1, fill=p.col(i))
class Color:
def __init__(self, r, g, b):
self.red = r
self.gre = g
self.blu = b
def hexVal(self, v):
return (hex(v)[2:]).zfill(2)
def str(self):
return "#" + self.hexVal(self.red) + self.hexVal(self.gre) + self.hexVal(self.blu)
class Palette:
def __init__(self, n0, y):
self.colors = []
self.n = n0
self.m = 0
if y == "red":
self.red()
elif y == "blue":
self.blue()
def add(self, c):
self.colors.append(c)
self.m += 1
def red(self):
self.add(Color(127, 0, 0))
self.add(Color(255, 127, 0))
def blue(self):
self.add(Color(0, 0, 127))
self.add(Color(0, 127, 255))
def col(self, i):
k = i % (self.n*self.m)
z = k // self.n
j = k % self.n
c0 = self.colors[z]
c1 = self.colors[(z + 1) % self.m]
t0 = (self.n - j)/self.n
t1 = j/self.n
r = int(math.floor(c0.red*t0 + c1.red*t1))
g = int(math.floor(c0.gre*t0 + c1.gre*t1))
b = int(math.floor(c0.blu*t0 + c1.blu*t1))
c = Color(r, g, b)
return c.str()
def upd(canvas):
try:
canvas.update()
return True
except TclError:
return False
def tryLine(canvas, w, h, p, i, d):
try:
line(canvas, w, h, p, i)
if i % d == 0:
upd(canvas)
return True
except TclError:
return False
class MenuFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.WIDTH = 800
self.HEIGHT = 800
self.canvas = Canvas(self.parent, width=self.WIDTH, height=self.HEIGHT)
self.pack(side=BOTTOM)
self.canvas.pack(side=TOP, fill=BOTH, expand=1)
self.parent.title("Line Test")
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
self.parent.protocol('WM_DELETE_WINDOW', self.onExit)
menu = Menu(menubar)
menu.add_command(label="Red", command=self.onRed)
menu.add_command(label="Blue", command=self.onBlue)
menu.add_command(label="Exit", command=self.onExit)
menubar.add_cascade(label="Draw", menu=menu)
self.pRed = Palette(256, "red")
self.pBlue = Palette(256, "blue")
def onRed(self):
# How to abort here any processes currently running?
self.canvas.delete("all")
for i in range(0, 7000):
tryLine(self.canvas, self.WIDTH, self.HEIGHT, self.pRed, i, 100)
upd(self.canvas)
def onBlue(self):
# How to abort here any processes currently running?
self.canvas.delete("all")
for i in range(0, 7000):
tryLine(self.canvas, self.WIDTH, self.HEIGHT, self.pBlue, i, 100)
upd(self.canvas)
def onExit(self):
self.canvas.delete("all")
self.parent.destroy()
def main():
root = Tk()
frame = MenuFrame(root)
root.mainloop()
if __name__ == '__main__':
main()
答案 0 :(得分:1)
这是一个简单的例子吗? ;)
您可以添加跟踪当前所选方法的变量,然后在完成for
循环之前检查该变量是否存在。这是一个更简单的例子:
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
Button(self, text='Task A', command=self._a).pack()
Button(self, text='Task B', command=self._b).pack()
self.current_task = None # this var will hold the current task (red, blue, etc)
def _a(self):
self.current_task = 'a' # set the current task
for i in range(1000):
if self.current_task == 'a': # only continue this loop if its the current task
print('a')
self.update()
def _b(self):
self.current_task = 'b'
for i in range(1000):
if self.current_task == 'b':
print('b')
self.update()
root = Tk()
Example(root).pack()
root.mainloop()
请告诉我这是否有意义或不适合你。