Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 11, 2020 21:29:05

rocky1945
Зарегистрирован: 2020-09-04
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Выйти из самоцикла в tkinter

Здравствуйте! скажите как быть:
При нажатии на кнопку перехожу в функцию в которой циклюсь при помощи самовызова функции.
В функции приём строки с компорта - мне необходимо при нажатии - желательно той же самой кнопки останавливать процесс.

 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()

Офлайн

#2 Окт. 12, 2020 00:42:45

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1393
Репутация: +  124  -
Профиль   Отправить e-mail  

Выйти из самоцикла в tkinter

я бы вот так сделал,кто опытнее скажите правильный ли у меня подход

 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())

Офлайн

#3 Окт. 12, 2020 02:14:59

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9999
Репутация: +  857  -
Профиль   Отправить e-mail  

Выйти из самоцикла в tkinter

xam1816
кто опытнее скажите правильный ли у меня подход
Если собрался что-то менять в тексте надписи, то к Label нужно привязать StringVar и менять её содержимое.

Обработчик кнопки должен вызываться максимально просто. lambda используется, если там передаётся какой-то параметр в обработчик. Если не передаётся, то не надо lambda использовать. Внутри обработчика уже можно переставлять флаг. Обработчик кнопки не должен знать, что его вызывают из-за кнопки, и не должен знать про существование кнопки вообще.



Офлайн

#4 Окт. 12, 2020 11:21:51

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Выйти из самоцикла в tkinter

rocky1945 дело в том что сам tkinter тоже имеет цикл, а ваш “самоцикл” будет вешать ГУИ ткинтера. вам нужно или запускать свой цикл в отдельном потоке/процессе, или использвать метод root.after() ткинтера, как это в примере xam1816, или каждый тик цикла делать root.update(), что ИМХО, некошерно..



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Окт. 12, 2020 11:23:17)

Офлайн

#5 Окт. 12, 2020 13:19:58

rocky1945
Зарегистрирован: 2020-09-04
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Выйти из самоцикла в tkinter

Оказыается всё просто с методом 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()

Офлайн

#6 Окт. 12, 2020 14:12:59

rocky1945
Зарегистрирован: 2020-09-04
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Выйти из самоцикла в tkinter

странно - почему-то окно активно когда я мышкой удерживаю курсором на окне программы

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version