简体   繁体   中英

Reverse ttk.Progressbar()

Curious how to fill a ttk.Progressbar() to the maximum value (any number specified by user) and reduce the bar with step in specified increments. So take a 100% filled bar (for instance user specifies 100 as the max value) and reduce it 25% every 15 seconds. here is what I've got:

#import module for update frequency and gui. ttk for progressbar
import threading,ttk
from Tkinter import *

#establishs counter for testing purposes
counter = 0

#establish window
root = Tk()

def main():
    #user inputs health
    health = float(input("Enter health:"))

    #user inputs how much damage each bullet does
    dps = float(input("Enter Damage per shot:"))

    #user inputs the fire rate of the weapon
    spm = float(input("Enter Fire Rate:"))

    #from user inputs establish how many shots it takes to reduce health to or below zero

    if ((health / dps).is_integer()) is False: #checks if the stk value will be a float

        stk = int(health / dps) + 1 #since stk value is a float go up to next whole number. 33dps doesn't kill in 3 shots.

    else: #if stk value is an integer, establishes stk variable

        stk = health / dps

    delay_in_seconds = float(60 / spm)

    #establishes the time to kill in seconds, take one from stk to account for delay of gunfire
    ttki = ((stk - 1) * delay_in_seconds)

    # establish progressbar
    progre = ttk.Progressbar(root, orient='horizontal', maximum=health, mode='determinate')
    progre.pack(fill=X)

    # test on how to test for frequency of updating GUI once I figure out how in the heck to build it
    def DPS_Timer():
        global counter
        print counter
        if counter != (stk-1):
            counter += 1
            progre.step(float((health/stk)))
            root.after(int(ttki*1000/stk), DPS_Timer)
        else:
            progre.stop()

    # establish GUI Button
    B1 = Button(root, text='start', command=DPS_Timer).pack(fill=X)

    root.mainloop()

main()

so basically I want this portion of code

# establish progressbar
progre = ttk.Progressbar(root, orient='horizontal', maximum=health, mode='determinate')
progre.pack(fill=X)

# test on how to test for frequency of updating GUI once I figure out how in the heck to build it
def DPS_Timer():
    global counter
    print counter
    if counter != (stk-1):
        counter += 1
        progre.step(float((health/stk)))
        root.after(int(ttki*1000/stk), DPS_Timer)
    else:
        progre.stop()

# establish GUI Button
B1 = Button(root, text='start', command=DPS_Timer).pack(fill=X)

to say "Hey ttk.Progressbar(), depict the bar at 100% / the maximum value of health and I need you to reduce it at this step value at this rate." This also might provide some insight that it isn't providing me: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Progressbar.html and https://docs.python.org/2/library/ttk.html#index-0

The original code has been revamped to be GUI based, so here is my new code which has a problem of the ttk.Progressbar() being initialized with a chunk already missing before the start button is selected. Just to specify, when the start button is selected it needs to be held off for the delay period before even the first chunk is removed.

#import module for update frequency and gui. ttk for progressbar
import ttk
from Tkinter import *

#establish window
root = Tk()
E1 = Entry(root)
E2 = Entry(root)
E3 = Entry(root)
global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter

def captcha_health():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    try:
        health = float(E1.get())
    except ValueError:
        exit()
    Entry2()

def captcha_dps():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    try:
        dps = float(E2.get())
    except ValueError:
        exit()
    Entry3()

def captcha_spm():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    try:
        spm = float(E3.get())
    except ValueError:
        exit()
    estvar()

def Entry2():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    # user inputs how much damage each bullet does
    E2.grid(sticky='we')
    DB = Button(root, text='enter damage/shot', command=captcha_dps).grid()

def Entry3():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    # user inputs the fire rate of the weapon
    E3.grid(sticky='we')
    SB = Button(root, text='enter fire rate', command=captcha_spm).grid()

def estvar():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    # establishs counter for testing purposes
    counter = 0
    # from user inputs establish how many shots it takes to reduce health to or below zero
    if ((health / dps).is_integer()) is False:  # checks if the stk value will be a float
        stk = int(
        health / dps) + 1  # since stk value is a float go up to next whole number. 33dps doesn't kill in 3 shots.
    else:  # if stk value is an integer, establishes stk variable
        stk = health / dps

    delay_in_seconds = float(60 / spm)

    # establishes the time to kill in seconds, take one from stk to account for delay of gunfire
    ttki = ((stk - 1) * delay_in_seconds)
    guiest()

def DPS_Timer():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    counter += 1
    progre.step(-1*dps)
    if counter < stk:
        root.after(int(ttki*1000/stk), DPS_Timer)

def guiest():
    global health, dps, spm, ttki, stk, delay_in_seconds, progre, counter
    # establish GUI Button
    ttkLabel = Label(root, text='Time to kill: ' + str(ttki)).grid(sticky=W)
    stkLabel = Label(root, text='Shots to kill: ' + str(stk)).grid(sticky=W)
    hhLabel = Label(root, text='Health: ' + str(health)).grid(sticky=W)
    dpsLabel = Label(root, text='Damage/shot: ' + str(dps)).grid(sticky=W)
    spmLabel = Label(root, text='Fire rate: ' + str(spm)).grid(sticky=W)
    delayLabel = Label(root, text='Delay between shots: ' + str(delay_in_seconds)).grid(sticky=W)
    B1 = Button(root, text='start', command=DPS_Timer).grid(sticky='we')
    # establish progressbar
    progre = ttk.Progressbar(root, orient='horizontal', maximum=health, mode='determinate')
    progre.grid(sticky='we')
    progre.step(health-1)

#user inputs health
E1.grid(sticky='we')
HB = Button(root, text='enter health value', command=captcha_health).grid()

root.mainloop()

In order to set the health bar to 100%, we can just use

progre.step(health - 1)

right above of our DPS_Timer() function. From there, your function was mostly correct aside from the step value. We want the step to be negative, as we are decreasing the value of the health bar. Also, .stop() is useless unless we use .start() at some point, so we can delete that chunk of code entirely. Once counter is equal to stk, root.after() won't be called anyways, so we don't need the else statement. Here's what that gives us:

def DPS_Timer():
    global counter
    print(counter)

    if counter < stk:
        counter += 1
        progre.step(-1*health/stk)
        root.after(int(ttki*1000/stk), DPS_Timer)

Also, your progre.step() doesn't actually remove the amount of damage given by dps. We can fix this with

progre.step(health - 1)

def DPS_Timer():
    global counter
    print(counter)

    counter += 1
    progre.step(-1*dps)
    if counter < stk:
        root.after(int(ttki*100/stk), DPS_Timer)

(I moved the if statement so DPS_Timer isn't called an extra time)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM