Python Forum
Thread Rating:
  • 2 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Feedback and help
#1
Hi Guys,
I'm new in the python coding scene and began learning Tkinter yesterday. I wrote a little dice rolling programm, based on a tkinter tutorial series(https://pythonprogramming.net/python-3-t...-tutorial/).
I know it's not the most intelligent program you can write, but I just want to learn.

from tkinter import *
from random import randint
from PIL import Image, ImageTk

class Window(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)

        self.master = master

        self.init_window()

    def init_window(self):
        self.master.title("Rolling the dice")
        
        self.pack(fill=BOTH, expand=1)
            
        #quitButton = Button(self, text= "quit", command=self.client_exit)
        #quitButton.place(x=0, y=0)

        #making the roll button
        rollButton = Button(self, text= "Roll the dice", command = self.roll())
        rollButton.place(x = 180, y = 270)

        #making the menu
        menu = Menu(self.master)
        self.master.config(menu=menu)

        #making the file cascade in menu with button exit
        file = Menu(menu)
        file.add_command(label="Exit", command=self.client_exit)
        menu.add_cascade(label="File", menu=file)

        edit = Menu(menu)
        edit.add_command(label="Undo")
        edit.add_command(label="Roll the dice", command=self.roll())
        menu.add_cascade(label= "Edit", menu=edit)
        


    def roll(self):
        randomNumber = randint(1, 6)

        if randomNumber == 1:
            load = Image.open("dices_1.png")
            render = ImageTk.PhotoImage(load)
            img = Label(self, textvariable=randomNumber)
            img.image = render
            img.place(x=0, y=0)



        elif randomNumber == 2:
            load = Image.open("dices_2.png")
            render = ImageTk.PhotoImage(load)

            img = Label(self, image=render)
            img.image = render
            img.place(x=0, y=0)

        elif randomNumber == 3:
            load = Image.open("dices_3.png")
            render = ImageTk.PhotoImage(load)

            img = Label(self, image=render)
            img.image = render
            img.place(x=0, y=0)

        elif randomNumber == 4:
            load = Image.open("dices_4.png")
            render = ImageTk.PhotoImage(load)

            img = Label(self, image=render)
            img.image = render
            img.place(x=0, y=0)


        elif randomNumber == 5:
            load = Image.open("dices_5.png")
            render = ImageTk.PhotoImage(load)

            img = Label(self, image=render)
            img.image = render
            img.place(x=0, y=0)
            
        elif randomNumber == 6:
            load = Image.open("dices_6.png")
            render = ImageTk.PhotoImage(load)

            img = Label(self, image=render)
            img.image = render
            img.place(x=0, y=0)



        
    def client_exit(self):
        exit()

    

root = Tk()
root.geometry("400x300")

app = Window(root)

