Matrix程序,在python中使用绑定来停止/启动

时间:2014-11-01 21:30:42

标签: python loops matrix tkinter

我正在尝试编写一段代码来运行一个简单的矩阵副本,它只是随机生成字符并将它们打印到屏幕上。

编写实际的矩阵部分一直没有问题,我很满意我的方式,尽管我欢迎任何有关该部分的建议。

但我坚持的部分就是让它停止,一旦它开始。

基本上在伪代码中,这就是我想要做的事情

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已冻结,我无法执行任何操作。

2 个答案:

答案 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)

可以根据Tkinter强度创建逻辑

添加了重复延迟,正如您在下面的一条评论中所提到的那样。

添加了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()