changing entry to float - python

from tkinter import *
pencere = Tk() #Pencereyi Oluşturyor
def Ekmek(event):
print(0.6*x)
#Here i am trying to calcute the carbohydrate for diabetes
#1 gram of bread is 0.6 carbohydrate and i am trying to calculate the gram user enters
def Patates(event):
print(0.16666666666666666)
gramy = Label(text = "Yemeğin Gramını Girin:",fg = "green",bg = "black")
gram = Entry(fg = "green",bg = "black")
x = gram.get()
#In this part i want to change the "x" to a
#float value but it gives error.How can i fix it ?
ekmek = Button(text="Ekmek",fg="orange",bg = "black")
ekmek.bind("<Button-1>",Ekmek)
patates = Button(text="Patates",fg="orange",bg = "black")
patates.bind("<Button-1>",Patates)
makarna = Button(text="Makarna",fg="orange",bg = "black")
pilav = Button(text="Pilav",fg="orange",bg = "black")
gramy.grid(row=0,column=1)
gram.grid(row =0,column =2)
ekmek.grid(row =1,column = 0)
patates.grid(row =1,column = 1)
makarna.grid(row = 1,column = 2)
pilav.grid(row = 2,column = 0)
pencere.mainloop() #Pencerenin Çarpıya

Your problem code is very problematic because 'x' will always be "" (empty string) since you placed it directly under its creation not giving any time for the user to enter. And as you know, "" can not be floated.
This is your problem code:
gram = Entry(fg = "green",bg = "black")
x = gram.get()
You should place gram.get here:
def Ekmek(event):
x = gram.get()
x=float(x.split('gram')[0])
print(0.6*x)
This will retrieve x after the user pressed the button.
Another method, is that you can use a StringVar.

Related

My python tkinter buttons are updating too quickly after the wrong comparison is made

