我正在尝试编写一段代码来运行一个简单的矩阵副本,它只是随机生成字符并将它们打印到屏幕上。
编写实际的矩阵部分一直没有问题,我很满意我的方式,尽管我欢迎任何有关该部分的建议。
但我坚持的部分就是让它停止,一旦它开始。
基本上在伪代码中,这就是我想要做的事情
IF PRESS == s:
matrix()
check press
IF PRESS == q:
END matrix()
我遇到的主要困难是在运行矩阵代码时检查按键。 这是我目前的代码:
import tkinter as tk
from random import randint
global event
event=""
box = tk.Tk()
def matrix():
line = chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
print (line)
key(event)
def key(event):
box.focus_set()
while event.char == "s":
print("Matrix starting")
matrix()
if event.char == "q":
#stops matrix
print("Matrix stopped")
box.bind("<Key>", key)
box.mainloop()
希望有人能够帮助我,我已经在互联网上看了,但我找不到我要找的东西。
此外,当我尝试更改代码时,GUI已冻结,我无法执行任何操作。
答案 0 :(得分:1)
每个按键事件都会调用一次key
函数,但在内部有一个永不停止的while循环:
while event.char == "s": # program gets stuck in this loop as event.char is
# always "s" for this function call
print("Matrix starting")
matrix()
if
语句应足以解决问题:
if event.char == "s":
print("Matrix starting")
matrix()
if event.char == "q":
#stops matrix
print("Matrix stopped")
为了打印多行,您应该修改矩阵函数以使用for
循环:
def matrix():
for i in range(10):
line = chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
print (line)
您可能不希望矩阵调用key(event)
,因为这也会让您进入无限循环
答案 1 :(得分:1)
添加了重复延迟,正如您在下面的一条评论中所提到的那样。
添加了StateFullControl({ nil->[S]tartedSTATE->[Q]uit->nil }
)来阻止/避免无意义的序列
添加了一些Tkinter详细信息
您可能希望限制 chr()
的范围,因为原始范围内的所有字符都不是&#34; 可打印&#34;并且你承担了不必要的副作用的风险。
try:
import Tkinter as tk
import tkMessageBox
except:
import tkinter as tk
import tkinter.messagebox as tkMessageBox
from random import randint
global event # global is possible, designing a Class is better though
event = "" # no need to assign <event>
global box
box = tk.Tk() # Tkinter top-level instance
box.aDelayInMSEC = 30000 # .SET an attribute, repeat each 30 sec
box.inStartedSTATE = False # .SET an attribute, a stateFull control
box.title( "MATRIX Reloaded ... " ) # Tkinter beautifier
box.protocol( 'WM_DELETE_WINDOW', ExitPROCESS ) # [X]-overide ------------------------
box.lift() # GUI make visible
def matrix():
line = chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
+ chr(randint(0,127)) + "\t" + chr(randint(0,127)) + "\t"
print (line)
box.after( box.aDelayInMSEC, matrix ) # re-schedule a next round .after()
def StartMATRIX( anEvent ):
if not box.inStartedSTATE: # .IF( not STARTED-already )
print( "Matrix starting" ) # .UI
box.inStartedSTATE = True # .SET state
matrix() # .CALL
pass
def StopMATRIX( anEvent ):
if box.inStartedSTATE: # .IF( was STARTED-before )
print( "Matrix stopped" ) # .UI
box.inStartedSTATE = False # .SET state
ExitPROCESS() # .CALL
pass
def ExitPROCESS(): # MVC-Controller-Part ..
if tkMessageBox.askokcancel( "Quit GUI", "Do you really wish to quit?" ):
box.destroy()
pass
box.bind( "<KeyPress-s>", StartMATRIX ) # .BIND StartMATRIX()-HANDLER
box.bind( "<Shift-KeyPress-s>", StartMATRIX ) # .BIND StartMATRIX()-HANDLER
box.bind( "<KeyPress-q>", StopMATRIX ) # .BIND StopMATRIX()-HANDLER
box.bind( "<Shift-KeyPress-q>", StopMATRIX ) # .BIND StopMATRIX()-HANDLER
box.mainloop()