I have been trying to load a photo onto a Tkinter canvas but I keep failing to do so. The message I get is: TclError: couldn't open "C:\Jules\...\photo_files•0651442_51c04521d6.gif": no such file or directory.
I am using Python 2.7.
Here is my code.
import Tkinter
topthree = Tkinter.Tk()
canvas = Tkinter.Canvas(topthree, height=800, width= 800)
canvas.grid(row = 0, column = 0)
photo = Tkinter.PhotoImage(file = "C:\Jules\...\6250651442_51c04521d6.gif")
im = canvas.create_image(0,0, image=photo)
canvas.pack()
topthree.mainloop()
Prepend r before the file name:
photo = Tkinter.PhotoImage(file = r"C:\Jules\...\6250651442_51c04521d6.gif")
This is because the backslash interprets the next char as a control char, and this can cause some chars to disappear. For example, \n becomes a new line and the n goes away...
Writing r before the string cancels control characters. (r stands for raw string)
Related
I wanted to get user input from user using Tkinter's Entry something like this
from Tkinter import *
top = Tk()
label = Label(top, text="Enter your bio")
entry = Entry(top, bd = 2)
def create_new():
new_file = open('file.txt', 'w+')
user_input = str(entry) # I ALSO TRIED WITHOUT str()
new_file.write(user_input) #still doesn't work
button = Button(top, text = "SAVE", fg ="red", command=create_new)
label.pack()
entry.pack()
button.pack()
top.mainloop()
When I add my info in the field and hit SAVE, it does create a new file.txt but it doesn't write my info into the file.txt
file.txt only has some numbers like these
.22775808
.22710272
.22382592
etc...
Any ideas on how can I fix this? Also what do these numbers mean and why are they here?
from tkinter import *
top = Tk()
label = Label(top, text="Enter your bio")
entry = Entry(top, bd = 2)
def create_new():
new_file = open('file.txt', 'w+')
user_input = (entry).get() # I ALSO TRIED WITHOUT str()
new_file.write(user_input) #still doesn't work
button = Button(top, text = "SAVE", fg ="red", command=create_new)
label.pack()
entry.pack()
button.pack()`enter code here`
top.mainloop()
You aren't writing the contents of the Entry, you're writing the Entry itself - which from Python's point of view is just the randomly-generated name of the actual widget which lives in the embedded Tcl/Tk interpreter. Use entry.get() for the actual contents.
You're also forgetting to close the file after you write to it, so anything you do manage to write may not show up immediately.
What I want to be able to do is run a list of MIDI files, I have the programme to list them out and play them...
import os,fnmatch,pygame
pygame.mixer.init()
List = []
Song = 0
def Update():
List = []
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.mid'):
List.append(file)
return List
List = Update()
while True:
while Song <= len(List):
pygame.mixer.music.load(List[Song])
pygame.mixer.music.play(1)
while pygame.mixer.music.get_busy() == True:
List = Update()
Song = Song + 1
Song = 0
This currently works with .mid files that it is in the same folder as, however I want to implement a slider with the programme to control the volume, I also have that code already...
from Tkinter import *
master = Tk()
def getThrottle(event):
Volume = Throttle.get()
Throttle = Scale(master, from_=0, to=100, tickinterval=10, length=200, orient=HORIZONTAL, command=getThrottle)
Throttle.set(0)
Throttle.pack()
mainloop()
What I want to know is how I can make both programmes run at the same time with a single variable global between both with that variable being Volume
Nevermind, I discovered how to run both a tkinter window and music at the same time, however a new problem is that the tkinter window is blank.
New question is "Why is the tkinter window blank?"
I am trying to create text using PIL. The problem is, that when I want to print a new line (\n), I only get a little box:
Here is the minimal example:
from PIL import Image, ImageDraw, ImageFont
import os
heading1 = 'heading1'+'\n'+'heading1'
path_f = os.path.dirname(os.path.realpath(__file__))
font = "Arial.ttf"
path_A = path_f+"/"+font
im1 = Image.open("c.png").resize((300, 300))
new_im=Image.new("RGB",(600 ,500), "white")
new_im.paste(im1, (0,100))
font = ImageFont.truetype(path_A, 20)
draw = ImageDraw.Draw(new_im)
draw.text((40,30), heading1, fill= "black", font=font)
new_im.show()
del draw
And this is the output I get:
enter image description here
Any kind of help would be very much appreciated!
"Because it doesn't interpret control characters."
Seems to be an answer to me.
Currently, I am working on a GUI text editor with python and tkinter. Thanks to the great people at SO (thank you Rinzler), I have managed to modify the font of the text. However, I am unable to save the font and font size to the txt file.
I know that this should be possible as Notepad can modify and save a txt file with a specified font.
This is the code to save to a file:
def file_saveas():
filename = tkFileDialog.asksaveasfile(mode='w', defaultextension=".txt")
if filename is None: # asksaveasfile return `None` if dialog closed with "cancel".
return
text2save = str(textPad.get(1.0, END)) # starts from `1.0`, not `0.0`
filename.write(text2save)
filename.close()
print filename
This is the code (courtesy of Rinzler) to change the font:
def choose_font():
global root, textPad # I hate to use global, but for simplicity
t = Tkinter.Toplevel()
font_name = Tkinter.Label(t, text='Font Name: ')
font_name.grid(row=0, column=0, sticky='nsew')
enter_font = Tkinter.Entry(t)
enter_font.grid(row=0, column=1, sticky='nsew')
font_size = Tkinter.Label(t, text='Font Size: ')
font_size.grid(row=1, column=0, sticky='nsew')
enter_size = Tkinter.Entry(t)
enter_size.grid(row=1, column=1, sticky='nsew')
# associating a lambda with the call to text.config()
# to change the font of text (a Text widget reference)
ok_btn = Tkinter.Button(t, text='Apply Changes',
command=lambda: textPad.config(font=(enter_font.get(),
enter_size.get())))
print font
ok_btn.grid(row=2, column=1, sticky='nsew')
done = Tkinter.Button(t, text='Get rid of Pushy!', command=t.destroy)
done.grid(row=4, column=1, sticky='nsew')
# just to make strechable widgets
# you don't strictly need this
for i in range(2):
t.grid_rowconfigure(i, weight=1)
t.grid_columnconfigure(i, weight=1)
t.grid_rowconfigure(2, weight=1)
Finally, this is the code that reads the font and other configuration information:
font = (fontname, size)
textPad.config(
borderwidth=0,
font=font ,
foreground="green",
background="black",
insertbackground="white", # cursor
selectforeground="blue", # selection
selectbackground="#008000",
wrap="word",
width=64,
undo=True, # Tk 8.4
)
I have searched the internet without coming up with any answers as to why the font and text size are not saved. Any help would be greatly appreciated.
I am using python 2.7.7 , Tkinter, and this is being run on Windows 7.
Any help manipulation an rtf file would also be helpful (currently, I see the tags and not the end format).
There is no support for this in tkinter. You will have to pick a file fomat that supports fonts (rtf, .docx, .html, etc), convert the data in the widget to this format, and then write it to a file.
Notepad can only have a custom font and size for its editor window, it doesn't save it to the file, it just remembers the user's custom settings, and applies them to its window when you use it.
The tkinter text widget can be horrible to save formatting to another format, I've tried converting it to XML to save to a .docx but I haven't been successful. I have used my own format which is a plain text file with an 'index' of the tkinter Text widget tags at the start and their line&column indexes, then a marker for where the document begins, then the document. This cannot hold images though, and it opens with all the formatting index when you open it in another word processor.
XML is ideal for opening and saving the tkinter text contents - use an xml parser to open, then wite a recursive function to add text with tags as you go. (If you want rich text, this, like xml, is an iterative format - elements inside elements, so could be done like i'm describing below for xml, but you need to write your own rich text parser)
import xml.etree.ElementTree as etree
e = etree.fromstring(string)
#create an element tree of the xml file
insert_iter(e)
#call the recursive insert function
def insert_iter(element):
#recursive insert function
text.insert("end", element.text, tagname)
#insert the elements text
for child in element:
insert_iter(child)
#iterate through the element's child elements, calling the recursive function for each
text.insert("end", child.tail, tagname)
#insert the text after the child element
text.tag_config(tagname, **attrib)
#configure the text
'attrib' is a dictionary eg. {"foreground":"red", "underline":True} would make the text you insert have red font and black underline,
'tagname' is a random string, and needs to be automatically created by your program
To save the file, make a function to do the reverse. I wouldn't bother with using the xml library for this - as tkinter outputs the correct format, just write it manually, but make sure to escape it
from xml.sax.saxutils import escape
data = text.dump("1.0", "end")
print(data[0:500]) # print some of the output just to show how the dump method works
output = ''
#get contents of text widget (including all formatting, in order) and create a string to add the output file to
for line in data:
if line[0] == "text":
#add the plain text to the output
output += escape(line[1])
elif line[0] == "tagon":
#add a start xml tag, with attributes for the given tkinter tag
name = 'font'
attrib = ""
tag = #the dictionary you stored in your program when creating this tag
for key in tag:
attrib += "%s='%s' "%(key, escape(tag[key]))
output += "<%s %s>"%(name, attrib)
elif line[0] == "tagoff":
#add a closing xml tag
output += '</%s>'%name
I am trying to make something like this using frames:
And this is my code so far: # I am trying to put the frames in the certain location only, and not fill the entire display
from Tkinter import *
class Menu():
def display(self):
self.canvas = Canvas(width=1200,height=700)
self.canvas.grid()
self.controlcanvas = Canvas(self.canvas,width=850,height=200)
self.controlcanvas.place(x=348,y=107)
indexframe = Frame(self.controlcanvas)
titleframe = Frame(self.controlcanvas)
readCframe = Frame(self.controlcanvas)
commentCframe = Frame(self.controlcanvas)
indexframe.pack(side=LEFT)
titleframe.pack(side=LEFT)
readCframe.pack(side=LEFT)
commentCframe.pack(side=LEFT)
dummyindex = Label(indexframe,text="#").grid(row=0,column=0)
dummytitle = Label(titleframe,text="Title").grid(row=0,column=1)
dummyreadC = Label(readCframe,text="Read Count").grid(row=0,column=2)
dummycommentC = Label(commentCframe,text="Comments").grid(row=0,column=3)
mainloop()
m = Menu()
m.display()
The problem here is that the # Title Read Count and Comments resize the frame into small one.
I want the frames to retain their original geometry so that I could create something like the picture.
Any help?
Frame has a list of config options that handle its properties like size and border. When you create the frame, you can specify these options:
indexframe = Frame(self.controlcanvas, height=400, width=200, borderwidth=2)
or you can access them later via:
indexframe.config(borderwidth=2)
Take a look at the method documentation for more options.