0

I am currently trying to insert data from an external file which I have defined with the function "browse" as shown below, and these data to implement inside the Listboxes which I have divided in 3 parts, the data in the external file is simply some dates and numbers which I will show below. Could anyone help me figure out how do I implement data inside a Listbox as shown in the pictures below. P.S datesel() function is date selection to pick up dates manually after implementing the file inside of the listbox in which I am struggling to solve. Lastly Date Listboxes must be only integer as show in the picture 2.Data file link

enter image description here Current results in 1st picture

enter image description here Results that I need 2nd picture

enter image description here

Data file picture #3 that I implement through Button 1

from Tkinter import *

import tkFont , time
import ttk,csv,sys,os
import Tkinter,tkFileDialog


class Application(Frame):
    def __init__(self,root):
        Frame.__init__(self,root)
        self.root=root
        self.function1()
        self.function2()



    def function1(self):  #tell the machine we are having new widget
        self.frame1 = Frame(self.root)
        self.frame3 = Frame(self.root, bg="lightblue", borderwidth=2, relief=GROOVE)
        self.label1 = Label(self.frame1, text="Upload Acitivity File:")
        self.first_button = Button(self.frame1, text="Button 1",command=self.browse)
        #Start date selector
        self.Sdate = Label(self.frame3, text="Start Date(dd/mm/yy):  ")
        self.Slb = Listbox(self.frame3, width = 6,height = 8,selectmode='multiple',exportselection=0)
        self.Slb2 = Listbox(self.frame3, width=6, height=8,selectmode='multiple',exportselection=0)
        self.Slb3 = Listbox(self.frame3, width=6, height=8,selectmode='multiple',exportselection=0)


    def function2(self): # # tell the machine where our widget will be
        self.frame1.pack()
        self.frame3.pack()
        self.label1.pack(padx=5, pady=10, side=LEFT)
        self.first_button.pack(side=LEFT)
        #start and end date
        self.Sdate.grid(row =0,column=0)
        self.Slb.grid(row =0,column=1)
        self.Slb2.grid(row=0, column=2)
        self.Slb3.grid(row=0, column=3)


    def browse(self):
        file = tkFileDialog.askopenfile(mode='rb', title='Choose a file')
        self.data = csv.reader(file)
        self.datalist = []
        for row in self.data:
            if len(row) != 0:
                self.datalist = self.datalist + [row]
        self.datalist.sort()
        print self.datalist


    def datesel(self):

        # get selected line index
        self.index = self.Slb.curselection()[0]
        # get the line's text
        self.seltext = self.Slb.get(self.index)
        print self.seltext


        self.index2 = self.Slb2.curselection()[0]
        self.seltext2 = self.Slb2.get(self.index2)
        print self.seltext2
        self.index3 = self.Slb3.curselection()[0]
        self.seltext3 = self.Slb3.get(self.index3)
        print self.seltext3

        self.Slist = [self.seltext,self.seltext2,self.seltext3]
        self.Slist.sort(0,END)
        print self.Slist



def main():
    parent=Tk() # main frame
    parent.geometry('600x600+300+30')  #The height and width of the program
    parent.title('Motion Tracker')#assign the title of the program
    app = Application(parent)
    parent.mainloop()#keeps the program running for infinite amount of time
main()
5
  • Are the Listboxes supposed to reflect the data read from the file? Because the data you show has no correlation to figure 2 (what you say you need). That's probably why there is no answer yet. Commented Jul 21, 2017 at 1:29
  • Yes Listboxes must be filled with the dates from activity_file(dates file), in the format of (dd/mm/yy) and I know that it is possible its just that I can't figure it out, its been 5 hours I can't figure out this thing....Basically I need to know how to filter this data and after filtering it its easy to use them inside those Listboxes!@RonNorris Commented Jul 21, 2017 at 1:41
  • Have you tried inserting integers into a listbox using something like self.Slb.insert(0,1)? This will insert a 1 into the top position of the listbox. Parsing the data is straightforward: Try activity, date, distance = row.split(','). Then day, month, year = date.split('/') Commented Jul 21, 2017 at 1:45
  • I have inserted integers manually I have the whole code written there but I didn't post it here as I considered as too much, however the main point is to insert those values from the file and not manually.... to be honest I am so tired right and clueless, 4:51 AM @RonNorris Commented Jul 21, 2017 at 1:52
  • @RonNorris As for activity,distance I have finished it already in a different section below the window, the only thing I am left with its this Listbox that includes day,month,year Commented Jul 21, 2017 at 1:56

