Related
I want to make radiobutton transparent on canvas image to make it look good, I tried passing lots of option parameters to radiobutton to somehow make it look better but nothing works.
Here is the code I am working with...
from tkinter import *
from tkinter import ttk
from tkinter.ttk import *
from PIL import ImageTk, Image
from tkinter import messagebox
class GUI_Prog:
def __init__(self):
root = Tk()
root.title("Risk Analysis")
root.geometry("1100x630")
r = IntVar()
#Setting up Canvas :
my_canvas = Canvas(root, width=1100, height=630)
my_canvas.pack(fill="both", expand=True)
#Background :
img = Image.open("diagnosis.png")
img = img.resize((1100,630), Image.ANTIALIAS)
bg = ImageTk.PhotoImage(img)
my_canvas.create_image(0,0,image=bg,anchor="nw")
#Creating title text :
my_canvas.create_text(540,40,text="Risk Analysis", font=("Times, 30"), fill = "white")
my_canvas.create_text(140,100,text="1) Do you smoke?", font=("helvetica, 15"), fill = "black")
but_1 = Radiobutton(root, text="yes", variable=r, value=1)
my_canvas.create_window(60, 150, window=but_1)
but_2= Radiobutton(root, text="no", variable=r, value=2)
my_canvas.create_window(150, 150, window=but_2)
mainloop()
obj = GUI_Prog()
Well I created my own RadioButton class but it only works on tkinter.Canvas:
from tkinter import *
from tkinter import ttk
from tkinter.ttk import *
from PIL import ImageTk, Image
from tkinter import messagebox
# Taken from: https://stackoverflow.com/a/17985217/11106801
def _create_circle(self, x, y, r, **kwargs):
return self.create_oval(x-r, y-r, x+r, y+r, **kwargs)
Canvas.create_circle = _create_circle
class Radiobutton:
def __init__(self, canvas, text="", variable=None, value=0, radius=10,
fill="black"):
self.canvas = canvas
self.variable = variable
self.fill = fill
self.text = text
self.value = value
self.radius = radius
self.variable.trace("w", self.redraw)
self.circle = None
def put(self, x, y):
self.x = x
self.y = y
self.canvas.create_circle(x, y, self.radius, outline=self.fill)
self.canvas.create_text(x + 2*self.radius, y, text=self.text,
fill=self.fill, anchor="w")
self.redraw()
self.canvas.bind("<Button-1>", self.select, add=True)
def select(self, event):
if (self.x - event.x)**2 + (self.y - event.y)**2 <= self.radius**2:
self.variable.set(self.value)
self.redraw()
def create_circle(self):
self.circle = self.canvas.create_circle(self.x, self.y, self.radius-4,
outline=self.fill,
fill=self.fill)
def redraw(self, *args):
if self.value == self.variable.get():
if self.circle is None:
self.create_circle()
else:
if self.circle is not None:
self.canvas.delete(self.circle)
self.circle = None
class GUI_Prog:
def __init__(self):
root = Tk()
root.title("Risk Analysis")
root.geometry("1100x630")
r = IntVar()
#Setting up Canvas:
my_canvas = Canvas(root, width=1100, height=630)
my_canvas.pack(fill="both", expand=True)
#Background:
img = Image.open("diagnosis.png")
img = img.resize((1100, 630), Image.ANTIALIAS)
bg = ImageTk.PhotoImage(img)
my_canvas.create_image(0, 0, image=bg, anchor="nw")
#Creating title text:
my_canvas.create_text(540, 40, text="Risk Analysis",
font=("Times", 30), fill="white")
my_canvas.create_text(140, 100, text="1) Do you smoke?",
font=("helvetica", 15), fill="black")
but_1 = Radiobutton(my_canvas, text="yes", variable=r, value=1,
fill="white")
but_1.put(60, 150)
but_2 = Radiobutton(my_canvas, text="no", variable=r, value=2,
fill="white")
but_2.put(150, 150)
r.set(1)
root.mainloop()
obj = GUI_Prog()
You create it as normal but you pass in the <tkinter.Canvas> as its master. After that you can just call .put with the position where you want it to be created. This is a very patchy solution so if someone else posts a better solution, I will delete this.
I am working on a project which kind of basic paint in python and I'm stuck on this flood fill part, it won't update the color of the object and there's no error so I can't figure out which part is wrong.
from tkinter import *
from tkinter.colorchooser import askcolor
coords = {"x1":0,"y1":0,"x2":0,"y2":0}
lines = []
class Filling():
def __init__(self, main):
self.main = main
self.main.title('Filling')
self.main.geometry("800x620")
btncir=Button(main, text="CIRCLE", fg='black', width=8, command=self.circle)
btncir.place(x=10, y=200)
btnfill=Button(main, text="FILL", fg='black', width=8, command=self.clickfillrec)
btnfill.place(x=10, y=250)
btnclear=Button(main, text="COLOR", fg='black', width=8, command=self.color_choice)
btnclear.place(x=10, y=300)
self.canvas = Canvas(self.main, bg='white', bd=5, relief=RIDGE, height=600, width=700)
self.canvas.place(x=80, y=0)
def circle(self):
self.canvas.bind("<ButtonPress-1>", self.circle_click)
self.canvas.bind("<B1-Motion>", self.drag)
def circle_click(self, e):
coords["x1"] = e.x
coords["y1"] = e.y
lines.append(self.canvas.create_oval(coords["x1"],coords["y1"],coords["x1"],coords["y1"]))
def drag(self, e):
coords["x2"] = e.x
coords["y2"] = e.y
self.canvas.coords(lines[-1], coords["x1"],coords["y1"],coords["x2"],coords["y2"])
def color_choice(self):
self.DEFAULT_COLOR = self.color
self.color = askcolor()
def clickfillrec(self):
self.canvas.bind("<Button-1>", self.ffillrec)
self.canvas.bind("<B1-Motion>", self.nothing)
def nothing(self, event):
pass
def ffillrec(self, event):
item = self.canvas.find_closest(event.x, event.y)
x = event.x
y = event.y
current_color = self.canvas.itemcget(item, 'fill')
if (x > 0) and (self.canvas.itemcget((event.x-1, event.y), 'fill')) == current_color:
self.canvas.itemconfig((event.x-1, event.y), fill = self.color)
if (y > 0) and (self.canvas.itemcget((event.x, event.y-1), 'fill')) == current_color :
self.canvas.itemconfig((event.x, event.y-1), fill = self.color)
if (x < self.canvas.winfo_screenwidth()) and (self.canvas.itemcget((event.x+1, event.y), 'fill')) == current_color :
self.canvas.itemconfig((event.x+1, event.y), fill = self.color)
if (y < self.canvas.winfo_screenheight()) and (self.canvas.itemcget((event.x, event.y+1), 'fill')) == current_color :
self.canvas.itemconfig((event.x, event.y+1), fill = self.color)
main = Tk()
p = Filling(main)
main.mainloop()
I tried main.update() and self.canvas.update_idletasks() but still doesn't work
Edit: thanks to #jasonharper's comments below I can ask a more informed question:
I have a main app, and a separate module snipping_tool.py that handles creating a new window with the option to screen-snip or select an image file. I want snipping_tool.py to provide an image to the main app, but currently I'm trying to retrieve the image too soon (before the snipping_tool window even opens).
How can I wait until the user selects or grabs an image before I try to assign MyNewObject.selected_image? Should I use a binding or some event handler? (I have limited experience with both). Or is there a simpler way?
Simplified Main App:
import tkinter as tk
import snipping_tool
class MinCodeEx:
def __init__(self, master):
self.master = master
self.ButtonA = tk.Button(width=60,height=40,command = lambda: self.UpdateImg(master))
self.ButtonA.pack()
def UpdateImg(self, master):
newDialog = snipping_tool.AcquireImage(self.master)
# self.ButtonA['image'] = newDialog.image_selected
#if newDialog.image_selected:
self.ButtonA.config(image=newDialog.image_selected)
print(newDialog.image_selected)
def main():
root = tk.Tk()
MinCodeEx(root)
root.mainloop()
if __name__ == '__main__':
main()
snipping_tool.py
returns None instead of an image file since I'm trying to retrieve the selected_image too soon.
import tkinter as tk
from PIL import ImageGrab, ImageTk, Image
import cv2
import numpy as np
from tkinter import filedialog
class ScreenSnip(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.image = None
def get_snip(self):
self.configure(cursor='cross')
self.attributes('-fullscreen', True)
self.attributes('-alpha', 0.4)
self.canvas = tk.Canvas(self, bg='dark gray')
self.canvas.pack(fill='both', expand=True)
self.begin_x = 0
self.begin_y = 0
self.end_x = 0
self.end_y = 0
self.click_drag = False
self.canvas.create_rectangle(0, 0, 0, 0, outline='#0052d6', width=2, fill='white', tags='snip_rect')
self.canvas.bind('<ButtonPress-1>', self.mousePressEvent)
self.canvas.bind('<B1-Motion>', self.mouseMoveEvent)
self.canvas.bind('<ButtonRelease-1>', self.mouseReleaseEvent)
print('Capture the screen...')
def mousePressEvent(self, event):
self.begin_x = event.x
self.begin_y = event.y
print(self.begin_x,self.begin_y)
def mouseMoveEvent(self, event):
self.click_drag = True
self.end_x = event.x
self.cur_y = event.y
width = self.end_x - self.begin_x
height = abs(width * 2/3)
if self.cur_y < self.begin_y:
height *= -1
self.end_y = self.begin_y + height
self.canvas.coords('snip_rect', self.begin_x, self.begin_y, self.end_x, self.end_y)
def mouseReleaseEvent(self, event):
self.destroy()
self.master.update_idletasks()
self.master.after(100) # give time for screen to be refreshed so as not to see the blue box on the screenshot
if not self.click_drag: # if the user just clicks, instead of clicking and dragging
self.begin_x -= 300
self.begin_y += 200
self.end_x = self.begin_x + 600
self.end_y = self.begin_y - 400
x1 = min(self.begin_x, self.end_x)
y1 = min(self.begin_y, self.end_y)
x2 = max(self.begin_x, self.end_x)
y2 = max(self.begin_y, self.end_y)
self.img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
self.image = ImageTk.PhotoImage(self.img)
#self.img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
#cv2.imshow('Captured Image', self.img)
#cv2.waitKey(0)
font1 = ("arial", 18, "bold")
class AcquireImage:
def __init__(self, master):
self.master = master
self.nWin = tk.Toplevel(master)
self.fontA = ("arial", 20, "bold")
self.frame = tk.Frame(self.nWin, bg="#1B2631")
self.frame.pack(fill="both", expand=True)
self.button1 = tk.Button(self.frame, text="Select Image File", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command =lambda: self.show_dialogs(1))
self.button1.grid(row=0, column=0, sticky="nsew")#, padx=10, pady=10)
self.button2 = tk.Button(self.frame, text="Get Screen Snip", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command=lambda: self.show_dialogs(2))
self.button2.grid(row=0, column=1, sticky="nsew")#, padx=10, pady=10)
self.image_selected = None
def show_dialogs(self, method): ################### THIS IS WHERE THE IMAGE IS SELECTED ###########
if method == 1:
ret = filedialog.askopenfilename()
if ret:
self.image_selected = ImageTk.PhotoImage(file = ret)
self.nWin.destroy()
elif method == 2:
newWin = ScreenSnip(self.nWin)
newWin.get_snip()
ret = newWin.image
if ret:
self.image_selected = ret
def main():
root = tk.Tk()
AcquireImage(root)
root.mainloop()
if __name__ == '__main__':
main()
#jasonharper was right. This solution is derived from his comments.
When I create an instance of AcquireImage I also pass ButtonA as a parameter so that I can modify its image. Within AcquireImage I first get a new image (either by snipping it, or with the file explorer) and then to avoid garbage collection immediately deleting it, I save it by assigning it to ButtonA.img. (I first create the .img part of ButtonA in the main program). Once I have the image, I can then assign it.
I probably could have also solved this issue by creating a function
within the main program that changes the image of whatever widget is
passed to it as a parameter. I could then pass this function to the
instance of AcquireImage with ButtonA as a parameter. It might
have looked something like this in the main program: def callback(i_file): ButtonA['image'] = i_file newDialog = snipping_tool.AcquireImage(self.master, self.callback) Later I
would have AcquireImage initialized/defined with
self.some_function as the second argument (after master), and I
could pass the image file to it. At least that's how I probably could
have done it.
This is how I actually solved it:
MAIN APP
import tkinter as tk
import snipping_tool
waitingforImage = True
class MinCodeEx:
global waitingforImage
def __init__(self, master):
self.master = master
self.ButtonA = tk.Button(width=60,height=40,command = lambda: self.UpdateImg())
self.ButtonA.pack()
self.ButtonA.img = None
def UpdateImg(self):
newDialog = snipping_tool.AcquireImage(self.master, self.ButtonA)
def main():
root = tk.Tk()
MinCodeEx(root)
root.mainloop()
if __name__ == '__main__':
main()
snipping_tool.py
import tkinter as tk
from PIL import ImageGrab, ImageTk, Image
from tkinter import filedialog
class ScreenSnip(tk.Toplevel):
def __init__(self, master, changeThis):
super().__init__(master)
self.image = None
self.master = master
self.changeThis = changeThis
def get_snip(self):
self.configure(cursor='cross')
self.attributes('-fullscreen', True)
self.attributes('-alpha', 0.4)
print("attempting to create tk.Canvas for get_snip")
self.canvas = tk.Canvas(self, bg='dark gray')
self.canvas.pack(fill='both', expand=True)
self.begin_x = 0
self.begin_y = 0
self.end_x = 0
self.end_y = 0
self.click_drag = False
self.canvas.create_rectangle(0, 0, 0, 0, outline='#0052d6', width=2, fill='white', tags='snip_rect')
self.canvas.bind('<ButtonPress-1>', self.mousePressEvent)
self.canvas.bind('<B1-Motion>', self.mouseMoveEvent)
self.canvas.bind('<ButtonRelease-1>', self.mouseReleaseEvent)
print('Capture the screen...')
def mousePressEvent(self, event):
self.begin_x = event.x
self.begin_y = event.y
print(self.begin_x,self.begin_y)
def mouseMoveEvent(self, event):
self.click_drag = True
self.end_x = event.x
self.cur_y = event.y
width = self.end_x - self.begin_x
height = abs(width * 2/3)
if self.cur_y < self.begin_y:
height *= -1
self.end_y = self.begin_y + height
self.canvas.coords('snip_rect', self.begin_x, self.begin_y, self.end_x, self.end_y)
def mouseReleaseEvent(self, event):
self.destroy()
self.master.update_idletasks()
self.master.after(100) # give time for screen to be refreshed so as not to see the blue box on the screenshot
if not self.click_drag: # if the user just clicks, instead of clicking and dragging
self.begin_x -= 300
self.begin_y += 200
self.end_x = self.begin_x + 600
self.end_y = self.begin_y - 400
x1 = min(self.begin_x, self.end_x)
y1 = min(self.begin_y, self.end_y)
x2 = max(self.begin_x, self.end_x)
y2 = max(self.begin_y, self.end_y)
self.img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
print("getting image grab")
self.changeThis.img = ImageTk.PhotoImage(self.img)
self.changeThis['image'] = self.changeThis.img
font1 = ("arial", 18, "bold")
class AcquireImage:
def __init__(self, master, changeThis):
self.master = master
self.changeThis = changeThis
self.nWin = tk.Toplevel(master)
self.fontA = ("arial", 20, "bold")
self.frame = tk.Frame(self.nWin, bg="#1B2631")
self.frame.pack(fill="both", expand=True)
self.button1 = tk.Button(self.frame, text="Select Image File", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command =lambda: self.show_dialogs(1))
self.button1.grid(row=0, column=0, sticky="nsew")#, padx=10, pady=10)
self.button2 = tk.Button(self.frame, text="Get Screen Snip", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command=lambda: self.show_dialogs(2))
self.button2.grid(row=0, column=1, sticky="nsew")#, padx=10, pady=10)
self.image_selected = None
def show_dialogs(self, method):
if method == 1:
ret = filedialog.askopenfilename() #filedialog.askopenfilename(initialdir='/home/user/images/')
self.changeThis.img = ImageTk.PhotoImage(file = ret)
self.changeThis['image'] = self.changeThis.img
elif method == 2:
print("attempting ScreenSnip")
newWin = ScreenSnip(self.master, self.changeThis)
newWin.get_snip()
self.nWin.destroy()
def main():
root = tk.Tk()
bt = tk.Button(root, width = 20, height = 20)
bt.pack()
ScreenSnip(root, bt)
#AcquireImage(root,bt)
root.mainloop()
if __name__ == '__main__':
main()
I still need to fix one unrelated thing -- the button doesn't fit the size of the image that I select or grab. It always ends up being a small square.
I'm having trouble with two tkinter classes that I want to interact. I think it comes from my lack of understanding of the Tk.Toplevel. Instead of creating an entirely new full-screen window for screen-grabbing, my code gives an error:
AttributeError: '_tkinter.tkapp' object has no attribute 'mousePressEvent'
Can someone help me understand the hierarchy of parent-child relationships in my code? I'm not asking anyone to rewrite my code, I just want to understand what I already have, so I can figure out what's wrong. I haven't found many examples in SO of multiple classes that interact with multiple windows - so it's hard to grasp the inter-workings of inheritance.
This is the structure I think I have:
root
object: AquireImage
method: show_dialogs()
object: ScreenSnip
method: get_snip()
method: mousePressEvent()
method: mouseMoveEvent()
method: mouseReleaseEvent()
Is this accurate?
CODE
import tkinter as tk
from PIL import ImageGrab, ImageTk, Image
import cv2
import numpy as np
from tkinter import filedialog
class ScreenSnip(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
def get_snip(self):
self.configure(cursor='cross')
self.attributes('-fullscreen', True)
self.attributes('-alpha', 0.4)
self.canvas = tk.Canvas(self, bg='dark gray')
self.canvas.pack(fill='both', expand=True)
self.begin_x = 0
self.begin_y = 0
self.end_x = 0
self.end_y = 0
self.click_drag = False
self.canvas.create_rectangle(0, 0, 0, 0, outline='#0052d6', width=2, fill='white', tags='snip_rect')
self.canvas.bind('<ButtonPress-1>', self.mousePressEvent)
self.canvas.bind('<B1-Motion>', self.mouseMoveEvent)
self.canvas.bind('<ButtonRelease-1>', self.mouseReleaseEvent)
print('Capture the screen...')
def mousePressEvent(self, event):
self.begin_x = event.x
self.begin_y = event.y
print(self.begin_x,self.begin_y)
def mouseMoveEvent(self, event):
self.click_drag = True
self.end_x = event.x
self.cur_y = event.y
width = self.end_x - self.begin_x
height = abs(width * 2/3)
if self.cur_y < self.begin_y:
height *= -1
self.end_y = self.begin_y + height
self.canvas.coords('snip_rect', self.begin_x, self.begin_y, self.end_x, self.end_y)
def mouseReleaseEvent(self, event):
self.destroy()
self.master.update_idletasks()
self.master.after(100) # give time for screen to be refreshed so as not to see the blue box on the screenshot
if not self.click_drag: # if the user just clicks, instead of clicking and dragging
self.begin_x -= 300
self.begin_y += 200
self.end_x = self.begin_x + 600
self.end_y = self.begin_y - 400
x1 = min(self.begin_x, self.end_x)
y1 = min(self.begin_y, self.end_y)
x2 = max(self.begin_x, self.end_x)
y2 = max(self.begin_y, self.end_y)
img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
self.img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
cv2.imshow('Captured Image', self.img)
cv2.waitKey(0)
font1 = ("arial", 18, "bold")
class AcquireImage:
def __init__(self, master):
self.master = master
self.fontA = ("arial", 20, "bold")
self.frame = tk.Frame(master, bg="#1B2631")
self.frame.pack(fill="both", expand=True)
self.button1 = tk.Button(self.frame, text="Select Image File", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command =lambda: self.show_dialogs(1))
self.button1.grid(row=0, column=0, sticky="nsew")#, padx=10, pady=10)
self.button2 = tk.Button(self.frame, text="Get Screen Snip", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command=lambda: self.show_dialogs(2))
self.button2.grid(row=0, column=1, sticky="nsew")#, padx=10, pady=10)
self.image_selected = None
def show_dialogs(self, method):
if method == 1:
ret = filedialog.askopenfilename() #filedialog.askopenfilename(initialdir='/home/user/images/')
if ret:
self.image_selected = ImageTk.PhotoImage(file = ret)
self.master.destroy()
elif method == 2:
newWin = ScreenSnip.get_snip(self.master)
ret = newWin.img
if ret:
self.image_selected = ImageTk.PhotoImage(file = ret)
def main():
root = tk.Tk()
AcquireImage(root)
root.mainloop()
if __name__ == '__main__':
main()
This answer is derived from #jasonharper's comment:
Instances of ScreenSnip would indeed have a mousePressEvent
attribute. But you never create any such instance; instead, you
attempt to call get_snip() on the class itself, which ends up
providing a completely inappropriate value for its self parameter.
The mistake I made was here:
newWin = ScreenSnip.get_snip(self.master)
I tried to create a new object newWin without putting the parent in the correct place, and while calling the method get_snip at the same time. This is what solved the issue:
newWin = ScreenSnip(self.master)
newWin.get_snip()
First create the object ScreenSnip from the class, with the parent
then call the method `get_snip'
i have a small ui programm and i need to display a calendar in it or a date picker . (NOTE : userid and password is root")**
i have tried this code :
from Tkinter import *
from PIL import Image, ImageTk
import ttkcalendar
class App():
def __init__(self):
pass
root = Tk()
root.configure(bg='black')
root.attributes('-alpha', 0.0)
def mainWindow(self):
self.root.geometry('{}x{}'.format(600,400))
self.root.attributes('-alpha', 1)
self.root.configure(bg='#404040')
self.ttkcal = ttkcalendar.Calendar(self.root,firstweekday=calendar.SUNDAY)
self.ttkcal.pack()
self.root.wm_title("time sheet management system")
# Create the toolbar as a frame
self.toolbar = Frame(self.root, borderwidth=1, relief='raised')
self.toolbar.configure( bg = '#838383')
# Load all the images first as PNGs and use ImageTk to convert
# them to usable Tkinter images.
self.img1 = Image.open('NewIcon.png')
self.useImg1 = ImageTk.PhotoImage(self.img1)
self.img2 = Image.open('LoadIcon.png')
self.useImg2 = ImageTk.PhotoImage(self.img2)
self.img3 = Image.open('SaveIcon.png')
self.useImg3 = ImageTk.PhotoImage(self.img3)
# Set up all the buttons for use on the toolbars.
newBtn = Button(self.toolbar, image=self.useImg1, command=self.callback)
newBtn.pack(side=LEFT, fill=X)
loadBtn = Button(self.toolbar, image=self.useImg2, command=self.callback)
loadBtn.pack(side=LEFT, fill=X)
saveBtn = Button(self.toolbar, image=self.useImg3, command=self.callback)
saveBtn.pack(side=LEFT, fill=X)
# Add the toolbar
self.toolbar.pack(side=TOP, fill=X)
"""
#create a frame
self.infoArea= Frame(self.root, borderwidth=2,height=40,width=100, relief='raised',bg='red')"""
self.root.mainloop()
"""
# Set up a Text box and scroll bar.
self.scrollbar = Scrollbar(self.root)
self.scrollbar.pack(side=RIGHT, fill=Y)
self.text = Text(self.root)
self.text.pack()
self.text.config(yscrollcommand=self.scrollbar.set)
self.scrollbar.config(command=self.text.yview)"""
def loginClick(self):
self.userid = self.txt1.get()
self.password = self.txt2.get()
print self.userid,self.password
if self.password == 'root' and self.userid == 'root':
self.wi.destroy()
self.mainWindow()
def callback(self):
print "A button was pressed"
def login(self):
self.wi = Toplevel (self.root)
#self.wi.geometry('{}x{}'.format(200,200))
self.wi.configure(bg='#404040')
self.wi.overrideredirect(1)
self.wi.update_idletasks()
self.w = self.wi.winfo_screenwidth()
self.h = self.wi.winfo_screenheight()
self.size = tuple(int(_) for _ in self.wi.geometry().split('+')[0].split('x'))
self.x = self.w/2 - self.size[0]/2
self.y = self.h/2 - self.size[1]/2
self.wi.geometry("%dx%d+%d+%d" % (self.size + (self.x, self.y)))
self.wi.geometry('{}x{}'.format(400,200))
self.frame1 = Frame ( self.wi,bg='#404040' )
self.frame1.pack(side=BOTTOM,fill=X)
self.butt1 = Button(self.frame1,text= "Cancel" , bg = '#838383',fg='white',command = self.wi.destroy)
self.butt1.pack(side=RIGHT,padx=1)
self.butt2 = Button(self.frame1,text= "Login" ,bg = '#838383',fg='white',command = self.loginClick)
self.butt2.pack(side=RIGHT)
"""self.frame2 = Frame ( self.wi,bg='green' )
self.frame2.pack(side=BOTTOM,fill=BOTH)"""
self.lab1 = Label (self.wi,text='UserID',bg='#404040',fg='white')
#self.lab1.pack(side=LEFT,padx=60,pady=20)
self.lab1.place(x=60,y=20)
self.lab2 = Label (self.wi,text='Password',bg='#404040',fg='white')
#self.lab1.pack(side=LEFT,padx=60,pady=20)
self.lab2.place(x=60,y=60)
self.txt1 = Entry( self.wi)
self.txt1.place(x=140,y=20)
self.txt2 = Entry( self.wi,show='*')
self.txt2.place(x=140,y=60)
"""
self.label = Label(self.wi,text="UserID",bg='#838383',fg='white')
self.label.place("""
self.wi.mainloop()
if __name__ == "__main__":
a = App()
#a.root.mainloop()
a.login()
but it is giving error that "name calendar not defined". how can i solve this ?
or is there any other way to implement a calendar or date picker in tkinter.
The code is using calendar module, but it is not importing the module.
self.ttkcal = ttkcalendar.Calendar(self.root, firstweekday=calendar.SUNDAY)
^^^^^^^^^^^^^^^
Simply adding following import statement will solve the problem.
import calendar