0

I have recently started using python and now I am trying to make a gui with tkinter. I'm using the latest version of PyCharm community edition. I need to make it appear like it does normally in PyCharm in a box and make it look more appealing and allowing inputs like text and clicks. Most of the tutorials are outdated and no longer work with PyCharm. It took me 10 minutes to find the proper import statement for tkinter itself. I need to make a text box where I can input the things as required by the code below. Like when it says press enter to lap I need to press enter to make it lap in the text box. Can someone just demonstrate that for one of the raw_inputs and then I can apply it for the rest? Thanks in advance.

Here is the code:

import time
laps=[0]

def lap():
    lapping = raw_input("lap? (press enter to lap) to stop type something first then press enter")
    if lapping == "":
        end()

    while lapping == "":
            break
            lap()

def end():
    end = time.time()
    elapsed = end - start
    laps[0]+=1
    print "%s seconds" % (elapsed)
    print "%s lap(s)" % (laps)
    lap()

starting = raw_input("start? (press enter to start)")
if starting == "":
    start = time.time()
    ending = raw_input("end? (press enter to end)")
    if ending == "":
        end()
  • You forgot to actually include a question – tobspr Apr 30 '16 at 05:54
  • The code looks badly indented even in the link (the content of the function `end`). I've tried to correct it and add that directly into your question, please check it, and in case it is the way you want it, delete the last sentence with the link. – quapka Apr 30 '16 at 06:36
  • @quapka Thanks a lot, i copied the code directly from PyCharm. – Archit Srivastava Apr 30 '16 at 09:50
  • @ArchitSrivastava When I post the code into soQ I do it basically two ways - 1) (I use SublimeText) in SublimeText I indent the whole code (`Ctrl + A, Tab, Ctrl + C`) and the paste it into the Q; 2) I copy it into the Q and select it all there and then click the `{}` for code formatting. – quapka Apr 30 '16 at 10:04
  • To your question: I am not using Tkinter, but after looking around a bit I could implement I little code with few buttons, which would handle the lapping mechanism and showing the lap times (can't do it right now, though, maybe I'll have time in like 2 hours from now). In the meantime [look at this answer](http://stackoverflow.com/a/7301250/2377489). – quapka Apr 30 '16 at 10:04
  • @quapka thanks, for both the link and your help! – Archit Srivastava Apr 30 '16 at 11:06
  • @quapka what type of gui will you use? – Archit Srivastava Apr 30 '16 at 11:35
  • I would use `tkinter`. – quapka Apr 30 '16 at 12:11
  • Sorry, I did not manage to get to it earlier. It was a bit harder than I thought, hopefully it wasn't total waste of time and would help you start your own development. :) – quapka Apr 30 '16 at 20:02

1 Answers1

0

Disclaimer: I used Tkinter only once before and don't have anymore experiences. However, I though I am capable of putting this code together. In the end it works, although I am not happy with many parts. Hopefully it might serve you as I starting point. But to be honest, searching google would give you much better and clearer starting examples. The code is also on my github.

import tkinter as tk
import time


class App(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        # boolean for checking, whether the stopwatch currently run
        self.running   = False
        # the starting time
        self.startTime = 0
        # StringVar so the text inside self.label is updated on change
        self.timeLabelText = tk.StringVar()
        self.label = tk.Label(textvariable=self.timeLabelText)
        # pack it in the frame
        self.label.pack()
        # similar code for button, added self._runButton when the button is clicked
        self.runButtonText = tk.StringVar()
        self.runButtonText.set("Run")
        self.runButton = tk.Button(textvariable=self.runButtonText,
                                   command=self.__runButton)
        self.runButton.pack()
        # array to hold the laps
        self.laps    = []
        self.lapButton = tk.Button(text="Lap",
                                   command=self.__lapButton)
        self.lapButton.pack()
        # bind Return with __lapButton function
        self.bind("<Return>", self.__lapButton)

    def __timelabel(self):
        # if running change the time each second
        if self.running:
            seconds = time.time() - self.startTime
            self.timeLabelText.set("%d:%02d:%02d" % seconds_to_time(seconds))
            self.after(1000, self.__timelabel)

    def __runButton(self):
        # if "was" running, set running to false and adjust label
        if self.running:
            self.running = False
            self.runButtonText.set("Run")
        # if "was not" running
        else:
            # get the time
            self.startTime = time.time()
            # change running to True
            self.running = True
            # start stopwatch immediately
            self.after(0, self.__timelabel)
            # change the text on the runButton
            self.runButtonText.set("Stop")
            # clear each lap from previous run
            for lap in self.laps:
                lap.pack_forget()
            # and empty it, maybe use while loop and pop
            self.laps = []

    def __lapButton(self, *args):

        if self.running:
            # get the time as str "HH:MM:SS"
            t = self.timeLabelText.get()
            t = time_to_seconds(t)
            # if there are previous laps
            if self.laps:
                # get their sum
                elapsed = sum([time_to_seconds(self.laps[x].cget("text")) for x in range(len(self.laps))])
                # substract that
                t       = t - elapsed
            t = seconds_to_time(t)
            t = ":".join([str(x) for x in t])
            # add new label with text
            self.laps.append(tk.Label(text=t))
            # pack all the label
            for lap in self.laps:
                lap.pack()

# methods for handling time
# probably it would be better to use some precoded method from 
# module time and datetime
def time_to_seconds(time):

    h, m, s = [int(x) for x in time.split(':')]
    return h*3600 + m*60 + s

def seconds_to_time(seconds):

    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    return h, m, s

if __name__ == '__main__':

    App().mainloop()
quapka
  • 2,799
  • 4
  • 21
  • 35
  • Ok thanks, I have figured out that _tkinter and Tkinter are different. I think thats why I messed up. Thanks A LOT for your help. – Archit Srivastava May 01 '16 at 03:52
  • Also, is there a way of printing the number of laps they have done? I looked around what your have done, and I understood most of what you have done. Its just that when you show the time, is there a way of also showing the laps that have been done? – Archit Srivastava May 01 '16 at 04:44
  • @architsrivastava Yes, it can be. There might be better ways, but I think it can be done changing only __lapButton function. I'll add that later:) – quapka May 01 '16 at 06:40
  • @ArchitSrivastava I've updated the code on github. You can also browse the file there and see the history, so you will explicitly see, what was added. – quapka May 01 '16 at 11:16
  • when i tried your code this error showed up Exception in Tkinter callback Traceback (most recent call last): File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py", line 1410, in __call__ return self.func(*args) File "/Users/mynamewashere/PycharmProjects/projectintro/gui for tihs.py", line 74, in __lapButton t = "{}. {}".format(len(self.laps)+ 1, t) ValueError: zero length field name in format – Archit Srivastava May 01 '16 at 12:12
  • I am using Python 3.5.1, this might be relevant problem, [see](http://stackoverflow.com/a/10054232/2377489). Try changing `t = "{}. {}".format(len(self.laps)+ 1, t)` to `t = "{0}. {1}".format(len(self.laps)+ 1, t)`. – quapka May 01 '16 at 12:14
  • Your welcome, in case this post answeres your question consider marking the _tick_ to the left of the post and give a vote up :) happy coding – quapka May 02 '16 at 10:06