2 Answers 2

1

I don't understand why you want the day, month, and year in separate Listboxes, but anyway, here's some code that shows how to fill 3 Listboxes in the way your 2nd picture shows. I've reduced the code to the bare minimum, and I've hard-coded the filename into the class, but that's easy to fix.

import Tkinter as tk

class Application(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.pack()
        self.root = root
        self.do_listboxes()

    def do_listboxes(self):
        tk.Button(self, text="Get dates", command=self.fill_dates).pack()
        self.Slb1 = tk.Listbox(self, width=6, height=8, selectmode='multiple', exportselection=0)
        self.Slb2 = tk.Listbox(self, width=6, height=8, selectmode='multiple', exportselection=0)
        self.Slb3 = tk.Listbox(self, width=6, height=8, selectmode='multiple', exportselection=0)
        self.Slb1.pack(side=tk.LEFT)
        self.Slb2.pack(side=tk.LEFT)
        self.Slb3.pack(side=tk.LEFT)

    def fill_dates(self):
        fname = 'dkebz.txt'
        # Use sets to get rid of duplicated days, months, and years
        days, mons, yrs = set(), set(), set()
        with open(fname, 'r') as f:
            #Skip header
            next(f)
            for row in f:
                # Extract the date from the row
                date = row.split(',')[1]
                # Extract the day, month, and year from the date
                day, mon, yr = date.split('/')
                days.add(day)
                mons.add(mon)
                yrs.add(yr)

            # Populate the list boxes
            for day in sorted(days):
                self.Slb1.insert(tk.END, day)
            for mon in sorted(mons):
                self.Slb2.insert(tk.END, mon)
            for yr in sorted(yrs):
                self.Slb3.insert(tk.END, yr)

def main():
    parent = tk.Tk()
    parent.title('Motion Tracker')
    app = Application(parent)
    parent.mainloop()

main()

I've used import Tkinter as tk rather than from Tkinter import *. The "star" import dumps 175 Tkinter names into your namespace (in Python 3, 136 names), which is messy and can cause name collisions, especially if you do other "star" imports. Using import Tkinter as tk means that you have to prefix each Tkinter name with tk., so it involves a little more typing, but it makes the code easier to read because it's clear where each name comes from.

Sign up to request clarification or add additional context in comments.

Comments

1

For that, you just need to modify the browse method. I have hard-coded the data to reflect what your file image showed. So if the data is exactly what you provided, this works. If it works for you, uncomment the 2 lines I commented, and delete the self.data list definition I wrote.

def browse(self):
    file = tkFileDialog.askopenfile(title='Choose a file')
    try:
        with open(file, 'r') as reader:
            self.data = list(reader)
    except:
        raise
    self.datalist = []
    for row in self.data:
        if len(row) != 0 and not row.startswith('Activity'):
            self.datalist = self.datalist + [row]
            activity, date, steps = row.split(',')
            month, day, year = date.split('/')
            self.Slb.insert(END, month)
            self.Slb2.insert(END, day)
            self.Slb3.insert(END, year)

6 Comments

The code worked partially I need make some changes.Writing the data manually at the variable self.data is kinda inefficient so is there a way of parsing the data directly from the file and by writing them inside the list. Anyways thank you very much for your effort!!
@Unix I added the file retrieval part back into the answer.
TypeError: coercing to Unicode: need string or buffer, file found. the error is on the line 135, in browse with open(file, 'rb') as reader:, what could be the problem now@RonNorris
When you open with 'rb', reading input will be a bytes object, not string. So open with 'r' only.
You need to post your input file in the question -- not an image. The file format is suspect as though it has unicode characters in it somewhere. In other words, it may be a csv type file, but it probably has at least one special character in it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.