Good Afternoon all,
I've been working on a contact-book program for a school project. I've got all of the underlying code complete. However I've decided to take it one step further and implement a basic interface. I am trying to display all of the contacts using the code snippet below:
elif x==2:
phonebook_data= open(data_path,mode='r',encoding = 'utf8')
if os.stat(data_path)[6]==0:
print("Your contact book is empty.")
else:
for line in phonebook_data:
data= eval(line)
for k,v in sorted(data.items()):
x= (k + ": " + v)
from tkinter import *
root = Tk()
root.title("Contacts")
text = Text(root)
text.insert('1.0', x)
text.pack()
text.update()
root.mainloop()
phonebook_data.close()
The program works, however every contact opens in a new window. I would like to display all of the same information in a single loop. I'm fairly new to tkinter and I apologize if the code is confusing at all. Any help would be greatly appreciated!!
First of all, the top of the snippet could be much more efficient:
phonebook_data= open(data_path,mode='r',encoding = 'utf8') should be changed to
phonebook_data = open(data_path).
Afterwards, just use:
contents = phonebook_data.read()
if contents == "": # Can be shortened to `if not contents:`
print("Your contact book is empty.")
And by the way, it's good practice to close the file as soon as you're done using it.
phonebook_data = open(data_path)
contents = phonebook_data.read()
phonebook_data.close()
if contents == "":
print("Your contact book is empty.")
Now for your graphics issue. Firstly, you should consider whether or not you really need a graphical interface for this application. If so:
# Assuming that the contact book is formatted `Name` `Number` (split by a space)
name_number = []
for line in contents.split("\n"): # Get each line
name, number = line.split()
name_number.append(name + ": " + number) # Append a string of `Name`: `Number` to the list
name_number.sort() # Sort by name
root = Tk()
root.title("Contact Book")
text = Text(root)
text.pack(fill=BOTH)
text.insert("\n".join(name_number))
root.mainloop()
Considering how much I have shown you, it would probably be considered cheating for you to use it. Do some more research into the code though, it didn't seem like the algorithm would work in the first place.
Related
I have this very easy program which I want to display one random line from a file each time I click on the Button.
Problem is a new line is display at startup of the program, but nothing happens when I click the button, can someone explain me why ?
from random import randrange
from tkinter import *
def entree():
n=randrange(251)
fs = open('lexique','r')
liste = fs.readlines()
return liste[n]
fen = Tk()
fen.title("lexique anglais politique")
defi = StringVar()
defi.set(entree())
lab = Label(fen, textvariable=defi).pack()
Button(fen, text='Beste Bat', command=entree).pack()
fen.mainloop()
As stated in one of the comments (by #matszwecja), your entree() function doesn't really do anything appart from returning a value.
Nothing in your code updates the actual label. Try something like this :
from random import randrange
from tkinter import *
def entree():
n=randrange(251)
fs = open('lexique','r')
liste = fs.readlines()
return liste[n]
def update_label():
lab.config(text=entree())
fen = Tk()
fen.title("lexique anglais politique")
lab = Label(fen, text=entree())
lab.pack()
Button(fen, text='Beste Bat', command=update_label).pack()
fen.mainloop()
In this example, the entree() function is used to go get a line from your file, and the update_label() function is used to actually update the label.
Also, if you want to be able to update a label, you'll have to pack it after assigning it to a variable.
On a side note, it could be worth noting that hardcoding values that could change in the future is generally considered bad practice. In that regard, I think coding the entree() function this way might be a better idea :
def entree():
fs = open('lexique','r')
liste = fs.readlines()
n=randrange(len(liste))
return liste[n]
This way, if you ever add or remove lines to your "lexique" file, you will not have to change the code.
the code might be a little non-standart / messy. it's basically a guess the number game..
Any way, i want to change the label after the user pressing the yes/no button. i had some ideas but non of them worked well.. please help me :)
currently the label is "start from last time?" and i would like to change it to "choose a number between 1 - 99".
label = Label(root, text="start from last time?")
label.pack()
this is the function that activates when the user pressing the button, you can ignore what is written there just add the code :)
def yes():
fd = open("save.txt", "r")
data = fd.read()
data = data.split("|")
global answer
answer = int(data[0])
global attempts
attempts = int(data[1])
fd.close()
btnYes.pack_forget()
btnNo.pack_forget()
entryWindow.pack()
btnCheck.pack()
btnQuit.pack()
btnSave.pack()
root.geometry("500x150")
text.set("You Have {0} attempts Remaining! Good Luck!".format(attempts))
If what you are trying to do is to change the tk.Label text there are two ways to do it.
Label.config(text="Whaterver you want")
or
Label["text"] = "New Text"
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
I want to make a program that show me the divisors of the number introduced in a text box using python tkinter GUI and store the results into a plain text file.
I don't how to get the value from the text box. I understood that is something linked with get() , I read something but I still don't get it.
Here is the code:
from tkinter import *
def create_file():
file_object = open("C:/Users/valis/Desktop/Divisors.txt","w+")
def evaluate():
show_after= Label(text= "Check your Desktop !")
show_after.pack(pady=2, anchor=SW)
create_file()
#Windows size and Title
window = Tk()
window.title("Show Divisors")
window.geometry("300x100")
message = Label(window, text="Enter a number : ")
message.pack(pady=2, anchor=NW)
textbox_input = Text(window,height=1, width=11)
textbox_input.pack(padx= 2,pady= 2, anchor=NW)
window.mainloop()
The code isn't complete, so what should I do ?
As you said, you will use the get() function but with some additional attributes.
If we have a text box textbox_input, then you can return its input using this line:
test_input = textbox_input.get("1.0",END)
The first part, "1.0" means that the input should be read from line one, character zero (ie: the very first character). END is an imported constant which is set to the string "end". The END part means to read until the end of the text box is reached.
Reference: This answer.
I am trying to create a program that collects a count total of the number of unread messages inside an inbox. I am having no issues with collecting the data, the problem I have is in displaying it in real-time into a text box so that when a new mail comes in the number ticks up, instead of creating a new line underneath it, or having to completely restart the program.
After asking this previous question (How to change the data output received externally in realtime within a program's text window?) a great community member of StackOverflow gave me the following code to work through.
Now it appears to collect the data from my inbox as normal, but it isn't posting the results. I think it must have something to do with how I am using [info] but I am at a total loss.
Thank you for your help!
#! /usr/bin/env python3.4
import imaplib
import email
import tkinter as tk
WIDTH = 500
HEIGHT = 500
def update():
mail=imaplib.IMAP4_SSL('imap.gmail.com',993)
mail.login('email"gmail.com','password')
mail.select("Submissions")
typ, messageIDs = mail.search(None, "UNSEEN")
messageIDsString = str( messageIDs[0], encoding='utf8' )
listOfSplitStrings = messageIDsString.split(" ")
number = len(listOfSplitStrings)
if number == 0:
info['text'] = 'no submissions'
else:
info['text'] = '{} submissions[s]'.format(number)
root.after(5000, update)
root = tk.Tk()
root.title('submissions counter')
x = (root.winfo_screenwidth()//2) - (WIDTH//2)
y = (root.winfo_screenheight()//2) - (HEIGHT//2)
root.geometry('{}x{}+{}+{}'.format(WIDTH, HEIGHT, x, y))
info = tk.Label(root, text='no submissions')
info.pack
update()
root.mainloop()
info.pack()
Instead of:
info.pack
A simple mistake anyone could make.