Buttons not appearing below image in python GUI - python

I am developing a GUI on Python and I have the following problem: I want to have the picture at the top of the window and buttons right underneath it. I am using the Tkinter module and whatever geometry I use (place, pack or grid) the buttons don't move. The are only displayed if I move the image using grid to row 1 (which is the second row), otherwise they don't appear at all. Here is the code I am using for now. For reference the picture has dimensions of 291x87 pixels.
import Tkinter
from Tkinter import *
def main():
window =Tk()
window.geometry("300x300")
window.title("Dienes Blocks Application")
window.iconbitmap(default='favicon.ico')
app = HomeScreen(window)
window.mainloop()
class HomeScreen(Frame):
def __init__(self, master):
Frame.__init__(self,master)
self.create_buttons()
self.sparx_head()
def sparx_head(self):
self.grid()
photo = Tkinter.PhotoImage(file="logosmall.gif")
sparx_header = Label(image=photo)
sparx_header.image = photo # keep a reference!
sparx_header.grid(column=0, row=0, columnspan=2, rowspan=2, sticky='NSEW')
def create_buttons(self):
self.grid()
#teacher button
teacher_button = Tkinter.Button(self, text="Teacher")
teacher_button.grid(column=0, row=10)
# student button
student_button = Tkinter.Button(self, text="Student")
student_button.grid(column=2, row=10)
# prototype button
prototype_button = Tkinter.Button(self, text="Prototype")
prototype_button.grid(column=1, row=10)
if __name__ == "__main__":
main()

You just need to use self in the image label:
sparx_header = Label(self,image=photo)
They were not having the same parent & that's why you were having this problem

Related

How to place tkinter button in specific place (in pixels)?

For the past few days I have been trying to create a Python script that serves as a dashboard. However, I cannot figure out how to create a Button that is in a specific place (ex. 50, 50) but cannot figure it out.
b = Button(root, text="some button", height=50, width=50, compound='c')
b.pack(x=50, y=50)
root.mainloop()
Any help would be appreciated!
A simple example:
from tkinter import Tk, Button
class App():
""" App class """
def __init__(self, master):
""" init """
self.master = master
self.my_button_1 = Button(self.master, text="Press", command=self.passing)
self.my_button_1.place(x=50, y=100)
def passing(self):
print("Button pressed")
if __name__ == "__main__":
root = Tk()
root.title("Geometry manager")
root.geometry("600x400")
App(root)
root.mainloop()
This will place the left-top button corner 50 pixels in the X-axis and 100 pixels in the Y-axis. You can achieve the same with grid() manager as well but you have to be carefully with columns and rows.
place( place-options):
x, y, height, width, anchor, bordermode, relx, rely, relheight, relwidth
You can find more info in the documentation.

Python tkinter 2 frames merge together

Hey guys I have to classes that both create a Frame. The first one contains a button that is supposed to close its frame. The second frame simply contains a Label. My code should first create the frame with the button and when the button is pressed the second window should show up. What happens is that when pressing the button a "merged" window is created that contains the button and the label.
import tkinter as tk
class Window1(tk.Frame):
def __init__(self):
tk.Frame.__init__(self)
self.grid()
self.btn = tk.Button(self,text = "button",command = self.run)
self.btn.grid(row = 0,column = 0)
def run(self):
tk.Frame.quit(self)
class Window2(tk.Frame):
def __init__(self):
tk.Frame.__init__(self)
self.grid()
self.label = tk.Label(self,text = "label ")
self.label.grid(row = 0,column = 0)
w = Window1()
w.mainloop()
v = Window2()
v.mainloop()
The first picture is before you press the button, the next one after you pressed the button. The problem seems that tk.Frame.quit(self) doesn't work correctly. I tried similar ways to close the window such as:
tk.Frame.destroy(self)
but that doesn't help either.
edit: I solved it by inheriting the class from tk.TK instead of tk.Frame
Frame doesn't create window - it only group elements. Tk() creates window.
To close window you have to destroy() object create by Tk(). But you don't creat it manually root = tk.Tk() so tkinter create it automatically, but you have no access to this root to close it.
If widget doesn't have parent then it uses root and your Frame does it too.
import tkinter as tk
class Window1(tk.Frame):
def __init__(self, master):
# send `root` to `Frame` as its parent
tk.Frame.__init__(self, master)
# `Frame` will keep `master as `self.master`
# so we don't have to do `self.master = master` manually
self.grid()
self.btn = tk.Button(self, text="Hello Button", command=self.run)
self.btn.grid(row=0, column=0)
def run(self):
# use `master` (`root`) to destroy it
self.master.destroy()
class Window2(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.grid()
self.label = tk.Label(self, text="Hello Label")
self.label.grid(row=0, column=0)
root = tk.Tk() # create main window as `root`
Window1(root) # send `root` to `Window1` and later to `Frame`
root.mainloop()
root = tk.Tk()
Window2(root)
root.mainloop()

Pararell instance of tkinter application window python

I want to create some simple tkinter python app (like StickyNotes on Windows), i have create the class mainApplication and i do not know how to by just simply triggering the button create another instance of this class which will be displayed pararell to other window (or even multiple windows). I know how to assigned function to pushButton, and other simple stuff but the problem is with this pararell window displaying. Thanks in advance for help.
class mainApplication(Frame):
_ids = count(0)
def __init__(self, parent):
""" """
self.id = next(self._ids)
Frame.__init__(self, parent)
self.parent = parent
self.parent.minsize(width=200,height=100)
self.parent.geometry(('%dx%d+%d+%d' % (200, 100, 1700, 0+self.id*100)))
self.initUI()
def initUI(self):
""" """
self.parent.title("a2l")
self.pack(fill=BOTH, expand=True)
style = Style()
style.configure("TFrame", background="#333")
frame1 = Frame(self, style="TFrame")
frame1.pack(fill=X)
self.lbl0 = Label(frame1, text="api", width=7, background="#333", foreground = "red")
self.lbl0.pack(side=TOP, padx=5, pady=5)
self.closeButton = Button(self, text="new", command = self.createNewInstance)
self.closeButton.pack(side=RIGHT, padx=5, pady=5)
#=======================================================================
# self.generateButton = Button(self, text="GENERATE", command = self.)
# self.generateButton.pack(side=RIGHT, padx=5, pady=5)
#=======================================================================
def createNewInstance(self):
y = mainApplication()
return y
if __name__ == "__main__":
root = Tk()
x = mainApplication(root).pack(side="top", expand=False)
Tk().mainloop()
You shouldn't create more than one Tk() window in one application with tkinter. Instead tkinter provides a widget called Toplevel which can be useful for this kind of thing.
It creates another window which can exist along side the Tk() window and alongside other Toplevel widgets.
You could use this to create a series of persistent windows with whatever text or widgets you wanted on them at any kind of trigger including a Button.
See my example below for a demonstration:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.top = [] #list to contain the Toplevel widgets
self.entry = Entry(self.root)
self.button = Button(self.root, text="Create window", command=self.command)
self.entry.pack()
self.button.pack()
def command(self): #called when button is pressed
self.top.append(Toplevel(self.root)) #adds new Toplevel to the list
Label(self.top[len(self.top)-1], text=self.entry.get()).pack() #Adds label equal to the entry widget to the new toplevel
root = Tk()
App(root)
root.mainloop()

How can I explicitly set the terminal size in python?

I would like to explicitly set the terminal size. Is there a cross-platform way to do this?
I want to make a game, showing fixed-sized art.
I used Tkinter (Thanks Steven Rumbalski!), because I don't mind using GUI if it's cross-platform. Basically, I set a window geometry and the size of my "art" label:
from Tkinter import *
#Assign a variable to the shown image to be able to change it
displayed_image = "test.gif"
class App:
def __init__(self, master):
#Make a frame to enclose the art with a relief
self.topframe = Frame(master, borderwidth=5, pady=5, relief=RIDGE)
#Pack the frame to draw it
self.topframe.pack()
#This frame will contain the prompt
self.frame = Frame(master)
self.frame.pack()
photo = PhotoImage(file="../Art/"+displayed_image)
art = Label(self.topframe, width=1280, height=720, image=photo)
art.photo = photo
art.pack()
prompt = Entry(self.frame, width=1280)
prompt.pack()
root = Tk()
root.wm_geometry("%dx%d" % (1300, 780))
app = App(root)
root.mainloop()
root.destroy()

tkinter canvas image is not displayed in class

I am trying to display an image in python using the tkinter canvas option. However, if I input it in a class, like below, it doesn't give an error but also doesn't show my image. The buttons are displayed correctly though. Also, if I take the code for generating this image out of the class it works correctly. I can't seem to find out what the problem is.
import Tkinter as tk
from Tkinter import *
class Board(tk.Frame):
def __init__(self,parent):
frame = Frame(parent)
frame.pack()
tk.Frame.__init__(self,parent)
frame2 = Frame(frame)
frame2.pack()
c=Canvas(frame2)
c.pack(expand=YES,fill=BOTH)
background=PhotoImage(file='Board.gif')
c.create_image(100,100,image=background,anchor='nw')
button = Button(frame, text="Next turn", command=self.next_turn)
button.pack()
button = Button(frame, text="Roll the dice", command=self.roll)
button.pack()
....
root = Tk()
board = Board(root)
board.pack()
root.mainloop()
You have to keep a reference to the PhotoImage. This is just and example (you can also use self.background instead of c.background):
c = Canvas(frame2)
c.pack(expand=YES,fill=BOTH)
c.background = PhotoImage(file='Board.gif')
c.create_image(100,100,image=c.background,anchor='nw')

Categories

Resources