Как мне правильно запустить поток с ткинтером?

Ссылка скопирована
1 ответ

У меня есть такой код:
Длинный код

from tkinter import * from tkinter import ttk import re import win32gui import threading from threading import Timer import traceback import configparser import pyautogui import cv2 import keyboard import time import queue  try:       def read_config(name):         config = configparser.ConfigParser()         config.read(name, encoding='utf-8')         conf = {}         conf['scale_x'] = config.get("Combinations", "scale_x")         conf['scale_y'] = config.get("Combinations", "scale_y")         conf['resolution'] = config.get("Combinations", "Resolution")         return conf     conf = read_config("code/buttons.ini")     resolution = conf['resolution']      resolutionObject = {         '0': [1034,436,329,329,329,329], #1366x768    #[x,y,w,h,size,sizeReal]         '1': [1054,514,384,384,384,384], #1440x900         '2': [1234,604,444,444,444,444], #1680x1050         '3': [1462,622,456,456,456,456], #1920x1080         '4': [1462,742,456,456,456,456], #1920x1200         #'3': [1034,436,329,329,329,329], #2560x1080         '5': [1955,835,605,605,465,605], #2560x1440         '6': [2835,835,605,605,465,605], #3440x1440         '7': [2940,1260,900,900,480,900], #3840x2160         '8': [3924,1684,1196,1196,460,1196], #5120x2280     }          resolutionX = resolutionObject[resolution][0]     resolutionY = resolutionObject[resolution][1]     resolutionW = resolutionObject[resolution][2]     resolutionH = resolutionObject[resolution][3]       def process_selection(selection):         # Код убран для экономии времени читателя вопроса     ######################################################################     #Создание окна масштаба      file = open('code/scale.txt', 'r')     scale = file.read()     file.close()     if scale == "" or scale == "0":         scale = "5"         file = open('code/scale.txt', 'w')         file.write(scale)         file.close()     scale = round(float(scale), 1)          def close():         # Код убран для экономии времени читателя вопроса      def validation(newval):         # Код убран для экономии времени читателя вопроса      def selectWindow(event=1):         # Код убран для экономии времени читателя вопроса      def window():          def set_transparency(root_window, transparency, fast=False):             if transparency == 1.0:                 root_window.attributes('-alpha', transparency)             else:                 if fast:                     root_window.attributes('-alpha', transparency)                 else:                     time.sleep(1.5)                     root_window.attributes('-alpha', transparency)          def update_window(root_window, label_text, selection_label):             try:                 data = state_queue.get_nowait()                 if data.get("labeltext") is not None:                     label_text["text"] = data.get("labeltext")                 elif data.get("set_transparency") is not None:                     if root_window.attributes('-alpha') == 0.0 and data.get("set_transparency") == 1.0:                         print("Setting transparency 1")                         set_transparency(root_window, data.get("set_transparency"))                     elif root_window.attributes('-alpha') == 1.0 and data.get("set_transparency") == 0.0:                         print("Setting transparency 2")                         set_transparency(root_window, data.get("set_transparency"))                     else:                         print("Setting transparency 3")                 elif data.get("selection") is not None:                     selection_label["text"] = data.get("selection")                 else:                     print("Ошибка. Неверные данные.")             except queue.Empty:                 pass             root_window.after(10, lambda: update_window(root_window, label_text, selection_label))          root = Tk()          geometry = f"199x70+{conf['scale_x']}+{conf['scale_y']}"         root.geometry(geometry)         # check = (root.register(validation), "%P")         # entry = Entry(fg="yellow", bg="black", font=('Roboto', '16'), width=5, validate="key", validatecommand=check)         # entry.master.overrideredirect(True)         # entry.master.lift()         # entry.master.wm_attributes("-topmost", True)         # entry.place(x=22, y=38)          label = Label(root, text=f'{scale} пикс/м', font=('Roboto', '19'), fg='yellow', bg='brown')         label.master.overrideredirect(True)         label.master.lift()         label.master.wm_attributes("-topmost", True)         label.pack(side=TOP)          selection = Label(root, text="Ожидаю ввода", font=('Roboto', '19'), fg='yellow', bg='brown')         selection.master.overrideredirect(True)         selection.master.lift()         selection.master.wm_attributes("-topmost", True)         selection.pack(side=BOTTOM)         #set_transparency(root, 0.0, True)         btn1 = ttk.Button(text="X", command=lambda: quit(), width=3)         btn1.master.overrideredirect(True)         btn1.master.lift()         btn1.master.wm_attributes("-topmost", True)         btn1.place(x=169, y=3)          timeout = 0         t = Timer(timeout, selectWindow)         t.start()          root.lift()         root.focus_force()         root.after(10, lambda: update_window(root, label, selection))         root.mainloop()       def main():         elements = [140, 150, 160, 170, 180, 185, 190, 200, 225, 250, 275, 300, 325, 350, 400, 450, 500, 550]         current_selection = -1         n_seconds = 2  # Время бездействия в секундах         plus = 'ctrl+='  # Комбинация клавиш для выбора элемента         minus = 'ctrl+-'         t = None         win = None          def on_key_event(event):             nonlocal current_selection             nonlocal t             nonlocal win             global Window              if event.event_type == keyboard.KEY_DOWN:                 if keyboard.is_pressed(plus):                     #check_window()                     data = {"set_transparency": 1.0}                     state_queue.put(data)                     current_selection += 1                     current_selection %= len(elements)  # Зацикливание списка                     print(f"Current selection: {elements[current_selection]}")                     selection_data = {"selection": elements[current_selection]}                     state_queue.put(selection_data)                     if t is not None:                         t.cancel()                         t = Timer(n_seconds, process_selection, [elements[current_selection]])                         t.start()                     else:                         t = Timer(n_seconds, process_selection, [elements[current_selection]])                         t.start()                 elif keyboard.is_pressed(minus):                     #check_window()                     data = {"set_transparency": 1.0}                     state_queue.put(data)                     current_selection -= 1                     current_selection %= len(elements)  # Зацикливание списка                     print(f"Current selection: {elements[current_selection]}")                     selection_data = {"selection": elements[current_selection]}                     state_queue.put(selection_data)                     if t is not None:                         t.cancel()                         t = Timer(n_seconds, process_selection, [elements[current_selection]])                         t.start()                     else:                         t = Timer(n_seconds, process_selection, [elements[current_selection]])                         t.start()          keyboard.on_press(on_key_event)          while True:             time.sleep(0.01)      ######################################################################     if __name__ == "__main__":         state_queue = queue.Queue()         Window = threading.Thread(target=window)         Window.start()         main()  except Exception as e:     file = open('error.log', 'a')     file.write('nn')     traceback.print_exc(file=file, chain=True)     traceback.print_exc()     file.close()

from tkinter import * from tkinter import ttk import re import win32gui import threading from threading import Timer import traceback import configparser import pyautogui import cv2 import keyboard import time import queue try: def read_config(name): config = configparser.ConfigParser() config.read(name, encoding='utf-8') conf = {} conf['scale_x'] = config.get("Combinations", "scale_x") conf['scale_y'] = config.get("Combinations", "scale_y") conf['resolution'] = config.get("Combinations", "Resolution") return conf conf = read_config("code/buttons.ini") resolution = conf['resolution'] resolutionObject = { '0': [1034,436,329,329,329,329], #1366x768 #[x,y,w,h,size,sizeReal] '1': [1054,514,384,384,384,384], #1440x900 '2': [1234,604,444,444,444,444], #1680x1050 '3': [1462,622,456,456,456,456], #1920x1080 '4': [1462,742,456,456,456,456], #1920x1200 #'3': [1034,436,329,329,329,329], #2560x1080 '5': [1955,835,605,605,465,605], #2560x1440 '6': [2835,835,605,605,465,605], #3440x1440 '7': [2940,1260,900,900,480,900], #3840x2160 '8': [3924,1684,1196,1196,460,1196], #5120x2280 } resolutionX = resolutionObject[resolution][0] resolutionY = resolutionObject[resolution][1] resolutionW = resolutionObject[resolution][2] resolutionH = resolutionObject[resolution][3] def process_selection(selection): # Код убран для экономии времени читателя вопроса ###################################################################### #Создание окна масштаба file = open('code/scale.txt', 'r') scale = file.read() file.close() if scale == "" or scale == "0": scale = "5" file = open('code/scale.txt', 'w') file.write(scale) file.close() scale = round(float(scale), 1) def close(): # Код убран для экономии времени читателя вопроса def validation(newval): # Код убран для экономии времени читателя вопроса def selectWindow(event=1): # Код убран для экономии времени читателя вопроса def window(): def set_transparency(root_window, transparency, fast=False): if transparency == 1.0: root_window.attributes('-alpha', transparency) else: if fast: root_window.attributes('-alpha', transparency) else: time.sleep(1.5) root_window.attributes('-alpha', transparency) def update_window(root_window, label_text, selection_label): try: data = state_queue.get_nowait() if data.get("labeltext") is not None: label_text["text"] = data.get("labeltext") elif data.get("set_transparency") is not None: if root_window.attributes('-alpha') == 0.0 and data.get("set_transparency") == 1.0: print("Setting transparency 1") set_transparency(root_window, data.get("set_transparency")) elif root_window.attributes('-alpha') == 1.0 and data.get("set_transparency") == 0.0: print("Setting transparency 2") set_transparency(root_window, data.get("set_transparency")) else: print("Setting transparency 3") elif data.get("selection") is not None: selection_label["text"] = data.get("selection") else: print("Ошибка. Неверные данные.") except queue.Empty: pass root_window.after(10, lambda: update_window(root_window, label_text, selection_label)) root = Tk() geometry = f"199x70+{conf['scale_x']}+{conf['scale_y']}" root.geometry(geometry) # check = (root.register(validation), "%P") # entry = Entry(fg="yellow", bg="black", font=('Roboto', '16'), width=5, validate="key", validatecommand=check) # entry.master.overrideredirect(True) # entry.master.lift() # entry.master.wm_attributes("-topmost", True) # entry.place(x=22, y=38) label = Label(root, text=f'{scale} пикс/м', font=('Roboto', '19'), fg='yellow', bg='brown') label.master.overrideredirect(True) label.master.lift() label.master.wm_attributes("-topmost", True) label.pack(side=TOP) selection = Label(root, text="Ожидаю ввода", font=('Roboto', '19'), fg='yellow', bg='brown') selection.master.overrideredirect(True) selection.master.lift() selection.master.wm_attributes("-topmost", True) selection.pack(side=BOTTOM) #set_transparency(root, 0.0, True) btn1 = ttk.Button(text="X", command=lambda: quit(), width=3) btn1.master.overrideredirect(True) btn1.master.lift() btn1.master.wm_attributes("-topmost", True) btn1.place(x=169, y=3) timeout = 0 t = Timer(timeout, selectWindow) t.start() root.lift() root.focus_force() root.after(10, lambda: update_window(root, label, selection)) root.mainloop() def main(): elements = [140, 150, 160, 170, 180, 185, 190, 200, 225, 250, 275, 300, 325, 350, 400, 450, 500, 550] current_selection = -1 n_seconds = 2 # Время бездействия в секундах plus = 'ctrl+=' # Комбинация клавиш для выбора элемента minus = 'ctrl+-' t = None win = None def on_key_event(event): nonlocal current_selection nonlocal t nonlocal win global Window if event.event_type == keyboard.KEY_DOWN: if keyboard.is_pressed(plus): #check_window() data = {"set_transparency": 1.0} state_queue.put(data) current_selection += 1 current_selection %= len(elements) # Зацикливание списка print(f"Current selection: {elements[current_selection]}") selection_data = {"selection": elements[current_selection]} state_queue.put(selection_data) if t is not None: t.cancel() t = Timer(n_seconds, process_selection, [elements[current_selection]]) t.start() else: t = Timer(n_seconds, process_selection, [elements[current_selection]]) t.start() elif keyboard.is_pressed(minus): #check_window() data = {"set_transparency": 1.0} state_queue.put(data) current_selection -= 1 current_selection %= len(elements) # Зацикливание списка print(f"Current selection: {elements[current_selection]}") selection_data = {"selection": elements[current_selection]} state_queue.put(selection_data) if t is not None: t.cancel() t = Timer(n_seconds, process_selection, [elements[current_selection]]) t.start() else: t = Timer(n_seconds, process_selection, [elements[current_selection]]) t.start() keyboard.on_press(on_key_event) while True: time.sleep(0.01) ###################################################################### if __name__ == "__main__": state_queue = queue.Queue() Window = threading.Thread(target=window) Window.start() main() except Exception as e: file = open('error.log', 'a') file.write('nn') traceback.print_exc(file=file, chain=True) traceback.print_exc() file.close()

Я хочу сделать так: я(код) или пользователь завершаем работу потока, закрывая окно, но если пользователь снова нажимает комбинацию клавиш, то поток проверяется на мёртв/жив, и если мертв, то есть окно закрыто, то он запускался снова и запускал окно. Если есть более адекватный способ, буду рад послушать. Сейчас у меня сделано костыльно - окно становится прозрачным, но не закрывается. Это может быть не очень удобно.

Дополнительно:

root.withdraw() для скрытия и root.deiconify() для показа пробовал?

  • Нет. Я их упоминания нигде не видел, пока искал. Спасибо, помогло!
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Виктор Sys Ответ

Для запуска потока с ткинтером в PHP вам нужно использовать класс \Thread из расширения pthreads. Вот пример кода, демонстрирующий это:

synchronized(function($tk) {
            $tk->wait();
        }, $tk);
    }
}
 
$thread = new MyThread();
$thread->start();
 
$thread->synchronized(function($thread) {
    $thread->notify();
}, $thread);
 
$thread->join();
 
?>

synchronized(function($tk) { $tk->wait(); }, $tk); } } $thread = new MyThread(); $thread->start(); $thread->synchronized(function($thread) { $thread->notify(); }, $thread); $thread->join(); ?>

В этом примере создается класс MyThread, который наследуется от класса Thread. В методе run() создается объект Threaded (ткинтер) и блокируется его с использованием метода synchronized. Затем создается объект потока, запускается и блокируется с использованием методов synchronized и notify. После этого поток присоединяется с использованием метода join().

Убедитесь, что у вас установлено и включено расширение pthreads для PHP, иначе этот код не будет работать. Не забудьте также проверить совместимость версий PHP и pthreads.

Надеюсь, этот ответ поможет вам правильно запустить поток с ткинтером в PHP. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно