【问题标题】:Tkinter loop "Tkinter não esta respondendo"Tkinter 循环“Tkinter não esta respondendo”
【发布时间】:2017-12-24 15:46:04
【问题描述】:

我有一个来自 tkinter 图形界面的代码,它与 arduino 通信,碰巧我得到了时间打开和关闭的时间,所以我将每个当前时间与无限循环中的输入进行比较,该无限循环仅用于当此处要求关闭 LED 的第二个输入代码条目结束时,当它进入循环时,tkinter 没有响应。

from tkinter import *
import serial
from time import strftime

conexao = serial.Serial('COM3', 9600, timeout=0.5)
cont=0
janela = Tk()
def ligar():
     global cont
     cont=cont+1
     if cont==1:
         valor=bytes(('1'),'utf-8')
         conexao.write(valor)
         ligar['text']='Desligar led'
     elif cont==2:
         valor=bytes(('2'),'utf-8')
         conexao.write(valor)
         ligar['text']='Ligar led'
         cont=0


def agendar():
     comeco= start.get()
     final=  limit.get()
     while 1>0:
          if comeco == strftime('%H:%M:%S'):
               valor=bytes(('1'),'utf-8')
               conexao.write(valor)
          elif final == strftime('%H:%M:%S'):
               valor=bytes(('2'),'utf-8')
               conexao.write(valor)
               break





ligar=Button(janela,command=ligar,text='ligar',width="60")
ligar.grid(row=1)
texto=Label(text='Defina o começo:').grid(row=2)
start=Entry(janela)
start.grid(row=3)
texto2=Label(text='Defina o fim:').grid(row=4)
limit=Entry(janela)
limit.grid(row=5)
salvar=Button(janela,width="30",text='Salvar Horarios',command=agendar)
salvar.grid(row=6)

【问题讨论】:

  • 请发布您的输出
  • 这个网站上有很多与 arduino 通信和使用 tkinter 相关的问题。在问这个问题之前你有没有做过任何研究?见How much research effort is expected of Stack Overflow users?
  • 代码完美运行,但在循环中界面挂起并且没有修改其他内容,但它会按照程序要求打开 LED
  • 不要使用 while 循环,而是使用 tkinter.after() 定期执行代码 - ti 不会阻塞 mainloop() 并且 IDE 不会冻结。顺便说一句:下次你可以写while True:而不是while 1>0:
  • 那段时间怎么和后面的呢,谢谢

标签: python loops tkinter arduino


【解决方案1】:

您可以使用线程而不是使用after 方法,这允许您的GUI 与while 循环同时运行。

import threading
from tkinter import *
import serial
from time import strftime

conexao = serial.Serial('COM3', 9600, timeout=0.5)
cont=0
janela = Tk()
def ligar():
     global cont
     cont=cont+1
     if cont==1:
         valor=bytes(('1'),'utf-8')
         conexao.write(valor)
         ligar['text']='Desligar led'
     elif cont==2:
         valor=bytes(('2'),'utf-8')
         conexao.write(valor)
         ligar['text']='Ligar led'
         cont=0

def agendar():
     global start,limit
     comeco= start.get()
     final=  limit.get()
     while 1>0:
          if comeco == strftime('%H:%M:%S'):
               valor=bytes(('1'),'utf-8')
               conexao.write(valor)
          elif final == strftime('%H:%M:%S'):
               valor=bytes(('2'),'utf-8')
               conexao.write(valor)
               break

global start,limit
ligar=Button(janela,command=ligar,text='ligar',width="60")
ligar.grid(row=1)
texto=Label(text='Defina o começo:').grid(row=2)
start=Entry(janela)
start.grid(row=3)
texto2=Label(text='Defina o fim:').grid(row=4)
limit=Entry(janela)
limit.grid(row=5)
salvar=Button(janela,width="30",text='Salvar Horarios',command=lambda: threading.Thread(target=agendar).start())
salvar.grid(row=6)

这里有一个简短的细分:

  1. 按下按钮执行 lambda 函数(使用 lambda 函数很有用,因为它可以让您避免包装函数)
  2. lambda 函数为您的议程函数创建一个单独的线程
  3. 线程开始

注意:我将 limit 和 start 定义为全局变量,但我不确定你是否需要它。
另外,我还没有测试过它,但我相当确定它可以工作。

【讨论】:

  • 尝试在最后调用 janela.mainloop()。还有一点,你不应该同时使用 ligar 作为按钮名和函数名。
【解决方案2】:

您应该使用after 定期运行代码。

我不能测试它,但我会做

from tkinter import *
import serial
from time import strftime

# -- 
def ligar():
     global cont

     cont = not cont

     if cont:
         conexao.write( b'1' )
         ligar['text'] = 'Desligar led'
     else:
         conexao.write( b'2' )
         ligar['text'] = 'Ligar led'


def agendar():
    comeco = start.get()
    final  = limit.get()

    current = strftime('%H:%M:%S')

    if comeco == current:
        conexao.write( b'1' )
        # run again after 1000ms (1s)
        janela.after(1000, agendar)        
    elif final == current:
        conexao.write( b'2' )

conexao = serial.Serial('COM3', 9600, timeout=0.5)
cont = False

janela = Tk()

ligar = Button(janela, command=ligar, text='ligar', width="60")
ligar.grid(row=1)

texto = Label(janela, text='Defina o começo:')
texto.grid(row=2)

start = Entry(janela)
start.grid(row=3)

texto2 = Label(janela, text='Defina o fim:')
texto2.grid(row=4)

limit = Entry(janela)
limit.grid(row=5)

salvar = Button(janela, width="30", text='Salvar Horarios', command=agendar)
salvar.grid(row=6)

janela.mainloop()

【讨论】:

  • 好吧,在该代码中,它仅在按下按钮时进行比较,而不是在条件为真时进行比较
  • 在其中我必须在时间等于输入的确切时刻点击,它不会自动比较
  • 正如我所说,我无法运行它来测试它。
猜你喜欢
  • 2013-12-15
  • 2018-05-26
  • 1970-01-01
  • 2013-06-19
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多