why does split method stop working with Tkinter? - python

Whenever I run this code with the chopped = first_word.split() line I get an error (the window closes instantly).
import tkinter as tk
win = tk.Tk()
win.title("Conversation")
win.iconbitmap("cake.ico")
win.geometry("600x700")
#Lists
Hellos = ["greetings", 'hello', 'greetings', 'hi']
gday = ['good', 'great', 'incredible', 'not bad', 'okay']
bday = ['bad', 'awful', 'not the best', 'terrible']
fw_label = tk.Label(win, text="Hello user, it's nice to meet you.")
fw_label.pack()
first_word = tk.Entry()
first_word.pack()
chopped = first_word.split()
But when I change the line first_word = tk.Entry() to first_word="A normal string" , the split method highlights and when I hover it it gives its description, which wasn't happening with ```first_word = tk.Entry()``.
I've ran into this problem when using libraries like opencv, may I know what's causing it not to work?

The solution is simple. You have to make a function to be called while pressing the submit button. And the statement chopped = first_word.get().split() should be inside that function.
Coming to the error part, it was because first_word is a tkinter entry object without any attribute split().
The split method works only for strings. To get the text entered into the entry widget in form of string, you need to use the get() method...
import tkinter as tk
def click():
chopped = first_word.get().split()
print(chopped)
win = tk.Tk()
win.title("Conversation")
# win.iconbitmap("cake.ico")
win.geometry("600x700")
#Lists
Hellos = ["greetings", 'hello', 'greetings', 'hi']
gday = ['good', 'great', 'incredible', 'not bad', 'okay']
bday = ['bad', 'awful', 'not the best', 'terrible']
fw_label = tk.Label(win, text="Hello user, it's nice to meet you.")
fw_label.pack()
first_word = tk.Entry()
first_word.pack()
tk.Button(win, text="Submit", command=click).pack()
win.mainloop()
So, you get the text of the entry using the get() method and then split it
Note : The statement chopped = first_word.get().split() should be inside the function because if its outside it, it would be executed at the time of the creation of the entry widget and using get() there would result in an empty value as the entry doesn't contain anything at that point

Maybe this could work
Change
chopped = first_word.split()
to
chopped = first_word.get().split()

I'm unable to reply my comment on your last question because of my low reputation. https://www.shapedivider.app/ here you would easily make the curves you want and embed the code to your project. I use this often.

Related

How to create a letter counter with Tkinker?

I just started to learn Python and I'm trying to create a mineral counter by only using letters for microscopic petrography, but I am having problems passing my python code to Tkinker. Can you guys give tips about how to get my output to work? I'm finding it challenging to use theget() method even with online tutorials.
Can you guys teach this noob? Thank you!
My original code:
# define sample
sample = "qreqqwer"
# mineral q:
mineralq= "q"
countq = sample.count(mineralq)
# print count of q
print("The quantity of q is: ", countq)
The structure I made with Tkinker:
from tkinter import *
import tkinter as tk
# Window
window=tk.Tk()
window.title("Mineral Counter")
window.geometry("800x1000")
window.configure(bg="#00090F")
inputUser=tk.Text(window,width=225,height=5,font=("Arial bold",12),wrap="word", bg="#00090F", fg="white")
inputUser.pack()
# define sample
# mineral q:
countq = inputUser.count("q")
# print count of q
output.insert(tk.INSERT,countq)
output=tk.Text(window,width=20,height=2,font=("Arial bold",12), bg="#00090F", fg="white")
output.pack()
window.mainloop()
You need a button to update your code, becuase initially the Text boxes are empty and hence there is no occurence for q so nothing can be inserted.
Try this out:
First create a button with a function to click onto after the data is entered
b = tk.Button(window, text='Click Me', command=click)
b.pack()
Then now define the function that the button calls when is clicked onto
def click():
sample = inputUser.get('1.0', 'end-1c') #getting value from text box 1
mineralq = 'q' #letter to be counted
countq = sample.count(mineralq) #counting the letter
output.insert('1.0', f'The quantity of q is: {countq}') #inserting the output to text box 2
Hope it cleared your doubt, if any errors do let me know
Cheers

Tkinter python dependent combobox

