Задать вопрос
Hackerman1
@Hackerman1
17 лет, плохое зрение.

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

У меня есть такой код:
Длинный код
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('\n\n')
    traceback.print_exc(file=file, chain=True)
    traceback.print_exc()
    file.close()

Я хочу сделать так: я(код) или пользователь завершаем работу потока, закрывая окно, но если пользователь снова нажимает комбинацию клавиш, то поток проверяется на мёртв/жив, и если мертв, то есть окно закрыто, то он запускался снова и запускал окно. Если есть более адекватный способ, буду рад послушать. Сейчас у меня сделано костыльно - окно становится прозрачным, но не закрывается. Это может быть не очень удобно.
  • Вопрос задан
  • 62 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
root.withdraw() для скрытия и root.deiconify() для показа пробовал?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы