Expanding dateentry display from m/d/yy to mm/dd/yyyy? - python

Using dateentry from the tkcalendar python module, every time I select a date on the widget it shortens it to the m/d/yy format. I'd like it to expand to mm/dd/yyyy if possible, or at least for the year.
When using the set_date method, it will display whatever is inputted (string), but then reverts back to the shortened format once another date is clicked.
Is there any way to have it always display the full date? I can't seem to find a format parameter that would allow me to use %Y so that's why I ask.

This is possible without overriding _select since version 1.5.0, using the date_pattern argument (See documentation):
import tkinter as tk
from tkcalendar import DateEntry
window = tk.Tk()
DateEntry(window, locale='en_US', date_pattern='mm/dd/y').pack() # custom formatting
DateEntry(window, locale='en_US').pack() # default formatting
window.mainloop()
gives

If you just want to change how it appears upon selection, you can make a class that inherit DateEntry and override the _select method.
from tkcalendar import DateEntry
import tkinter as tk
root = tk.Tk()
class CustomDateEntry(DateEntry):
def _select(self, event=None):
date = self._calendar.selection_get()
if date is not None:
self._set_text(date.strftime('%m/%d/%Y'))
self.event_generate('<<DateEntrySelected>>')
self._top_cal.withdraw()
if 'readonly' not in self.state():
self.focus_set()
entry = CustomDateEntry(root)
entry._set_text(entry._date.strftime('%m/%d/%Y'))
entry.pack()
root.mainloop()

Related

Python, Tkinter - some general questions about the code

I have some general questions regarding working code below:
tkinter is library for graphic interface as I understand I can use it interchangeably with for example Kivy?
Would it be better to learn Kivy instead or other?
Lines import tkinter as tk and from tkinter import * do exactly the same, in the first one I have alias though?
In the code below, why do I have to use ttk in ttk.Progressbar?
I imported whole library with import tkinter as tk so why do i have to reimport ttk just for progress bar? (otherwise it is not working). I would expect to work sth. like tk.Progressbar
In the line btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress), why method "fnUpdateProgress" can't have any variables? Whenever I add any, the button stop working? -> for example btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress(24)) (ofc then some changes in def of the method itself)
I created progress bar (pb) as attribute of the class Test, but wolud it be better to define it as regular variable (without self)? To be honest, code works exactly the same.
Code:
import tkinter as tk
from tkinter import *
from tkinter import ttk
from CreateProgramMain import main
import GlobalVariables
class Test():
####################################################################################
def __init__(self):
self.Progress=0
self.root = tk.Tk()
self.root.title(GlobalVariables.strAppName)
self.root.geometry('400x200')
lbl = Label(self.root, text="Please choose environment.",font=("Arial Bold", 12))
lbl.grid(column=2, row=0,sticky='e')
def btnTestClicked():
main("TEST",self)
btnTest=tk.Button(self.root, text="Test Environment", command=btnTestClicked)
btnTest.grid(column=2, row=15)
#Place progress bar
pb = ttk.Progressbar(self.root,orient='horizontal',mode='determinate',length=200)
pb.grid(column=1, row=65, columnspan=2, padx=10, pady=20)
pb["value"]=self.Progress
pb["maximum"]=100
btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress)
btnProg.grid(column=2, row=75)
self.root.mainloop()
def fnUpdateProgress(self): #why i cant insert variable inside?
pb["value"]=self.Progress
self.Progress=self.Progress+5
pb.update()
app = Test()
Thank you
it is upto you. However, tkinter and kivy both have their own syntaxes, commands, and their own usages. It might be a little difficult to convert tkinter code to kivy.
it is upto you
Yes. In the first, you have imported tkinter as tk. In the second one. You have done a wild card import. You have imported everything
Tkinter is a folder containing various modules. It contains a file called ttk.py which you have to import to access ttk.
All other classes like Label, Entry, Tk is present in __init__.py
you have to use lambda for it. If you call the function, it will be executed wlright away and the returned value is kept as the command.
Doing command=self.fnUpdateProgress(24)) will execute the function right away. Then, the returned value is kept as a command. Here, it returns None. So the command is nothing or the button is useless.
Use a lambda expression command=lambda: self.fnUpdateProgress(24))
if you don't add self it will be local to the function only. To access ot outside, it would have to be declared global, which is the point to avoid while using classes

Tkinter text widget - Why does INSERT not work as text index?

I have a problem that annoys me. I am currently building a small app with a Tkinter GUI.
On the front page, I want some introductory text in either a text or a scrolledtext widget. The code examples I've come across uses keywords such as INSERT, CURRENT and END for indexation inside the widget.
I have literally copy pasted the below code into my editor, but it doesn't recognise INSERT (throws error: "NameError: name 'INSERT' is not defined"):
import tkinter as tk
from tkinter import scrolledtext
window = tk.Tk()
window.title("test of scrolledtext and INSERT method")
window.geometry('350x200')
txt = scrolledtext.ScrolledText(window,width=40,height=10)
txt.insert(INSERT,'You text goes here')
txt.grid(column=0,row=0)
window.mainloop()
I can get the code to work if I change [INSERT] with [1.0], but it is very frustrating that I cannot get INSERT to work, as I've seen it in every example code I've come across
Use tk.INSERT instead of only INSERT. Full code is shown.
import tkinter as tk
from tkinter import scrolledtext
window = tk.Tk()
window.title("test of scrolledtext and INSERT method")
window.geometry('350x200')
txt = scrolledtext.ScrolledText(window,width=40,height=10)
txt.insert(tk.INSERT,'You text goes here')
txt.grid(column=0,row=0)
window.mainloop()
You don't need to use the tkinter constants. I personally think it's better to use the raw strings "insert", "end", etc. They are more flexible.
However, the reason the constants don't work for you is that you're not directly importing them. The way you're importing tkinter, you need to use tk.INSERT, etc.
INSERT could not be used directly.
You can use it in the past just because you used this in the past:
from tkinter import * # this is not a good practice
INSERT,CURRENT and END are in tkinter.constants.Now in your code,you even didn't import them.
If you want to use them,you can use
from tkinter.constants import * # not recommended
...
txt.insert(INSERT,'You text goes here')
Or
from tkinter import constants
...
txt.insert(constants.INSERT,'You text goes here') # recommend
If didn't want to import them,you can also use:
txt.insert("insert",'You text goes here')
Edit:I found in the source code of tkinter,it had import them,reboot's answer is also OK.

Python Tkinter ttk calendar

I am trying to create a drop down calendar for a date entry.
Below is a portion of my code:
The drop down portion of it dosen't work and I can't seem to find the syntax for DateEntry() of ttk calendar anywhere to include the calendar widget option!
#creating the frame
from tkinter import *
from tkcalendar import *
root = Tk()
f1=Frame(root,width=1500,height=100,relief=SUNKEN,bd=4,bg='light steel blue')
f1.pack(side=TOP)
f2=Frame(root,width=1500,height=550,relief=SUNKEN,bd=4,bg='white')
f2.pack()
f3=Frame(root,width=1600,height=100,relief=SUNKEN,bd=4,bg='white')
f3.pack(side=BOTTOM)
#Creating the date column
l4=Label(f2,text='DATE',font=('tahoma',20,'bold'),fg='black',anchor='w')
l4.grid(row=0,column=3)
cal=DateEntry(f2,dateformat=3,width=12, background='darkblue',
foreground='white', borderwidth=4,Calendar =2018)
cal.grid(row=1,column=3,sticky='nsew')
I want it to look like this:
UPDATE: I have fixed the issue and published a new version of tkcalendar.
EDIT: the problem is that in Windows, the drop-down does not open when the downarrow button is clicked. It seems that it comes from the default ttk theme for Windows because it works with other themes. So the workaround is to switch theme and use 'clam' for instance ('alt' should work as well). Meanwhile, I will look into it and see if I can fix the DateEntry for the other themes and release a new version (https://github.com/j4321/tkcalendar/issues/3).
I am not sure what you want to achieve exactly with the DateEntry, but if your goal is to make it look like the one in the picture, it can be done the following way:
import tkinter as tk
from tkinter import ttk
from tkcalendar import DateEntry
from datetime import date
root = tk.Tk()
# change ttk theme to 'clam' to fix issue with downarrow button
style = ttk.Style(root)
style.theme_use('clam')
class MyDateEntry(DateEntry):
def __init__(self, master=None, **kw):
DateEntry.__init__(self, master=None, **kw)
# add black border around drop-down calendar
self._top_cal.configure(bg='black', bd=1)
# add label displaying today's date below
tk.Label(self._top_cal, bg='gray90', anchor='w',
text='Today: %s' % date.today().strftime('%x')).pack(fill='x')
# create the entry and configure the calendar colors
de = MyDateEntry(root, year=2016, month=9, day=6,
selectbackground='gray80',
selectforeground='black',
normalbackground='white',
normalforeground='black',
background='gray90',
foreground='black',
bordercolor='gray90',
othermonthforeground='gray50',
othermonthbackground='white',
othermonthweforeground='gray50',
othermonthwebackground='white',
weekendbackground='white',
weekendforeground='black',
headersbackground='white',
headersforeground='gray70')
de.pack()
root.mainloop()
I created a class inheriting from DateEntry to add the label with today's date below the calendar and to create a black border around the drop-down (self._top_cal is the Toplevel containing the calendar).
Then, I created an instance of MyDateEntry and with all calendar options needed to make it look like the picture. In addition, I used the year, month, day options to define the initial date inside the entry.
Here is the result:

Scroll tkinter ttk Entry text to the End in Python

I am trying to create a GUI form using Python tkinter. For a ttk Entry widget, I want to set a default text. I do that using the insert() as shown below-
from tkinter import *
from tkinter import ttk
root = Tk()
e = ttk.Entry(root, width=20)
e.pack()
e.insert(0, 'text greater than width of the widget')
The widget shows the beginning portion of the inserted text. Is there a way that I can make it scroll to the end of the inserted text by default?
You can call the xview method to scroll a given index into view:
e.xview("end")

Issue with Scale widget using tickinterval

The widget shows tick using tickinterval when following code shown below,
from Tkinter import *
slider_1 = Scale(mGui,orient=HORIZONTAL,length = 100,from_=0,to=9, tickinterval =1).pack()
However it throws error with the following code
from Tkinter import *
from ttk import *
slider_1 = Scale(mGui,orient=HORIZONTAL,length = 100,from_=0,to=9, tickinterval =1).pack()
Error:
_tkinter.TclError: unknown option "-tickinterval"
Why is it so? Is it a bug or problem with the installation. For information i am using Python 2.7.10
This is because the ttk module contains also a Scale widget, and you are actually using the Scale widget from ttk and not from Tkinter. Widgets in the ttk module are customised and styled differently from Tkinter widgets.
Check the following documentation on ttk for more information regarding its widgets:
ttk — Tk themed widgets
To solve your problem, you could remove your second global import and simply do:
import ttk
Then, every time you want to use a widget from ttk, you can simply prefix it with ttk..

Categories

Resources