so when I was trying o make a game the front page is good
Front page
but when I tried the game no image is shown. why? how can it get to fix it without changing the system order?
it always shows no image or just nothing in my other projects don't know why
a screen shot
here code:
from Tkinter import *
from PIL import Image,ImageTk
from Winsound import *
win = Tk()
win.config(bg="#e300ff")
win.geometry("950x600+160+60")
win.resizable(width = False, height = False)
def play_sound_play():
global playgame
PlaySound("SoundEffects\Coins.wav", SND_FILENAME)
playbtn.destroy()
win.config(bg="white")
playgame = True
game()
def printpos(event):
print(f"{plr_posx}")
def MoveLeft(event):
global plr_posx
if plr_posx == 311:
print("cant go into grass")
else:
plr_posx -= 150
plr.place(x=plr_posx,y=plr_posy)
def MoveRight(event):
global plr_posx
if plr_posx >= 610:
print("cant go into grass")
else:
plr_posx += 150
plr.place(x=plr_posx,y=plr_posy)
def game():
global plr
global plr_posx
global plr_posy
#road
road_img = ImageTk.PhotoImage(Image.open("texture\ymd.png"))
road = Label(win, image=road_img)
road.pack()
road.place(x=321,y=0)
#grass
grass_img = ImageTk.PhotoImage(Image.open("texture\grass.png"))
grass1 = Label(win, image=grass_img)
grass1.pack()
grass1.place(x=-2,y=0)
grass2 = Label(win, image=grass_img)
grass2.pack()
grass2.place(x=646,y=0)
#Plr pos
plr_posx=311
plr_posy=450
#Plr
plr_img = ImageTk.PhotoImage(Image.open("texture\Player.png"))
plr = Label(win, image=plr_img)
plr.pack()
plr.place(x=plr_posx,y=plr_posy)
if playgame == False:
print("2")
else:
print("1")
#controls
win.bind("<Left>",MoveLeft)
win.bind("<Right>",MoveRight)
win.bind("<p>",printpos)
def main():
global playbtn
#PlayBtn
play_btn = ImageTk.PhotoImage(Image.open("texture\play_btn.png"))
playbtn = Button(win, image=play_btn,bd=0,bg="#e300ff",activebackground='#e300ff', command=play_sound_play)
playbtn.pack()
playbtn.place(x=150,y=250)
win.mainloop()
main()
no error is shown
No Error
even after I close it
no error
This is a simple math game which is currently in progress. The loop starts off in mainGame() which then proceeds to mainMenu(). I am trying to create 2 frames; mframe and gframe in order to .destroy() the frames later on, essentially clearing the previous interface for the next one (similar to changing pages).
error:
Label(gframe, textvariable=self.question_var).pack() #gframe stands
for game frame NameError: name 'gframe' is not defined
from tkinter import *
from random import randint
root = Tk()
mframe = Frame(root).pack()
gframe = Frame(root).pack()
frame.pack()
start = True
class mainMenu:
def __init__(self):
gframe.destroy() #gets rid of previous interface
title = Label(mframe, text = "main menu").pack() #mfame stands for menu frame
class mainGame:
def __init__(self):
if start == False:
mframe.destroy() #gets rid of previous interface
#question
self.question_var = StringVar()
Label(gframe, textvariable=self.question_var).pack() #gframe stands for game frame
#answer
self.user_answer_var = StringVar()
entry = Entry(gframe, textvariable=self.user_answer_var)
entry.pack()
submit = Button(gframe, text = "submit", command = self.check_answer).pack()
#response output
self.response_var = StringVar()
self.count = 0
self.score = 0
Label(gframe, textvariable=self.response_var).pack()
#starts loop
self.ask_question()
root.mainloop()
def ask_question(self):
if self.count == 1:
self.endGame()
num1 = randint(1, 10)
num2 = randint(1, 10)
self.question_var.set("What is "+str(num1)+" + " +str(num2)+"?")
self.true_answer = num1 + num2
#print(self.true_answer) #testing purposes
def check_answer(self):
self.count += 1
user_answer = self.user_answer_var.get()
#print(user_answer) #testing purposes
if int(user_answer) == self.true_answer:
text = "Good job"
self.score += 1
else:
text = "Oh no"
self.response_var.set(text)
#clear answer for next loop
self.user_answer_var.set("")
self.ask_question()
def endGame(self):
print("endGame")
mainMenu()
mainGame()
As said in the comments above, the pack() method returns None. What you need to do is first create the two frames and assign them to variables, then pack them later. This way, the variables still point to the frame instances and not None.
You should change;
root = Tk()
mframe = Frame(root).pack()
gframe = Frame(root).pack()
frame.pack()
start = True
to;
root = Tk()
mframe = Frame(root)
gframe = Frame(root)
mframe.pack()
gframe.pack()
start = True
I write a pipeline for a lab, so I know it is impossible to insert a "console" in a GUI, so I made it with a Frame and I put label on it.
But the problem is, I am a beginner in threading, and I don't know how to use it to put my label into my frame after a function execution in a loop.
So this is my code (python 3.x) :
########
# IMPORTS #
########
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import *
from tkinter.messagebox import *
import os
import glob
from datetime import date, time, datetime
#########
# FUNCTION #
#########
def OneFile(path1,DB,path2,seq,seq2,typ,path3):
"""
This function is very long, take all the sequences of the input file and BLAST it to the Library DATABASE
path : path to the library databse
DB : library database name
path2 : path of the file with the query sequences
seq : name of the file with the query sequences append with a job ID
seq2 : name of the file with the query sequence
Typ : Nucleotide or Proteine
"""
from datetime import date, time, datetime
import subprocess
import platform
import time
OS = platform.system()
if OS == 'Linux' or OS == 'Darwin':
pathLibrary = path1+'/'
pathSequence = path2+'/'
pathFolder = path3+'/'
if OS == 'Windows':
pathLibrary = path1+'\\'
pathSequence = path2+'\\'
if typ not in [(1,1),(2,2),(1,2),(2,1)]:
showerror('Error : Missing Type !', "You do not choose your type\n(nucleotides or proteins)")
else:
library = DB
if os.path.isfile(pathLibrary+library) != True:
showerror('Error : Missing File !', "You must choose a Library Database file")
else:
if os.path.isfile(pathSequence+seq2) != True:
showerror('Error : Missing File !', "You must choose your sequence file")
else:
if typ == (1,1):
typ = "blastn"
if typ == (2,2):
typ = "blastp"
if typ == (1,2):
typ = "blastx"
if typ == (2,1):
typ = "tblastn"
if OS == 'Linux' or OS == 'Darwin':
t0 = time.time()
query = str(seq2)
blast = str(seq)+'_Blast.txt'
seqs = str(seq)+'_seqs.txt'
subprocess.call(typ+" -query "+pathSequence+query+" -db "+pathLibrary+library+" -evalue 1e-10 -out "+pathFolder+blast, shell=True)
subprocess.call("grep '\(Sbjct\|>\)' "+pathFolder+blast+" > "+pathFolder+seqs, shell=True)
t1 = time.time()
print('Job finish in '+str(round(t1-t0,2))+' seconds')
if OS == 'Windows':
t0 = time.time()
query = str(seq2)
blast = str(seq)+'_Blast.txt'
seqs = str(seq)+'_seqs.txt'
subprocess.call(typ+' -query '+pathSequence+query+' -db '+pathLibrary+library+' -evalue 1e-10 -out '+pathSequence+blast, shell=True)
print('Fichier n° '+str(1)+' '+str(seq2))
subprocess.Popen('findstr "Sbjct >" '+pathSequence+blast+' > '+pathSequence+seqs, shell=True)
t1 = time.time()
print('Job finish in '+str(round(t1-t0,2))+' seconds')
#######
# CLASS #
#######
class GraphicalUserInterface():
#principal application
def __init__(self):
#constructor
self.fen = Tk()
self.fen.title("Starch Enzyme Pipeline")
#first label
self.label1 = Label(self.fen, text="Folder with your set(s) : ")
self.label1.grid(row=0, columnspan=2, sticky="W")
#first button
self.browse1 = Button(self.fen)
self.browse1.config(text="Browse",command=self.folderPath)
self.browse1.grid(row=1,column=0, sticky="W")
#label to show the path
self.varLabel1 = StringVar()
self.pathLabel1 = Label(self.fen, textvariable=self.varLabel1, relief=SUNKEN)
self.pathLabel1.grid(row=1,column=1, sticky="EW")
#second title
self.label2 = Label(self.fen, text="Folder with your library database(s) ")
self.label2.grid(row=2,column = 0, columnspan=2 , sticky="W")
#second button
self.browse2 = Button(self.fen)
self.browse2.config(text="Browse",command=self.folderPath2)
self.browse2.grid(row=3,column=0, sticky="W")
#label to show the path for database
self.varLabel2 = StringVar()
self.pathLabel2 = Label(self.fen, textvariable=self.varLabel2, relief=SUNKEN)
self.pathLabel2.grid(row=3,column=1, sticky = "EW")
#Frame wrappe listBox and other
self.frameListBoxAll = Frame(self.fen)
self.frameListBoxAll.grid(row=6,columnspan=2)
#list box label
self.labListBox1 = Label(self.frameListBoxAll, text="Your sets :",padx=10)
self.labListBox1.grid(row=0,column=0)
self.labListBox2 = Label(self.frameListBoxAll, text="Your library database :",padx=10)
self.labListBox2.grid(row=0,column=1)
#frame with listbox1
self.frame1 = Frame(self.frameListBoxAll, bd=2, relief=SUNKEN)
self.frame1.grid(row=1,column=0)
#frame with listbox1
self.frame2 = Frame(self.frameListBoxAll, bd=2, relief=SUNKEN)
self.frame2.grid(row=1,column=1)
#scrollbar listbox1
self.scrollbar1 = Scrollbar(self.frame1)
self.scrollbar1.grid(row=0,column=1, sticky="NS")
self.scrollbar2 = Scrollbar(self.frame2)
self.scrollbar2.grid(row=0,column=3, sticky="NS")
self.scrollbar3 = Scrollbar(self.frame1, orient=HORIZONTAL)
self.scrollbar3.grid(row=1,column=0, sticky="WE")
self.scrollbar4 = Scrollbar(self.frame2, orient=HORIZONTAL)
self.scrollbar4.grid(row=1,column=2, sticky="WE")
#liste box
self.listeBox1 = Listbox(self.frame1, selectmode=EXTENDED, exportselection=0, yscrollcommand=self.scrollbar1.set, xscrollcommand=self.scrollbar3.set)
self.listeBox1.grid(row=0,column = 0)
self.scrollbar1.config(command=self.listeBox1.yview)
self.scrollbar3.config(command=self.listeBox1.xview)
#liste box2
self.listeBox2 = Listbox(self.frame2, selectmode=EXTENDED, exportselection=0, yscrollcommand=self.scrollbar2.set, xscrollcommand=self.scrollbar4.set)
self.listeBox2.grid(row=0,column = 2)
self.scrollbar2.config(command=self.listeBox2.yview)
self.scrollbar4.config(command=self.listeBox2.xview)
#radioboutton list box 1
self.var = IntVar()
for item in [1,2]:
if item == 1:
self.rb = Radiobutton(self.frameListBoxAll, text='Nucleotides',value=item,variable=self.var)
self.rb.grid(row=2, column=0)
if item == 2:
self.rb = Radiobutton(self.frameListBoxAll, text='Proteins',value=item,variable=self.var)
self.rb.grid(row=3, column=0)
#radioboutton list box 2
self.var2 = IntVar()
for item in [1,2]:
if item == 1:
self.rb2 = Radiobutton(self.frameListBoxAll, text='Nucleotides',value=item,variable=self.var2)
self.rb2.grid(row=2, column=1)
if item == 2:
self.rb2 = Radiobutton(self.frameListBoxAll, text='Proteins',value=item,variable=self.var2)
self.rb2.grid(row=3, column=1)
#variables
self.path1 = str()
self.path2 = str()
self.path3 = str()
#RUN Buttun
self.runbutton = Button(self.fen, text="RUN",command=self.start_foo_thread).grid(row=7,column=0,columnspan=2)
#FRAME CONSOLE
self.console = Frame(self.fen)
self.console.config(relief=SUNKEN, bg="black", height=200, width=400)
self.console.grid(row=8, columnspan=10)
self.console.grid_propagate(False) #to block the size of the frame
#QUIT BUTTON
self.quitButton = Button(self.fen)
self.quitButton.config(text="QUIT", command=self.fen.destroy)
self.quitButton.grid(row=100,column=0)
def folderPath(self):
path = askdirectory(title='Choose your set folder')
self.varLabel1.set(path)
self.listeBox1.delete(0, END)
for filename in sorted(glob.glob(path+'/*')):
if os.path.isfile(filename):
#stockage of path
self.path1 = os.path.split(filename)[0]
name = os.path.split(filename)[1]
self.listeBox1.insert(END, name)
def folderPath2(self):
path = askdirectory(title="Choose your library database folder")
self.varLabel2.set(path)
self.listeBox2.delete(0, END)
for filename in sorted(glob.glob(path+'/*')):
if os.path.isfile(filename):
#stockage of path
self.path2 = os.path.split(filename)[0]
name = os.path.split(filename)[1]
self.listeBox2.insert(END, name)
def run(self):
self.fen.mainloop()
def createJobName():
job = str(datetime.now())
job = job.replace(" ","-")
return job
def typeNP(self):
liste = []
#selection of query files
valListBox1 = [self.listeBox1.get(idx) for idx in self.listeBox1.curselection()]
#selection of database file
valListBox2 = [self.listeBox2.get(idx) for idx in self.listeBox2.curselection()]
#selection of sequence type
typ = (self.var.get(),self.var2.get())
# loop
for i in range(len(valListBox2)):
job = GraphicalUserInterface.createJobName()
path1 = self.path2
path2 = self.path1
DB = valListBox2[i]
path3 = os.getcwd()+"/"+DB+job
if os.path.isdir(DB+job) == True:
showwarning('Warning', "The folder already exist \n or they are no folder name !\nChange or get the folder name")
else:
os.mkdir(DB+job)
for filename in valListBox1:
seq = filename+job
seq2 = filename
#stock data for OneFile function
liste.append([path1,DB,path2,seq,seq2,typ,path3])
return liste
def start_foo_thread(self):
liste = self.typeNP()
for i in range(len(liste)):
global foo_thread
import threading
print('Fichier n°'+str(i+1)+' '+str(liste[i][4]))
stringLabel = Label(self.console,text='Fichier n°'+str(i+1)+' '+str(liste[i][4]),bg='black', fg='white')
stringLabel.grid(row=i,sticky="W")
foo_thread = threading.Thread(target=OneFile(liste[i][0],liste[i][1],liste[i][2],liste[i][3],liste[i][4],liste[i][5],liste[i][6]))
foo_thread.daemon = True
foo_thread.start()
#########
# AUTORUN #
#########
if __name__ == '__main__':
app = GraphicalUserInterface()
app.run()
The problem is when the loop began in:
def start_foo_thread(self):
liste = self.typeNP()
for i in range(len(liste)):
With the print function, I see the function run, but the label does not go in the frame when the iteration finishes. When the loops are completed, I see my label in the frame.
What is the correct code to have my label in my frame at the same time my function runs in my loop?
You sometimes have to manually update the widget. You have posted too much code to wade through, so this simple example should show the problem. Run as is, the labels don't show up until the function returns. Run with update_idletasks() uncommented does what I think you want. Also note that the program stops until the call to subprocess returns.
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
else:
import tkinter as tk ## Python 3.x
class GraphicalUserInterface():
def __init__(self):
#constructor
self.fen = tk.Tk()
self.fen.title("Starch Enzyme Pipeline")
self.console=tk.Frame(self.fen)
self.console.grid()
self.liste=["one", "two", "three"]
tk.Button(self.fen, text="Exit", command=self.fen.quit).grid(row=1)
self.start_foo_thread()
self.fen.mainloop()
def start_foo_thread(self):
for ctr in range(len(self.liste)):
lit='Fichier n %s' % (ctr)
print(lit)
stringLabel = tk.Label(self.console, text=lit,
bg='black', fg='white')
stringLabel.grid(row=ctr,sticky="W")
##self.console.update_idletasks()
print("Waiting 2 seconds")
self.fen.after(2000) ## wait 2 seconds to show effect
print("Return from function")
if __name__ == '__main__':
app = GraphicalUserInterface()
I'm new to tkinter and am running python 3.4.2 with Tk version 8.5.17 using IDLE 3.4.2 under Yosemite. This is a modified demo from Liang's book Introduction to Programming Using Python 3. I was expecting the following code to display four buttons:
from tkinter import *
class ButtonsDemo:
def __init__(self):
window = Tk()
window.title("Buttons Demo")
frame0 = Frame(window)
frame0.pack()
plusImage = PhotoImage(file = "image/plus.gif")
minusImage = PhotoImage(file = "image/minus.gif")
timesImage = PhotoImage(file = "image/times.gif")
divideImage = PhotoImage(file = "image/divide.gif")
Button(frame0, image = plusImage, command =
self.add).grid(row = 1, column = 1, sticky = W)
Button(frame0, image = minusImage, command =
self.subtract).grid(row = 1, column =2)
Button(frame0, image = timesImage, command =
self.multiply).grid(row = 1, column = 3)
Button(frame0, image = divideImage, command =
self.divide).grid(row = 1, column = 4)
window.mainloop()
def add(self):
print("add pressed")
def subtract(self):
print("subtract pressed")
def multiply(self):
print("multiply pressed")
def divide(self):
print("divide pressed")
ButtonsDemo()
When I run the code, only the first three buttons are displayed. The button with divideImage on it does not appear.
If I click where the divide button should be, I do get the message "divide pressed". It's as if the button is there, but it's invisible.
I see the same behavior running the program from the command line
instead of from IDLE.
There's nothing wrong with the gif. If I use divide.gif for plusImage, I can see divide.gif in the first button position. Also, when I put text = "Divide" on the divide button instead of image = DivideImage, the button becomes visible.
Why is the divide button invisible when I use an image? How can I fix it?
EDIT: Here's the code with everything moved to the main program. I think this should have fixed a garbage collection problem if there were one. Is this correct?
from tkinter import *
def add():
print("add pressed")
def subtract():
print("subtract pressed")
def multiply():
print("multiply pressed")
def divide():
print("divide pressed")
window = Tk()
window.title("Buttons Demo")
frame0 = Frame(window)
frame0.pack()
plusImage = PhotoImage(file = "image/plus.gif")
minusImage = PhotoImage(file = "image/minus.gif")
timesImage = PhotoImage(file = "image/times.gif")
divideImage = PhotoImage(file = "image/divide.gif")
Button(frame0, image = plusImage, command =
add).grid(row = 0, column = 0, sticky = W)
Button(frame0, image = minusImage, command =
subtract).grid(row = 0, column = 1)
Button(frame0, image = timesImage, command =
multiply).grid(row = 0, column = 2)
Button(frame0, image = divideImage, command =
divide).grid(row = 0, column = 3)
window.mainloop()
This is the code for the function I'm using to start the main part of the program, however I want some sort of loop or something which creates ten questions, but waits for an input from the Entry box before moving onto the next question.
Any ideas?
def StartGame():
root = Tk()
root.title("Maths Quiz - Trigonometry and Pythagoras' Theorem | Start The Game")
root.geometry("640x480")
root.configure(background = "gray92")
global AnswerEntry
TotScore = 0
Count = 0
AnswerReply = None
WorkingArea = Text(root, width = 70, height = 10, wrap = WORD).place(x = 38, y = 100)
n = GetRandomNumber()
Angle,Opposite,Adjacent,Hypotenuse = Triangle()
Question,RealAnswer = QuestionLibrary(Opposite,Adjacent,Hypotenuse,Angle,n)
AskQuestion = Label(root, text = Question, wraplength = 560).place(x = 48, y = 300)
PauseButton = ttk.Button(root, text = "Pause").place(x = 380, y = 10)
HelpButton = ttk.Button(root, text = "Help", command = helpbutton_click).place(x = 460, y = 10)
QuitButton = ttk.Button(root, text = "Quit", command = root.destroy).place(x = 540, y = 10)
AnswerEntry = Entry(root)
AnswerEntry.place(x = 252, y = 375)
SubmitButton = ttk.Button(root, text = "Submit", command = submit_answer).place(x = 276, y = 400)
TotScore,AnswerReply = IsAnswerCorrect(Answer,RealAnswer)
ScoreLabel = ttk.Label(root, text = TotScore).place(x = 38, y = 10)
AnswerReplyLabel = ttk.Label(root, text = AnswerReply).place(x = 295, y = 440)
root.mainloop()
I want the loop to start after the AnswerReply = None
You don't want a loop. The only really important loop inside a GUI should be the mainloop(), handling signal and executing callbacks.
Example:
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
class QAGame(Tk.Tk):
def __init__(self, questions, answers, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Questions and answers game")
self._setup_gui()
self._questions = questions[:]
self._answers = answers
self._show_next_question()
def _setup_gui(self):
self._label_value = Tk.StringVar()
self._label = Tk.Label(textvariable=self._label_value)
self._label.pack()
self._entry_value = Tk.StringVar()
self._entry = Tk.Entry(textvariable=self._entry_value)
self._entry.pack()
self._button = Tk.Button(text="Next", command=self._move_next)
self._button.pack()
def _show_next_question(self):
q = self._questions.pop(0)
self._label_value.set(str(q))
def _move_next(self):
self._read_answer()
if len(self._questions) > 0:
self._show_next_question()
self._entry_value.set("")
else:
self.quit()
self.destroy()
def _read_answer(self):
answer = self._entry_value.get()
self._answers.append(answer)
def _button_classification_callback(self, args, class_idx):
self._classification_callback(args, self._classes[class_idx])
self.classify_next_plot()
if __name__ == "__main__":
questions = ["How old are you?",
"What is your name?"]
answers = []
root = QAGame(questions, answers)
root.mainloop()
for q,a in zip(questions, answers):
print "%s\n>>> %s" % (q, a)
We only have a Label, an Entry and a Button (I did not care about layout!, just pack()).
Attached to the button is a command (aka callback). When the button is pressed, the answer is read and the new question is assigned to the label.
Usage of this class is understandable from the example in the `if name == "main" block. Please note: the answers-list is filled in place, the questions-list is kept unchanged.
I don't know Tk, but is there no any signals of input text changed? There should be for sure. Just check if this signal occured and then move onto new question, because it means that someone typed something in input box.