首页 > 解决方案 > 使窗口像警告信号灯一样闪烁特定次数并执行某些功能

问题描述

我想使用 tkinter 在 python 中制作一个通知应用程序。我想检查系统时间,如果它与任何行的数据库时间字段中的时间相匹配,窗口会显示闪烁的特定次数,例如危险警告灯。闪烁完成后,窗口应该显示的次数约为要通知用户的事件/计划。我试图编写代码,但它使窗口只出现一次。

我曾尝试使用 tkinter 的 root.after 方法,但不知道如何在应用程序中实现我想要的要求。

#repeatedly checking if system time matched any teachers scedule time--------------------------------

def repeatedquery():

    def alertmsg():

        for j in range (4):
            newteacheradd.withdraw()
            messagewindow = Toplevel()

            #to come out press alt+escape

            messagewindow.wm_attributes("-fullscreen", 1)
            messagewindow.title("Notification")
            msgflash = Label(messagewindow, text='Notice', bg="#1f618d", fg='white', font=("Verdana", 28, 'bold'),
                             height=5,width=40, relief=RAISED)
            msgflash.place(x=150, y=300)
            print ("hjgj")
            time.sleep(10)
            messagewindow.after(15000, messagewindow.withdraw)

        messagewindow.mainloop()

    def showMesagewin():

        newteacheradd.withdraw()

        global messagewindow
        messagewindow = Toplevel()
        # Covers whole  screen  to come  out     press          Alt + Esc
        messagewindow.wm_attributes("-fullscreen", 1)
        messagewindow.title("Notification Screen")

        tt =  '{:3}'.format(str(i[0])) + '       {:15}'.format(str(i[1])) + '  {:15}'.format(
            str(i[2])) + '  {:15}'.format(str(i[3])) + '\n'


        msg = 'YOUR LECTURE/PRAC  DETAILS  \n\n'+"           "+tt
        # to place message at centre
        msgflash = Label(messagewindow, text=msg, bg="#1f618d",fg='white', font=("Verdana", 28,'bold'),height=5,relief = RAISED)
        msgflash.place(x=250, y=300)


        #Bell rings ___________________________________________________________________________________________
        pygame.init()
        pygame.mixer.init()
        sounda = pygame.mixer.Sound("bell.wav")

        sounda.play()
        time.sleep(5)
        #Belll rings____________________________________________________________________________________________

        messagewindow.after(5000, messagewindow.withdraw)

        # schedule closing of showMesagewin event in 5 seconds
        messagewindow.mainloop()

    currentDT = datetime.datetime.now()
    t=currentDT.strftime("%H")



    conn = sq.connect("Teacher.db")
    curr = conn.cursor()
    tid = __userip.get()


    day2 = datetime.datetime.now()
    day3 = day2.strftime("%A")

    curr.execute("select Time,Subject,Lecture_prac,Venue from "+day3+" where Teacher_ID=?", (tid,))
    sc = curr.fetchall()
    t1=0
    for i in sc:

        if (t == i[0]):
            alertmsg()
            print ('gbhj')
            showMesagewin()

    newteacheradd.after(1000,repeatedquery)
    #-------------------------------------------------------------------------------------------------
repeatedquery()



编辑代码

#repeatedly checking if system time matched any teachers scedule time--------------------------------

from  tkinter import *
import datetime
import time