root.mainloop
First I want to ask some feedback about the structure of the code. Is it as bad as I think it is?
The pictures are in my google drive folder(https://drive.google.com/open?id=1jrdAb3...NjAuO77tJO).
But my main problem is that it does only show the pictures((https://drive.google.com/open?id=1jrdAb3...NjAuO77tJO)) once, after you click the button. What do I have to change?

Thank you,

tomX
Reply
#2
I'd change roll method to:

    def roll(self):
        randomNumber = randint(1, 6)
       
        # If using python 3.6 or newer:
        png_name = f'dices_{rnum}.png'
        # Otherwise:
        # png_name = 'dices_{}.png'.format(rnum)

        load = Image.open(png_name)
        render = ImageTk.PhotoImage(load)
        img = Label(self, textvariable=randomNumber)
        img.image = render
        img.place(x=0, y=0)
Reply
#3
Thank you very much!
I edited the code and came to this result:
from tkinter import *
from random import randint
from PIL import Image, ImageTk

class Window(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)

        self.master = master

        self.init_window()

    def init_window(self):
        self.master.title("Rolling the dice")
        
        self.pack(fill=BOTH, expand=1)
            
        #quitButton = Button(self, text= "quit", command=self.client_exit)
        #quitButton.place(x=0, y=0)

        #making the roll button
        rollButton = Button(self, text= "Roll the dice", command = self.roll())
        rollButton.pack(side=BOTTOM)

        #making the menu
        menu = Menu(self.master)
        self.master.config(menu=menu)

        #making the file cascade in menu with button exit
        file = Menu(menu)
        file.add_command(label="Exit", command=self.client_exit)
        menu.add_cascade(label="File", menu=file)

        edit = Menu(menu)
        edit.add_command(label="Undo")
        edit.add_command(label="Show Image", command=self.showImg)
        edit.add_command(label="Roll the dice", command=self.roll())
        menu.add_cascade(label= "Edit", menu=edit)
        
        
    def showImg(self):
        load = Image.open("pic.jpg")
        render = ImageTk.PhotoImage(load)

        # labels can be text or images
        img = Label(self, image=render)
        img.image = render
        img.place(x=0, y=0)

    def roll(self):
        randomNumber = str(randint(1, 6))
        
        # If using python 3.6 or newer:
        #png_name = f'dices_{randomNumber}.png'
        #Otherwise:
        png_name = 'dices_'+ randomNumber +'.png'
 
        load = Image.open(png_name)
        render = ImageTk.PhotoImage(load)
        img = Label(self, image=render)
        img.image = render
        img.pack(side=TOP)
        
    def client_exit(self):
        exit()

    

root = Tk()
root.geometry("400x300")

app = Window(root)

root.mainloop
The problem is still that if I run it I can't refresh the image, when I click on the Button.
And at the beginning there are two pictures shown. Why?
Reply
#4
Please post your pic.jpg and any other images so I can run
png_name = 'dices_'+ randomNumber +'.png'
The format method that I showed is a better choice, and f-string better yet.
using + is the old python 2 method.
Reply
#5
(Dec-28-2018, 06:13 PM)Larz60+ Wrote: Please post your pic.jpg and any other images so I can run
The pictures are in my google drive folder:

usp=sharinghttps://drive.google.com/drive/folders/1...sp=sharing
Reply
#6
Got it. will take a look tonight
Reply
#7
Quote:Got it. will take a look tonight
How is it going?
Reply
#8
I modified a couple of items, having issues just getting project to run.
What version of python are you using?

from tkinter import *
from random import randint
from PIL import Image, ImageTk
import os

 
class Window(Frame):
    def __init__(self, master = None):
        # make sure in src directory
        os.chdir(os.path.abspath(os.path.dirname(__file__)))

        Frame.__init__(self, master)
 
        self.master = master
 
        self.init_window()
 
    def init_window(self):
        self.master.title("Rolling the dice")
         
        self.pack(fill=BOTH, expand=1)
             
        #quitButton = Button(self, text= "quit", command=self.client_exit)
        #quitButton.place(x=0, y=0)
 
        #making the roll button
        rollButton = Button(self, text= "Roll the dice", command = self.roll())
        rollButton.pack(side=BOTTOM)
 
        #making the menu
        menu = Menu(self.master)
        self.master.config(menu=menu)
 
        #making the file cascade in menu with button exit
        file = Menu(menu)
        file.add_command(label="Exit", command=self.client_exit)
        menu.add_cascade(label="File", menu=file)
 
        edit = Menu(menu)
        edit.add_command(label="Undo")
        edit.add_command(label="Show Image", command=self.showImg)
        edit.add_command(label="Roll the dice", command=self.roll())
        menu.add_cascade(label= "Edit", menu=edit)
         
         
    def showImg(self):
        load = Image.open("pic.jpg")
        render = ImageTk.PhotoImage(load)
 
        # labels can be text or images
        img = Label(self, image=render)
        img.image = render
        img.place(x=0, y=0)
 
    def roll(self):
        randomNumber = str(randint(1, 6))
         
        # If using python 3.6 or newer:
        #png_name = f'dices_{randomNumber}.png'
        #Otherwise:
        png_name = 'dices_{}.png'.format(randomNumber)
  
        load = Image.open(png_name)
        render = ImageTk.PhotoImage(load)
        img = Label(self, image=render)
        img.image = render
        img.pack(side=TOP)
         
    def client_exit(self):
        exit()

def main():    
    root = Tk()
    root.geometry("400x300")

    app = Window(root)    
    root.mainloop

if __name__ == '__main__':
    main()
Reply
#9
(Dec-30-2018, 10:02 AM)Larz60+ Wrote: I modified a couple of items, having issues just getting project to run.
What version of python are you using?


I'm using Python 3.7.2.

A question: How is this...
def main():    
    root = Tk()
    root.geometry("400x300")
 
    app = Window(root)    
    root.mainloop
 
if __name__ == '__main__':
    main()
... better than only this?
root = Tk()
root.geometry("400x300")
 
app = Window(root)
 
root.mainloop
And why have you put this:
 # make sure in src directory
        os.chdir(os.path.abspath(os.path.dirname(__file__)))
Thank you very much for your help!
Reply
#10
using
if __name__ == '__main__':
allows you to to be able to run the program using what's in main from command line,
but not running if the module is imported into another program. It's a good habit to get into as it encourages code re-use

os.chdir(os.path.abspath(os.path.dirname(__file__)))
is something that I always put in my code because I run everything in a virtual environment.
It allows me to run code from a different directory (other than source code directory) by assuring that the code always knows the starting point for any relative directory operations, of which I use a lot.
In this instance since for me I will remove code after this thread is finished, I keep the image files in with the source code. Normally I'd keep them separate.
Now I can run the code (using VSCode) from the 'root' directory of my virtual environment and find image files in their proper place.
It's not always needed, but is a simple step to get a firm grip on my directory's relative paths (especially true when using pathlib paths, like homepath = Path('.')
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020