Создавайте всплывающие окна непрерывно в цикле, не блокируя код - PullRequest
0 голосов
/ 19 сентября 2019

Моя программа выполняет потоковую передачу данных, и я хочу создать всплывающее окно, отображающее текст при каждом выполнении условия.Я попытался создать простое окно tkinter и окно ctypes, но оба они, похоже, блокируют мой код, не позволяя ему продолжаться до тех пор, пока окно не будет закрыто.Как я могу создать простую функциональность всплывающего окна, например, в цикле?

То, что у меня пока есть, является чем-то вроде этой структуры.

import tkinter as tk
for i in range(11):
    if i%5 == 0:  # Any condition
        popup = tk.Tk()
        label = ttk.Label(popup, text='hi', font=('Verdana', 12))
        label.pack(side='top', padx=10, pady=10)
        popup.mainloop()

и

import ctypes
for i in range(11):
    if i%5 == 0:  # Any condition
        popup = ctypes.windll.user32.MessageBoxW
        popup(None, 'hi', 'title', 0)

Однако в обоих случаях цикл не будет продолжаться, пока я не закрою всплывающее окно.

Ответы [ 2 ]

1 голос
/ 19 сентября 2019

Случай 1 - Tkinter:

Вы используете mainloop(), который ничем не отличается от истинного цикла while.Вы можете заставить его работать непрерывно, удалив его.

import tkinter as tk
from tkinter import ttk

for i in range(11):
    if i%5 == 0:  # Any condition
        popup = tk.Tk()
        label = ttk.Label(popup, text='hi', font=('Verdana', 12))
        label.pack(side='top', padx=10, pady=10)

Случай 2 - Ctypes:

Чтобы сделать его непрерывным, вам придется использовать threading.

import ctypes, threading

for i in range(11):
    if i%5 == 0:  # Any condition
        popup = ctypes.windll.user32.MessageBoxW
        threading.Thread(target = lambda :popup(None, 'hi', 'title', 0)).start()
1 голос
/ 19 сентября 2019

Не слишком знаком с ctypes, но для tkinter пользовательский интерфейс всегда будет блокировать ваш основной код во время mainloop.

Вы можете несколько обойти его, если просто создаете экземпляр Tk() без вызова mainloop и используете функцию after:

import tkinter as tk
from tkinter.messagebox import showinfo

root = tk.Tk()
root.withdraw()

for i in range(10):
    if i in (5, 8):
        root.after(ms=1, func=lambda x=i: showinfo('Message!', f'Stopped at {x}'))

# ... do something here

root.after ставит окно сообщения в очередьбудет отображаться через 1 миллисекунду (ms=1).

Лучшим способом может быть создание немодального сообщения / диалогового окна в ctypes, но, как уже упоминалось, я не слишком знаком, и быстрый поиск не сделалне дает простого решения.

...