I need a python messagebox with custom buttons.
I need something like this. I need it to return the button clicked. Like If I clicked 'A' it would return 'A'
I know about tkinter but I want to use this with pygame and can't get it to work.
Here is what I made with tkinter, not the perfect messagebox, but why not?
For the theme used you have to install it first, like:
pip install ttkthemes
Then the code
# imports
from tkinter import *
from tkinter import ttk
from ttkthemes import themed_tk as tktheme
from PIL import ImageTk, Image
from tkinter import messagebox
# making new themed window
root = tktheme.ThemedTk()
root.title('Take selection')
root.get_themes()
root.set_theme('vista')
# message to be shown by the box
message = 'Here is a custom messagebox.'
# defining functions
def click1():
root.destroy()
return 'A'
def click2():
root.destroy()
return 'B'
def click3():
root.destroy()
return 'C'
# creating white frame
frame1 = Frame(height=139, width=440, bg='white')
frame1.grid(row=0, column=0)
# creating gray frame
frame2 = ttk.Frame(height=50, width=440)
frame2.grid(row=1, column=0)
# importing the image, any image can be used(for the question mark)
dir = Image.open('Blue_question.png')
dir = dir.resize((50, 50), Image.ANTIALIAS)
img_prof = ImageTk.PhotoImage(dir)
img_label = Label(root, image=img_prof, bg='white')
img_label.grid(row=0, column=0, sticky=W, padx=25)
# defining main label
cust_messagebox = Label(root, text=message, font=('Arial', 10), bg='white')
cust_messagebox.grid(row=0, column=0, sticky=W, padx=(95, 0))
# defining buttons
button1 = ttk.Button(root, text='A', command=click1)
button1.grid(row=1, column=0, sticky=W, padx=30, ipadx=10)
button2 = ttk.Button(root, text='B', command=click2)
button2.grid(row=1, column=0, ipadx=10)
button3 = ttk.Button(root, text='C', command=click3)
button3.grid(row=1, column=0, sticky=E, padx=(0, 30), ipadx=10)
# keeping the app alive
root.mainloop()
With bigger messages you might want to increase the width of the frames and the play with the padding of the widgets too.
If any doubts or errors, do let me know.
Cheers
Related
So what I am trying to do is create a theme picker for my application
For example, the user could click on a the Green/Black button and it would change every widgets background to Black and it would change every widgets foreground to Green. Then they could click the Red/White button and it would do the same thing but change every widgets background to White and every widgets foreground to Red.
# Imports the tkinter library.
from tkinter import *
from tkmacosx import Button
# Pillow is a improved verison of PIL, stands for Python Image Library. Allows you to import image types like .jpg and .png
from PIL import ImageTk,Image
# Imports messagebox module from tkinter library.
from tkinter import messagebox
# Declare global variables
global selectedBackground
global selectedForeground
selectedBackground="white"
selectedForeground="red"
# Tk() helps to display the root window and manages all the other components of the tkinter application and assigns it to root.
root = Tk()
root.eval("tk::PlaceWindow . center")
root.configure(bg=selectedBackground)
cipherButton = Button(root, text=" Cipher ", padx=40, pady=20, command=openCipher, borderwidth=0, fg="#22fd35", bg="black", highlightbackground="#22fd35").grid(row=1, column=0)
decipherButton = Button(root, text="Decipher", padx=40, pady=20, command=openDecipher, borderwidth=0, fg="#22fd35", bg="black", highlightbackground="#22fd35").grid(row=1, column=1)
spacer1 = Label(root, text=" ", padx=10, pady=1, background="black").grid(row=4, column=1)
quitButton = Button(root, text="Exit d3cryptt", padx=10, pady=5, command=root.quit, borderwidth=0, fg="#22fd35", bg="black", highlightbackground="#22fd35").grid(row=5, column=0, columnspan=2)
spacer2 = Label(root, text=" ", padx=10, pady=1, background=selectedBackground).grid(row=6, column=1)
changecolour = Button(root, text="change colour", padx=1, pady=5, background="black", command=changeColour).grid(row=7, column=0)
#Enter the event main loop
root.mainloop()
I have tried using a function. Something like this.
def changeColour():
selectedBackground="black"
selectedForeground="#22fd35"
changecolour = Button(root, text="change colour", padx=1, pady=5, background="black", command=changeColour).grid(row=7, column=0)
But that doesn't work. I think a function is the right way to go, but I may be wrong.
I will also need this 'theme' to carry on to any other windows that are created from this window. I think I can just do that by using lambda in the command section of the widget.
Widget.config(bg=color) is what your looking for.
Here is a small example of a theme-changing app:
from tkinter import *
from tkmacosx import Button
root = Tk()
def changethemetoblack():
root.config(bg="#000000")
def changethemetowhite():
root.config(bg="#ffffff")
def changethemetored():
root.config(bg="#ff0000")
themeblackbutton = Button(root, text="Change Theme To Black", command=changethemetoblack, bg="#000000", fg="#ffffff")
themewhitebutton = Button(root, text="Change Theme To White", command=changethemetowhite)
themeredbutton = Button(root, text="Change Theme To Red", command=changethemetored, bg="#ff0000", fg="#ffffff")
themeblackbutton.pack()
themewhitebutton.pack()
themeredbutton.pack()
root.mainloop()
I'll try to change it so that it applies for your code.
However, your provided script does not seem to be a working one. I assume this is because it is only a snippet of the real one. I'm not pushing for your entire code, but edit it so we can run it. Ex. openCipher method is causing errors as we have not defined it.
An example of what I want to get:
Main program:
from tkinter import *
import tkinter as tk
import module
main_window = Tk()
def createCanvas():
canvas = Canvas(main_window, bg="grey")
canvas.grid(row=1, column=0, columnspan=2)
def resetCanvas():
canvas.destroy()
createCanvas()
button1 = Button(main_window, text="launch module", command=module.moduleFunction)
button1.grid(row=0, column=0)
button2 = Button(main_window, text="reset canvas", command=resetCanvas)
button2.grid(row=0, column=1)
createCanvas()
main_window.mainloop()
Module:
from tkinter import *
import tkinter as tk
from tkinter import Toplevel
def moduleFunction():
child_window = Toplevel()
def resetCanvasFromModule():
# THE QUESTION!
resetCanvas()
button3 = Button(child_window, text="reset canvas from module", command=resetCanvasFromModule)
button3.grid(row=0, column=0)
Obviously this doesn't work, since resetCanvas() isn't defined inside the module, but if I define it, it will try to destroy canvas, which isn't defined in the module, so it won't work either.
So, what would I have to do to get the effect I want?
P.S.: I have tried with 'global', without success.
Can't you just pass the element?
like this
from tkinter import *
canvas = None
def createCanvas():
global canvas
canvas = Canvas(main_window, bg="grey")
canvas.grid(row=1, column=0, columnspan=2)
def ResetCanvasFromModule():
global canvas
canvas.forget()
createCanvas()
button1 = Button(main_window, text="create canvas", command=createCanvas)
button1.grid(row=0, column=0)
button2 = Button(main_window, text="reset canvas", command=ResetCanvas)
button2.grid(row=0, column=1)
Please let me know If this helped you, if not comment so I can edit my answer
Thanks for your help guys.
Passing resetCanvas() as a parameter to moduleFunction(), and a lambda as button1 command, works fine.
This is my working example code(maybe in the future it can be useful to a newbie like me):
Main code:
from tkinter import *
import tkinter as tk
import module
main_window = Tk()
def createCanvas():
global canvas
canvas = Canvas(main_window, bg="grey")
canvas.grid(row=1, column=0, columnspan=2)
return
canvas
def resetCanvas():
canvas.destroy()
createCanvas()
button1 = Button(main_window, text="launch module", command=lambda:[module.moduleFunction(resetCanvas)])
button1.grid(row=0, column=0)
button2 = Button(main_window, text="reset canvas", command=resetCanvas)
button2.grid(row=0, column=1)
createCanvas()
main_window.mainloop()
Module:
from tkinter import *
import tkinter as tk
from tkinter import Toplevel
def moduleFunction(resetCanvas):
child_window = Toplevel()
def resetCanvasFromModule():
resetCanvas()
button3 = Button(child_window, text="reset canvas from module", command=resetCanvasFromModule)
button3.grid(row=0, column=0)
Thanks a lot.
I am trying to change the color of a Tkinter label when ever the user clicks the check button. I am having trouble writing the function correctly and connecting that to the command parameter.
Here is my code:
import Tkinter as tk
root = tk.Tk()
app = tk.Frame(root)
app.pack()
label = tk.Label(app, bg="white", pady=5, font=(None, 1), height=20, width=720)
checkbox = tk.Checkbutton(app, bg="white", command=DarkenLabel)
label.grid(row=0, column=0, sticky="ew")
checkbox.grid(row=0, column=0, sticky="w")
def DarkenLabel():
label.config(bg="gray")
root.mainloop()
Thank you
In your code, command=DarkenLabel is unable to find reference to the function DarkenLabel. Thus you need to define the function above that line, so you may use your code as following:
import Tkinter as tk
def DarkenLabel():
label.config(bg="gray")
root = tk.Tk()
app = tk.Frame(root)
app.pack()
label = tk.Label(app, bg="white", pady=5, font=(None, 1), height=20, width=720)
checkbox = tk.Checkbutton(app, bg="white", command=DarkenLabel)
label.grid(row=0, column=0, sticky="ew")
checkbox.grid(row=0, column=0, sticky="w")
root.mainloop()
Hope it helps!
I am trying to get the input from text box and trying to write them to a file:
I get the error as: retrieve_input is not defined.
Please help me to rectify my code:
coding:
import tkinter as tki
class App(object):
def __init__(self,root):
self.root = root
# create a Frame for the Text and Scrollbar
txt_frm = tki.Frame(self.root, width=600, height=400)
txt_frm.pack(fill="both", expand=True)
# ensure a consistent GUI size
txt_frm.grid_propagate(False)
self.txt1 = tki.Text(txt_frm, borderwidth=3, relief="sunken", height=4,width=55)
self.txt1.config(font=("consolas", 12), undo=True, wrap='word')
self.txt1.grid(row=0, column=1, sticky="nsew", padx=2, pady=2)
scrollb1 = tki.Scrollbar(txt_frm, command=self.txt1.yview)
scrollb1.grid(row=0, column=2, sticky='nsew')
self.txt1['yscrollcommand'] = scrollb1.set
button = tki.Button(self,text=u"Click command=retrieve_input)
button.grid(column=1,row=0)
def retrieve_input():
input = self.txt1.get("0.0",'END-1c')
with open('hello.txt','w') as f:
f.wite(input)
root = tki.Tk()
app = App(root)
root.mainloop()
In addition to the obvious typos, the problem is this line:
button = tki.Button(self,text="Click", command = self.retrieve_input)
Notice that the first parameter you pass to tk.Button is self. The first argument must be a widget, but you're giving it self which is not a widget. Perhaps you meant to use txt_form instead?
I'm creating a simple Tkinter gui. However, something appears to be going haywire. Nothing is actually being 'pack'ed to the frame. Can anyone spot what I've done wrong? (Other than the issues caused by using 'from Tkinter import *', and the apparently un-useful 'do_nothing()' function.
#/usr/bin/python
from Tkinter import *
class gui:
def __init__(self, parent):
f = Frame(parent, width=300, height=500)
f.pack(padx=30, pady=15)
self.label = Label(f, text="Japanese Trainer")
self.label.pack(side=TOP, padx=10, pady=12)
self.txtlbl = Entry(f, justify=CENTER, text="", font=("Calibri", 15, "bold"), width=37)
self.txtlbl.pack()
self.txtlbl.grid(row=1, rowspan=2, sticky=E, pady=10, padx=40)
self.button0 = Button(f, text="Kana Trainer", width=20, command=self.do_nothing)
self.button0.pack()
self.button0.grid(row=3, rowspan=2, sticky=W, pady=10, padx=40)
self.button1 = Button(f, text="Vocab Trainer", width=20, command=self.do_nothing)
self.button1.pack()
self.button1.grid(row=3, rowspan=2, sticky=E, pady=10, padx=40)
def do_nothing(self):
self.txtlbl.delete(0, END)
self.txtlbl.insert(END, "Command did nothing...")
root = Tk()
root.title('Eg.')
app = gui(root)
root.mainloop()
You are mixing grid and pack in the same master window. You can't do that. Each one will potentially resize the widgets they manage, and each will respond to resizes in the widgets they manage. So, pack will resize the widgets to fit, grid will recognize the change and try to resize widgets to fit, pack will recognize the change and try to resize widgets to fit, ... resulting in an endless loop.
You can use pack and grid together in the same program, but you cannot use them to manage the same container.