Найти - Пользователи
Полная версия: Выйти из самоцикла в tkinter
Начало » Python для новичков » Выйти из самоцикла в tkinter
1
rocky1945
Здравствуйте! скажите как быть:
При нажатии на кнопку перехожу в функцию в которой циклюсь при помощи самовызова функции.
В функции приём строки с компорта - мне необходимо при нажатии - желательно той же самой кнопки останавливать процесс.
 but_receive = Button(frame_receive, text = 'Принимать',height=1,width = 30,bg = "silver", fg = "black",relief="solid",borderwidth = 1,command = receive);but_receive.pack(side=LEFT)
 #приём данных
def receive():
        time.sleep(0.05)
        lbl_receive.update()
        answer = ser.readline().decode('ascii'); lbl_receive.config(text = "Принято: " + answer,bg = "gold",anchor=N)
        receive()
xam1816
я бы вот так сделал,кто опытнее скажите правильный ли у меня подход
 import tkinter as tk
import random
class ComPort:
	# прием данных
	def receive(self):
		answer = random.randint(0, 100)
		return answer
class InterFace:
	def __init__(self, comport):
		self.comport = comport
		self.root = tk.Tk()
		# -----------
		self.lbl = tk.Label(text='остановлено', bg='red')
		self.lbl.pack()
		# ------------
		self.active = False  # когда активна выполняется функция обновления lbl
		self.but_receive = tk.Button(
			text='Принимать',
			height=1,
			width=30,
			bg="silver",
			fg="black",
			relief="solid",
			borderwidth=1,
			command=lambda: (self.btn_active(), self.update_lbl())
		)
		self.but_receive.pack()
		# ----------------------
		self.root.mainloop()
	def btn_active(self):
		self.active = not self.active
	# обновление lbl
	def update_lbl(self):
		if self.active:
			self.lbl.config(text=f'принято {self.comport.receive()}', bg="gold")
			self.root.after(200, self.update_lbl)# циклит функцию,200 это задержка в мс.
		else:
			self.lbl.config(text=f'остановлено', bg='red')
			return
if __name__ == '__main__':
	InterFace(ComPort())
py.user.next
xam1816
кто опытнее скажите правильный ли у меня подход
Если собрался что-то менять в тексте надписи, то к Label нужно привязать StringVar и менять её содержимое.

Обработчик кнопки должен вызываться максимально просто. lambda используется, если там передаётся какой-то параметр в обработчик. Если не передаётся, то не надо lambda использовать. Внутри обработчика уже можно переставлять флаг. Обработчик кнопки не должен знать, что его вызывают из-за кнопки, и не должен знать про существование кнопки вообще.
PEHDOM
rocky1945 дело в том что сам tkinter тоже имеет цикл, а ваш “самоцикл” будет вешать ГУИ ткинтера. вам нужно или запускать свой цикл в отдельном потоке/процессе, или использвать метод root.after() ткинтера, как это в примере xam1816, или каждый тик цикла делать root.update(), что ИМХО, некошерно..
rocky1945
Оказыается всё просто с методом after_cancel:
 from tkinter import *
import time
d = 0;z = 0
def r():
    global d
    global z
    d = not d
    if d == True:
        tick()
    else:
        label['text'] = time.strftime('')
        root.after_cancel(z)
                    
def tick():
    global z
    z = label.after(200, tick)
    label['text'] = time.strftime('%H:%M:%S')
    
    
root=Tk()
label = Label(font='sans 20')
label.pack()
but = Button(command = r)
but.pack()
root.mainloop()
rocky1945
странно - почему-то окно активно когда я мышкой удерживаю курсором на окне программы
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB