Counting characters, digits, spaces and newlines in the loaded file I wrote an application that loads a file after pressing button and counts characters, digits, spaces and newlines in the loaded file. This application is written in Python language using tkinter library and OOP programming paradigm.

4programmers.py:

# -*- coding: utf-8 -*-
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog

class GUI:
    def __init__(self, root):
        self.root = root
        self.filePath = StringVar()
        self.filePath.set("File not loaded")
        self.charLength = StringVar()
        self.charLength.set(0)
        self.digitsLength = StringVar()
        self.digitsLength.set(0)
        self.spacesLength = StringVar()
        self.spacesLength.set(0)
        self.entersLength = StringVar()
        self.entersLength.set(0)

        root.title("A program that counts characters, digits, spaces and newlines in the given file.")

        topFrame1 = Frame(root)
        topFrame1.pack( side = TOP )
        Label(topFrame1, text="Chars count: ").pack( side = LEFT )
        lblCharLength = Label(topFrame1, textvariable=self.charLength)
        lblCharLength.pack( side = RIGHT )

        topFrame2 = Frame(root)
        topFrame2.pack( side = TOP )
        Label(topFrame2, text="Digits count: ").pack( side = LEFT )
        lblDigitsLength = Label(topFrame2, textvariable=self.digitsLength)
        lblDigitsLength.pack( side = RIGHT )

        topFrame3 = Frame(root)
        topFrame3.pack( side = TOP )
        Label(topFrame3, text="Spaces count: ").pack( side = LEFT )
        lblSpacesLength = Label(topFrame3, textvariable=self.spacesLength)
        lblSpacesLength.pack( side = RIGHT )

        topFrame4 = Frame(root)
        topFrame4.pack( side = TOP )
        Label(topFrame4, text="Newlines count: ").pack( side = LEFT )
        lblEntersLength = Label(topFrame4, textvariable=self.entersLength)
        lblEntersLength.pack( side = RIGHT )

        bottomFrame = Frame(root)
        bottomFrame.pack( side = BOTTOM )

        lblFileName = Label(bottomFrame, textvariable=self.filePath)
        lblFileName.pack( side = LEFT )

        btnReadFile = Button(
                bottomFrame,
                text="Load a file",
                fg="black",
                command=self.importFile)
        btnReadFile.pack( side = RIGHT )

    def importFile(self):
        self.filePath.set(tkFileDialog.askopenfilename())

        s = open(self.filePath.get()).read()
        self.charLength.set(len(s))
        self.digitsLength.set(sum(c.isdigit() for c in s))
        self.spacesLength.set(sum(c.isspace() for c in s))
        self.entersLength.set(sum(c == "\n" for c in s))
        self.root.update()

root = Tk()
gui = GUI(root)
root.mainloop()
Don't use wildcard imports

PEP8 says that wildcard imports should be avoided. Instead, I recommend you import tkinter like this:

import Tkinter as tk


This means that everywhere you use a tkinter class or constant you need to prefix it with tk.. This will make your program a bit easier to read and understand, especially if you eventually choose to import widgets from ttk which provides many classes with the same name as tkinter classes. 

Group layout commands together

You have calls to pack scattered throughout your code, making it difficult to visualize how things are laid out. I strongly recommend grouping your layout code based on parent (ie: call pack on all children that share the same parent)

For example:

topFrame1 = Frame(root)
lbl = Label(topFrame1, text="Chars count: ")
lblCharLength = Label(topFrame1, textvariable=self.charLength)

# pack all children of topFrame1 together
lbl.pack( side = LEFT )
lblCharLength.pack( side = RIGHT )

lbl = Label(topFrame2, text="Digits count: ")
lblDigitsLength = Label(topFrame2, textvariable=self.digitsLength)

# pack all children of topFrame2 together
lbl.pack( side = LEFT )
lblDigitsLength.pack( side = RIGHT )

...

# pack all of the children of root together
topFrame1.pack( side = TOP )
topFrame2.pack( side = TOP )
topFrame3.pack( side = TOP )
topFrame4.pack( side = TOP )
bottomFrame.pack( side = BOTTOM )


You don't need StringVar

You don't need to use StringVar in your code. The way you are using it means you have more objects, but these objects don't give you any added benefits. Thus, it makes your code more complex than it needs to be.

If you need to change a label at runtime, you can keep a reference and then use the configure method to directly change the label.

self.lblCharLength = Label(topFrame1, textvariable=self.charLength)
...
self.lblCharLength.configure(text=len(s))


If you choose to use them, I recommend setting the value at the time  you create them, which will cut down on the total lines of code:

self.filePath = StringVar("File not loaded")
self.charLength = StringVar(value=0)
self.digitsLength = StringVar(value=0)
self.spacesLength = StringVar(value=0)
self.entersLength = StringVar(value=0)


Use with to open and read a file

with makes it easy to write code that is wrapped by other code. In this case you want to do an open, read some code, and then do a close. 

Note: you should also verify that the user picked a path. As written, if the user presses cancel, self.filePath will be empty and your code will throw an error.

Also, when you try to cram two or more function calls into a single statement it can make the code harder to debug. By using intermediate variables it makes it easier to pause your program and examine the state. 

For example:

if filepath:
    self.filePath.set(filepath)   # if using StringVar
    # self.filePath.configure(text=filepath)   # if not using StringVar

    with open(filepath, "r") as f:
        s = f.read()
    ...


Avoid calling update

At the end of your function importFile you call self.root.update. That is completely superfluous. The screen will update as soon as the function returns.