Форум сайта python.su
Здравствуйте! скажите как быть:
При нажатии на кнопку перехожу в функцию в которой циклюсь при помощи самовызова функции.
В функции приём строки с компорта - мне необходимо при нажатии - желательно той же самой кнопки останавливать процесс.
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()
Офлайн
я бы вот так сделал,кто опытнее скажите правильный ли у меня подход
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())
Офлайн
xam1816Если собрался что-то менять в тексте надписи, то к Label нужно привязать StringVar и менять её содержимое.
кто опытнее скажите правильный ли у меня подход
Офлайн
rocky1945 дело в том что сам tkinter тоже имеет цикл, а ваш “самоцикл” будет вешать ГУИ ткинтера. вам нужно или запускать свой цикл в отдельном потоке/процессе, или использвать метод root.after() ткинтера, как это в примере xam1816, или каждый тик цикла делать root.update(), что ИМХО, некошерно..
[code python][/code]
Отредактировано PEHDOM (Окт. 12, 2020 11:23:17)
Офлайн
Оказыается всё просто с методом 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()
Офлайн
странно - почему-то окно активно когда я мышкой удерживаю курсором на окне программы
Офлайн