I am a python and arcpy user and I have a problem about dependent combobox. Actually I have asked the same topic on here, but no one answer yet. I've got the answer from here and here. But I think I am too newbie on python programming and I don't get the answer clearly.
I try my code like this below, base on the answer that I've got before:
import Tkinter
from Tkinter import *
root = Tkinter.Tk()
bu = StringVar()
bu.set("")
businessunit = ["DUM", "IND", "KAM", "RAP"]
bu_menu = OptionMenu(root, bu, *businessunit, command=Combobox_1)
bu_menu.config(bg="white", fg="dark blue", width=3, relief=GROOVE)
bu_menu.place(x=95, y=110)
sec = StringVar()
sec.set("")
sector = {"DUM":['GRG', 'KBU', 'LBO', 'PLS', 'PLU', 'PPR', 'RPT', 'SBI', 'SKB'],
"IND":['BYS','MER','NGD','PER','SJG','SLJ'],
"KAM":['RSG','SRG','SRY','TSK'],
"RAP":['BAS','CER','LGB','LON','LOS','MDU','MRE','MRW','PEN','PES','PPD','TEE','TEW','TSB','UKU']}
sec_menu = OptionMenu(root, sec, *sector, command=Combobox_2)
sec_menu.config(bg="white", fg="dark blue", width=3, relief=GROOVE)
sec_menu.place(x=155, y=110)
def __init__(self):
def Combobox_1(businessunit):
print bu.get()
def Combobox_2(sector):
print sec.get()
self.Combobox_1.activated[str].connect(self.on_combo_activated)
def on_combo_activated(self, text):
self.Combobox_2.clear()
self.Combobox_2.addItems(self.sector[text])
root.pack()
root.mainloop()
root.destroy()
Please anyone help me on this. Thank you so much for your answer.
edited:
in this case, dependent combobox means:
If DUM is selected in Combobox_1, Combobox_2 will only show GRG,KBU,LBO, etc.
If IND is selected in Combobox_1, Combobox_2 will only show BYS,MER,PER, etc.
If KAM is selected in Combobox_1, Combobox_2 will only show RSG,SRG,SRY, etc.
If RAP is selected in Combobox_1, Combobox_2 will only show BAS,CER,LGB, etc.
I would advise looking at: Change OptionMenu based on what is selected in another OptionMenu
Just change the values as you need them in your menu.
(Also, you don't need to import Tkinter twice, just use "import Tkinter" or "import Tkinter as tk")
Thank you for your contribution. Actually I've got the answer of this question in my question before. Please see this link Graded combobox Menu Python Tkinter
This is called a cascade combo box. Basically in your command (action) you then create the second box with the data based on the selected value of the first. This is easy with a database i dont know of other ways but some sort of array or dictionary should also work fine.
I do it in a class that I call from my app so this is a little over complicated but can be easily simplified if you dont want to bother with the class vals is a dictionary that looks like {'value1':number,'value2':number2} to keep the index needed fro a database call to get more values or whatever. I am using .grid you can use pack or whatever suits you.
def ebox(self, index=None, row=None, column=None, vals=None):
self.value[index] = tk.StringVar()
lis = []
for item in vals:
lis.append(item)
self.combos[index] = ttk.Combobox(self.win, values=lis, textvariable=self.value[index])
self.combos[index].bind("<<ComboboxSelected>>", lambda event, y=vals: self.eboxclk(event, y))
self.combos[index].grid(row=row, column=column)
return
def eboxclk(self, event=None, index=None):
print(event.widget.get(), " widget get ")
print(index[event.widget.get()], " this should be your index")
return
I initialize a dictionary for my widgets, but you could just skip it and just
mycombo = ttk.Combobox(master,values=alist, textvariable=tk.StringVar)
mycombo.bind('<<ComboboxSelected>>', lambda event, dict: dosomething(event, dict)

Python Tkinter/GUI Not Updating/Working Correctly

I'm wondering if anyone can give me a quick simple fix for my issue.
I'm trying to make a program (as a gcse mock) that will obtain the position of words in a sentence.
I have the sentence bit working great in the text however I want to go above and beyond to get the highest possible marks so I'm creating it again with a gui!
So far I have the following code and it's not working correctly, it's not updating the 'sentence' variable and I'm looking for a simple way around fixing this Instead of updating. I get some random number which I'm not sure where it has come from. Any help will be much appreciated. :)
#MY CODE:
#GCSE MOCK TASK WITH GUI
import tkinter
from tkinter import *
sentence = ("Default")
window = tkinter.Tk()
window.resizable(width=FALSE, height=FALSE)
window.title("Sentence")
window.geometry("400x300")
#Add custom logo here later on
def findword():
print ("")
sentencetext = tkinter.Label(window, text="Enter Sentence: ")
sentence = tkinter.Entry(window)
sentencebutton = tkinter.Button(text="Submit")
findword = tkinter.Label(window, text="Enter Word To Find: ")
wordtofind = tkinter.Entry(window)
findwordbutton = tkinter.Button(text="Find!", command = findword)
usersentence = sentence.get()
usersentence = tkinter.Label(window,text=sentence)
shape = Canvas (bg="grey", cursor="arrow", width="400", height="8")
shape2 = Canvas (bg="grey", cursor="arrow", width="400", height="8")
#Packing & Ordering Modules
sentencetext.pack()
sentence.pack()
sentencebutton.pack()
shape.pack()
findword.pack()
wordtofind.pack()
findwordbutton.pack()
usersentence.pack()
shape2.pack()
window.mainloop()
Currently your sentence's 'submit' button doesn't actually have a command bound, and the two 'sentence' references are likely to conflict:
sentencebutton = tkinter.Button(text="Submit")
sentence = ("Default")
sentence = tkinter.Entry(window)
I can see that what you've tried to do is set it so that the variable sentence changes from "Default" to whatever one enters in the Entry window - this will not work, all you've done is set it so that sentence becomes the entry widget itself, not whatever is entered.
I would recommend creating a function called something like 'update_sentence', and rename your initial 'sentence' variable to distinguish it from the label:
var_sentence = "default"
def update_sentence:
var_sentence = sentence.get()
And then change your button so it has a command, like so:
sentencebutton = tkinter.Button(text="Submit", command = update_sentence)
Hope this helps!

win32api.messagebox gets called on program start

I have a very simple Python program that I am using to get familiar with the win32api message calls. I put a line in my program
mywin['button'].onclick = win32api.MessageBox(0, 'hello', 'title')
The problem is that the message box gets displayed as soon as the program starts. And it does not get displayed when the button is clicked. Any ideas what I am doing wrong?
Here is the rest of my code:
import gui
import win32api
gui.Window(name='mywin', title=u'gui2py minimal app', resizable=True, height='459px', width='400px', image='', )
gui.Button(label=u'Click me!', name='button', left='8', top='115', default=True, parent='mywin', )
# get a reference to the Top Level Window:
mywin = gui.get("mywin")
mywin['button'].onclick = win32api.MessageBox(0, 'hello', 'title')
if name == "main":
mywin.show()
gui.main_loop()
You are assigning the .onclick attribute to the return value of calling win32api.MessageBox. It is no different than doing:
value = win32api.MessageBox(0, 'hello', 'title')
mywin['button'].onclick = value
To fix the problem, you can use a lambda function:
mywin['button'].onclick = lambda: win32api.MessageBox(0, 'hello', 'title')
The above assigns the .onclick attribute to the lambda function. When the button is clicked, the lambda will be called and the win32api.MessageBox(0, 'hello', 'title') code will be executed.

Python: "choice" Function does not seem to be working as I want it to.

Here is the code I'm working with:
import sys
from tkinter import *
from random import choice
def motiv():
motiv1 = mLabel = Label(text='Waste not, want not', fg="red").pack()
motiv2 = mLabel = Label(text='Sticks and stones', fg="red").pack()
motiv3 = mLabel = Label(text='Keep holding on', fg="red").pack()
motiv4 = mLabel = Label(text='Hold On, Pain Ends', fg="red").pack()
ranMotiv = [motiv1, motiv2, motiv3, motiv4]
print (choice(ranMotiv))
mGui = Tk()
mGui.geometry('450x450+500+150')
mGui.title('RMM')
mLabel = Label(text='Welcome to the Random Motivation Machine', fg="red").pack()
mButton = Button(text = "Click for Some Motivation", command = motiv)
mButton.pack()
mGui.mainloop()
There are no errors, but it keeps printing out all of those texts at the same time, when I'm wanting it to only print out only one of them at random.
My goal is to have someone press the button and out pops a random phrase in the GUI window.
So someone presses the button and only one of any of the four text phrases comes out on the window:
1.Waste not, want not.
2.Sticks and stones
3.Keep holding on.
4.Hold on, Pain Ends.
I believe my troubles are arising from this area right here:
ranMotiv = [motiv1, motiv2, motiv3, motiv4]
print (choice(ranMotiv))
Does anyone have any ideas? This is just a very small pet project of mine. I've only been using Python for less than a few months so I'm not very astute. I'm running Python 3.2.5 by the way. Thank you all in advance.
I originally posted this as a comment, but it turned out to be the answer, so I'm reposting it here:
The problem is that Label(text='Waste not, want not', fg="red").pack() packs the label right away. Doing this with all labels causes them to be packed. It doesn't matter if you call random.choice later because the labels have already been packed into your GUI.
If you want to create a random label from a pool of labels, What you want to do is this:
def motiv():
myLabels = ['Waste not, want not', 'Sticks and stones', 'Keep holding on', 'Hold On, Pain Ends']
chosenLabel = random.choice(myLabels)
randMotiv = Label(text=chosenLabel, fg="red").pack()
How about this:
from tkinter import *
from random import choice
# Place the messages outside of the function so that they are not
# re-created each time the button is pressed
messages = ['Waste not, want not', 'Sticks and stones',
'Keep holding on', 'Hold On, Pain Ends']
def motiv():
# Just update the text of the Label instead of create a whole new one
message["text"] = choice(messages)
mGui = Tk()
mGui.geometry('450x450+500+150')
mGui.title('RMM')
mLabel = Label(text='Welcome to the Random Motivation Machine', fg="red").pack()
mButton = Button(text = "Click for Some Motivation", command = motiv)
mButton.pack()
# Make a Label to hold the messages that will be updated with each click of the button
message = Label(fg="red")
message.pack()
mGui.mainloop()
Instead of just tacking a new message to the bottom of the GUI, this method is cleaner and just updates the text of the message. It also fixes the problem of messages running off of the GUI (you can see this by clicking the button like 30 times).

Categories