I'm trying to make a memory game for fun and as a learning experience, and I've run into the issue where even with something like time.sleep(.5) I still can't get buttons to update correctly with a delay. In fact the second button seems to update to hidden as it's about to show the proper image. I'm assuming the issue lies somewhere in the buttonClicked() function.
I'm trying to figure out how I can make it show one button, then the second, then wait half a second and hide both. And if someone understands why this is happening or where I could look into the issue and read up on my own, that would be helpful.
Thanks.
from re import A
import time
import tkinter as tk
from tkinter import *
from typing_extensions import Self
from PIL import Image, ImageTk
import glob
import os, os.path
import numpy as np
from sqlalchemy import null
#resize images and button
imgButtonWidth = 100
imgButtonHeight = 100
imgButtonSize = (imgButtonWidth,imgButtonHeight)
#Set the height and width of the game by number of items.
width = 6
height = 6
#buttons = [[Button]*width]*height
#Total number of items 36 (0-35)
count = width*height-1
buttonList = []
#Will be a 2d array of [button, id]
answersList = []
clickedCount = 0
imgs = []
hiddenImg = null
# Create frame, set default size of frame and background color.
root = Tk()
root.title('Memory Game')
root.geometry(str(imgButtonWidth * (width+1)) + "x" + str(imgButtonHeight * (height+1)))
root.config(bg='darkblue')
frame = Frame(root, bg='darkblue')
# Fetch images from location and create a list of Image objects, then return.
def getImages():
imgs = []
path = "/home/paul/Programming/Python/MyMiniProjects/Mid/MemoryGame/"
valid_images = [".jpg",".gif",".png",".tga"]
for f in os.listdir(path):
ext = os.path.splitext(f)[1]
if ext.lower() not in valid_images:
continue
imgs.append([Image.open(os.path.join(path,f)).resize(imgButtonSize), f])
return imgs + imgs
#Shuffle images for the game
imgs = getImages()
random.shuffle(imgs)
#Simple image to cover the tiles
hiddenImg = ImageTk.PhotoImage(Image.new('RGB', (imgButtonWidth, imgButtonHeight), (0,0,105)))
#Disable buttons after a match
def disable():
global clickedCount, answersList
clickedCount = 0
for a in answersList:
a[0]["state"] = "disabled"
a[0]["bg"] = "green"
answersList = []
#Hide buttons again
def hide():
global clickedCount, answersList
clickedCount = 0
for a in answersList:
#a[0].config(image = hiddenImg)
a[0]["image"] = hiddenImg
a[0]["state"] = "normal"
a[0]["bg"] = "white"
answersList = []
def wrong():
for a in answersList:
a[0]["bg"] = "red"
def buttonClicked(picture, id, button):
global clickedCount, answersList
print(clickedCount, len(answersList))
#print(button.image, "1", hiddenImg, picture)
if button.image is hiddenImg and clickedCount < 2:
button["image"] = picture
button["state"] = "disabled"
clickedCount += 1
answersList.append([button, id])
if len(answersList) == 2:
#Check id but make sure it's not the same button pressed twice
if answersList[0][1] is answersList[1][1]:#and answersList[0][0] is not answersList[1][0]:
disable()
else:
wrong()
hide()
#Create the actual buttons with their respective image
for h in range(height): #print(buttons[w][::],"\n")
newList = []
for w in range(width):
tempImage = imgs.pop(count)
picture = ImageTk.PhotoImage(tempImage[0])
id = tempImage[1]
button = Button(frame, image=hiddenImg, state=NORMAL, height=imgButtonHeight, width=imgButtonWidth)
#Need to split this up because of how python handles closures
button["command"] = lambda pic_temp=picture, id_temp=id, button_temp = button: buttonClicked(pic_temp, id_temp, button_temp)
button.image = hiddenImg
#buttons[w][h].name = str(w + h)
#buttons[w][h].grid(row=w, column=h, ipadx=random.randint(0,40), ipady=random.randint(0,40), padx=random.randint(0,5), pady=random.randint(0,5))
button.grid(row=h, column=w, padx=1, pady=1)
#Button(frame, image=picture).grid(row=w, column=h, ipadx=random.randint(0,40), ipady=random.randint(0,40), padx=random.randint(0,5), pady=random.randint(0,5))
count -= 1
# buttonList.append(buttons[h][w])
newList.append(button)
buttonList.append(newList)
# for y in range(height):
# for x in range(width):
# print(ButtonList[y][x])
# print("")
frame.pack(expand=True)
root.mainloop()```

python - how to go to next image in slideshow using tkinter gui

i'm trying to make a photo slideshow program. it isn't working as i want to go to the next photo in the list using the self.counter variable, but the value of self.counter is going back to 0 as it forgets the fact that i changed the value. i didn't think i could use configure as then the buttons to go to the next image wouldn't work either.
i hope you can help :) much appreciated.
from tkinter import *
class SlideShowGUI:
def __init__(self, parent, counter = 0):
self.counter = counter
self.images_list = ["smiley.png", "carrot.png", "bunny.jpg"]
self.photo = PhotoImage(file = self.images_list[self.counter])
self.b1 = Button(parent, text = "", image = self.photo, bg = "white")
self.b1.grid(row = 0, column = 0)
back = Button(parent, width = 2, anchor = W, text = "<", relief = RIDGE, command = self.previous_image)
back.grid(row = 1, column = 0)
forward = Button(parent, width = 2, anchor = E, text = ">", relief = RIDGE, command = self.next_image)
forward.grid(row = 1, column = 1)
def previous_image(self):
self.counter -= 1
self.photo.configure(file = self.images_list[self.counter])
def next_image(self):
self.counter += 1
self.photo.configure(file = self.images_list[self.counter])
#main routine
if __name__ == "__main__":
root = Tk()
root.title("hello")
slides = SlideShowGUI(root)
root.mainloop()
sorry it will not work without getting images !
error message if i click next button two times
use this instead:
def previous_image(self):
self.counter -= 1
self.photo.configure(file = images_list[self.counter])
def next_image(self):
self.counter += 1
self.photo.configure(file = images_list[self.counter])
except You have to watch out for List Out Of Index errors
Also why are You using global images_list? There seems to be no point. If You wanted to reuse that list in the class You could have just named it self.images_list = [your, items].
The error You are getting: read this

Python self.after() changes running order

I am (still!) writing a Noughts and Crosses program using Tkinter in Python 3.
I wanted to implement a short pause between the player's move and the computer's move, so in the add_move_comp() method implemented self.after() function.
I expected this to pause the program for 1000ms then continue by 'drawing' on the computer's move.
However when I run my code, the program only recognises the computer's move the next move after, causing problems with identifying a 3-in-a-row.
I think this is due to line 62 running after 1000ms while the rest of the program continues running, but I don't know how to stop the whole program and continue running with line 62 after the pause.
from tkinter import *
from functools import partial
from itertools import *
import random
class Window(Frame):
def __init__(self, master = None): # init Window class
Frame.__init__(self, master) # init Frame class
self.master = master # allows us to refer to root as master
self.rows = 3
self.columns = 3
self.guiGrid = [[None for x in range(self.rows)] for y in range(self.columns)] # use this for the computer's moves
self.noText = StringVar(value = '')
self.cross = StringVar(value = 'X')
self.nought = StringVar(value = 'O')
self.button_ij = None
self.myMove = True
self.create_window()
self.add_buttons()
def create_window(self):
self.master.title('Tic Tac Toe')
self.pack(fill = BOTH, expand = 1)
for i in range(0,3): # allows buttons to expand to frame size
self.grid_columnconfigure(i, weight = 1)
self.grid_rowconfigure(i, weight = 1)
def add_buttons(self):
rows = 3
columns = 3
for i in range (rows):
for j in range(columns):
self.button_ij = Button(self, textvariable = self.noText, command = lambda i=i, j=j: self.add_move(i,j))
self.guiGrid[i][j] = self.button_ij
self.button_ij.grid(row = i,column = j, sticky =E+W+S+N)
def add_move(self, i,j):
# player's move
while self.myMove:
pressedButton = self.guiGrid[i][j]
self.guiGrid[i][j].config(textvariable = self.cross)
# computer's turn
self.myMove = False
while (self.myMove == False):
self.add_move_comp()
def add_move_comp(self):
repeat = True
while repeat:
i = random.randint(0,0) # row - only allow O to be drawn on 1st row for testing purposes
j = random.randint(0,2) # column
testText = self.guiGrid[i][j].cget('text')
if testText == '':
self.after(1000,lambda i = i, j = j :self.guiGrid[i][j].config(textvariable = self.nought)) # search up rules with returning values using lambda
print('Should plot O at row: ',i,' column: ',j)
print('TEXT ACTUALLY PLOTTED IS: ',self.guiGrid[i][j].cget('text'))
self.myMove = True
repeat = False
print(self.guiGrid[0][0].cget('text'), self.guiGrid[0][1].cget('text'), self.guiGrid[0][2].cget('text')+'THIS IS PRINTING')
root = Tk() # creating Tk instance
rootWidth = '500'
rootHeight = '500'
root.geometry(rootWidth+'x'+rootHeight)
ticTacToe = Window(root) # creating Window object with root as master
root.mainloop() # keeps program running
This is due to the fact that self.after imeadiately returns and starts the given function after passing trough a queque to prevent the actual Window from beeing unable to responde because there is some code running. A way to work around this is to create a BooleanVariable for validation and using self.wait_variable as follows:
from tkinter import *
from functools import partial
from itertools import *
import random
class Window(Frame):
def __init__(self, master = None): # init Window class
Frame.__init__(self, master) # init Frame class
self.master = master # allows us to refer to root as master
self.rows = 3
self.columns = 3
self.guiGrid = [[None for x in range(self.rows)] for y in range(self.columns)] # use this for the computer's moves
self.noText = StringVar(value = '')
self.cross = StringVar(value = 'X')
self.nought = StringVar(value = 'O')
self.button_ij = None
self.myMove = True
self.validationVar = BooleanVar(self)
self.create_window()
self.add_buttons()
def create_window(self):
self.master.title('Tic Tac Toe')
self.pack(fill = BOTH, expand = 1)
for i in range(0,3): # allows buttons to expand to frame size
self.grid_columnconfigure(i, weight = 1)
self.grid_rowconfigure(i, weight = 1)
def add_buttons(self):
rows = 3
columns = 3
for i in range (rows):
for j in range(columns):
self.button_ij = Button(self, textvariable = self.noText, command = lambda i=i, j=j: self.add_move(i,j))
self.guiGrid[i][j] = self.button_ij
self.button_ij.grid(row = i,column = j, sticky =E+W+S+N)
def add_move(self, i,j):
# player's move
while self.myMove:
pressedButton = self.guiGrid[i][j]
self.guiGrid[i][j].config(textvariable = self.cross)
# computer's turn
self.myMove = False
while (self.myMove == False):
self.add_move_comp()
def add_move_comp(self):
repeat = True
while repeat:
i = random.randint(0,0) # row - only allow O to be drawn on 1st row for testing purposes
j = random.randint(0,2) # column
testText = self.guiGrid[i][j].cget('text')
if testText == '':
self.after(1000, self.validationVar.set, True)
self.wait_variable(self.validationVar)
self.guiGrid[i][j].config(textvariable = self.nought) # search up rules with returning values using lambda
print('Should plot O at row: ',i,' column: ',j)
print('TEXT ACTUALLY PLOTTED IS: ',self.guiGrid[i][j].cget('text'))
self.myMove = True
repeat = False
print(self.guiGrid[0][0].cget('text'), self.guiGrid[0][1].cget('text'), self.guiGrid[0][2].cget('text')+'THIS IS PRINTING')
root = Tk() # creating Tk instance
rootWidth = '500'
rootHeight = '500'
root.geometry(rootWidth+'x'+rootHeight)
ticTacToe = Window(root) # creating Window object with root as master
root.mainloop() # keeps program running

here in this code when i select option A i am getting total = 0 as a output instead of output total = 10, how to solve it?

total = 0
def round1():
import tkinter
t =tkinter. Tk()
t.title('Round 1')
t.geometry('1000x800')
v1 = tkinter.IntVar()
def marks():
global total
if v1.get() == 1:
total = total + 10
print("total", total)
l1 = tkinter.Label(t,text = "Q 1 - Is python a case sensitive language?").grid(row = 1)
r1 = tkinter.Radiobutton(t,text = "A - true",variable = v1,value = 1).grid(row = 2)
r2 = tkinter.Radiobutton(t,text = "B - false",variable = v1,value = 2).grid(row = 3)
b = tkinter.Button(t, text = 'Submit',command = marks).place(x = 300, y = 300)
t.mainloop()
def call():
import tkinter
t = tkinter.Tk()
t.title('Instruction')
t.geometry('1000x800')
b1 = tkinter.Button(t, text = 'next',command = round1).pack()
t.mainloop()
call()
This is a well known side effect of using Tk more than once. Use Tk to create the first window, and use Toplevel to make additional windows. It works the same but you don't need a mainloop call.
Also, imports always go on the top, never in a function, and don't initialize and layout a widget on the same line (leads to common bugs).
import tkinter
total = 0
def round1():
t =tkinter.Toplevel()
t.title('Round 1')
t.geometry('1000x800')
v1 = tkinter.IntVar()
def marks():
global total
if v1.get() == 1:
total = total + 10
print("total", total)
l1 = tkinter.Label(t,text = "Q 1 - Is python a case sensitive language?")
l1.grid(row = 1)
r1 = tkinter.Radiobutton(t,text = "A - true",variable = v1,value = 1)
r1.grid(row = 2)
r2 = tkinter.Radiobutton(t,text = "B - false",variable = v1,value = 2)
r2.grid(row = 3)
b = tkinter.Button(t, text = 'Submit',command = marks)
b.place(x = 300, y = 300)
def call():
t = tkinter.Tk()
t.title('Instruction')
t.geometry('1000x800')
b1 = tkinter.Button(t, text = 'next',command = round1)
b1.pack()
t.mainloop()
call()

Compiled - OsError: Cannot load native module 'Cryptodome.Cipher._raw_ecb'

from pubnub import Pubnub ;
from tkinter import *
Window = Tk()
pubnub = Pubnub(publish_key="pub-c-9997b5b1-da6f-4935-88f7-4d0645bcdf2b",
subscribe_key="sub-c-2bc2a578-776c-11e6-9195-02ee2ddab7fe")
def Callback(message, channel):
Logic.UpdateMessageList(message)
Logic.UpdateMessageDisplay()
Display.DisplayMessage()
def Error(message):
Window.title("PubNub - Error")
def Connect(message):
Window.title("PubNub - Connected")
def Reconnect(message):
Window.title("PubNub - Reconnected")
def Disconnect(message):
Window.title("PubNub - Disconnected")
def SendMessage(event):
message = (Logic.Username, Display.MessageEntry.get())
pubnub.publish("my_channel", message = message)
pubnub.subscribe(channels='my_channel',
callback = Callback,
error = Error,
connect = Connect,
reconnect = Reconnect,
disconnect = Disconnect)
class Logic:
def __init__(self):
self.Username = ""
self.MessageList = ([],[])
self.MessageNumber = 0
self.MaxMessages = 6
def UpdateMessageList(self, message):
self.MessageList[0].append(message[0])
self.MessageList[1].append(message[1])
self.MessageNumber += 1
def UpdateMessageDisplay(self):
self.DisplayList = []
if self.MessageNumber >= (self.MaxMessages + 1):
self.MessageList[0].pop(0)
self.MessageList[1].pop(0)
for Num in range(len(self.MessageList[0])):
for ListNum in range(2):
self.DisplayList.append((self.MessageList[ListNum][Num]))
self.DisplayList.append("\n")
Logic = Logic()
class MainDisplay:
def __init__(self):
Window.geometry("400x400")
Window.resizable(0,0)
self.MessageVar = StringVar()
Window.title("PubNub")
def ScreenOne(self):
Window.bind("<Return>", self.AdvScreenTwo)
self.EasyFrame = Frame(Window)
self.EasyFrame.config(bg = "Grey", height = 400, width = 400)
self.EasyFrame.grid()
self.EasyFrame.place(relx = 0.5, y = 200, anchor = CENTER)
self.UsernameEntry = Entry(self.EasyFrame)
self.UsernameEntry.config(width = 15, bg = "White", fg = "Black")
self.UsernameEntry.grid()
self.UsernameEntry.place(relx = 0.5, y = 200, anchor = CENTER)
UsernameLabel = Label(self.EasyFrame, text = "Enter Username")
UsernameLabel.config(bg = "Grey", bd = 0, font = ("times",13,"bold"), fg = "White")
UsernameLabel.grid()
UsernameLabel.place(relx = 0.5, y = 90, anchor = CENTER)
def AdvScreenTwo(self, event):
Logic.Username = (self.UsernameEntry.get())
Window.unbind("<Return>")
self.EasyFrame.grid_forget()
self.EasyFrame.destroy()
Window.bind("<Return>", SendMessage)
self.ScreenTwo()
def ScreenTwo(self):
self.MessagesParent = Frame(Window)
self.MessagesParent.config(bg = "Grey", height = 400, width = 400)
self.MessagesParent.grid()
self.MessagesParent.place(relx = 0.5, y = 200, anchor = CENTER)
self.MessageEntry = Entry(self.MessagesParent)
self.MessageEntry.config(width = 40, bg = "Grey", fg = "Black")
self.MessageEntry.grid()
self.MessageEntry.place(relx = 0.5, y = 350, anchor = CENTER)
def DisplayMessage(self):
Y = 10
for Item in (Logic.MessageList[0]):
self.TextLabel = Label(Window, text = Item, height = 3, width = 6, font = ("times", 8, "bold"), anchor = "w")
self.TextLabel.grid()
self.TextLabel.place(relx = 0.05, y = Y)
Y += 50
Y = 10
for Item in (Logic.MessageList[1]):
self.TextLabel = Label(Window, text = Item, height = 3, width = 40, font = ("times", 8, "bold"),wraplength = 270, anchor = "w")
self.TextLabel.grid()
self.TextLabel.place(relx = 0.2, y = Y)
Y += 50
Display = MainDisplay()
def Main():
Display.ScreenOne()
if __name__ == "__main__":
Main()
Window.mainloop()
This is my code which does work when i run it through the console or IDLE which is fine and all but i would like to compile it. I managed to compile it with my usual method using cx_freeze but i get a error message:
OsError: Cannot load native module 'Cryptodome.Cipher,_raw_ecb'
Can provide any additional information that may be required.
Has gotten a fair amount of views so i thought i would post the answer, i emailed pubnub support
Hi Joshua,
Please use this branch from our SDK https://github.com/pubnub/python/tree/reduce_crypto ; it has cryto unbundled from the dependencies.
This fixed it :) (Replace the pubnub file in Pythonx.x with the pubnub.py file on the git)

Categories