def mainwin():
    newteacherappend=Tk()
    i=[]

    i.append(2)
    i.append('Phy')
    i.append('L') 
    i.append('301')

    def repeatedquery():

        def alertmsg():

            for j in range (4):
                newteacherappend.withdraw()
                messagewindow = Toplevel()

                # Covers whole  screen  to come  out     press          Alt + Esc
                messagewindow.wm_attributes("-fullscreen", 1)
                messagewindow.title("Notification")
                msgflash = Label(messagewindow, text='Notice', bg="#1f618d", fg='white', font=("Verdana", 28, 'bold'),
                                 height=5,width=40, relief=RAISED)
                msgflash.place(x=150, y=300)
                print ("hjgj")
                time.sleep(5)
                messagewindow.after(5000, messagewindow.withdraw)

            messagewindow.mainloop()

        def showMesagewin():

            newteacherappend.withdraw()

            global messagewindow
            messagewindow = Toplevel()
            # Covers whole  screen  to come  out     press          Alt + Esc
            messagewindow.wm_attributes("-fullscreen", 1)
            messagewindow.title("Notification Screen")

            tt =  '{:3}'.format(str(i[0])) + '       {:15}'.format(str(i[1])) + '  {:15}'.format(
                str(i[2])) + '  {:15}'.format(str(i[3])) + '\n'


            msg = 'YOUR LECTURE/PRAC  DETAILS  \n\n'+"           "+tt
            # to place message at centre
            msgflash = Label(messagewindow, text=msg, bg="#1f618d",fg='white', font=("Verdana", 28,'bold'),height=5,relief = RAISED)
            msgflash.place(x=250, y=300)



            messagewindow.after(5000, messagewindow.withdraw)

            # schedule closing of showMesagewin event in 5 seconds
            messagewindow.mainloop()

        currentDT = datetime.datetime.now()
        t=currentDT.strftime("%H")
        t=2

        if (t == i[0]):
            alertmsg()
            print ('gbhj')
            showMesagewin()

        newteacherappend.after(1000,repeatedquery)

    repeatedquery()

    newteacherappend.mainloop()


mainwin()




标签: pythontkinter

解决方案


我制作了after不使用sleep显示闪烁消息的代码 - 第一次在 5 秒后,第二次在 15 秒后。而且它只有一个mainloop()

代码中的更多信息

import tkinter as tk
import datetime

# --- functions ----

# function which creates window with message
def message_start(text):
    global repeates
    global message_window
    global message_label

    repeates = 3 # how many times change background color

    # create window with messages
    message_window = tk.Toplevel()
    message_label = tk.Label(message_window, text=text, bg='red')
    message_label.pack()

    # update window after 500ms
    root.after(500, message_update)

# function which changes background in displayed window
def message_update():
    global message_window
    global repeates

    if repeates > 0:
        repeates -= 1

        if message_label['bg'] == 'red':
            message_label['bg'] = 'green'
        else:
            message_label['bg'] = 'red'

        # update window after 500ms
        root.after(500, message_update)
    else:
        # close window 
        message_window.destroy()

        # inform `check_time` that window is not busy
        message_window = None

# loop which updates current time and checks which message it has to display        
def check_time():

    # display current time
    current_time = datetime.datetime.now()
    root_label_time['text'] = current_time.strftime('%Y.%m.%d %H:%M:%S')

    # check if there is message to display
    for message in messages:
        if current_time >= message['start']:  # it is time to display message
            if message['state'] == 'waiting': # message is not displayed at this moment
                if message_window is None: # window is not busy
                    message['state'] = 'displayed' # don't display it again
                    message_start(message['text'])  # display message

    # update time after 1000ms (1s)
    root.after(1000, check_time)

# --- main ---

messages = [
    {
        'text': 'Time for coffee',
        'start': datetime.datetime.now() + datetime.timedelta(seconds=5),
        'state': 'waiting',
    },
    {
        'text': 'Back to work',
        'start': datetime.datetime.now() + datetime.timedelta(seconds=15),
        'state': 'waiting',
    },
]

message_window = None
repeates = 3

# ---

root = tk.Tk()

# label with current time
root_label_time = tk.Label(root, text='- wait -')
root_label_time.pack()

# label with sheduler
root_label_sheduler = tk.Label(root)
root_label_sheduler.pack()

# displa messages in sheduler
for message in messages:
    root_label_sheduler['text'] +=  "\n" + message['start'].strftime('%Y.%m.%d %H:%M:%S ') + message['text']

# start displaying time    
check_time()

root.mainloop()

推荐阅读