Insert while loop values to tkinter magic window - python

I have a code to create a "magic window" in python.
It should shows title, time and news.
I took news with function newz to loop (it should show the news on-by-on in Tkinter window)
I tried to insert it into tkinter label but it doesn't work(it just doesn't appear, but when I insert plain text to label it works), how could I do it? Here is the whole code with time functions and news function + tkinter
import tkinter as tk
from tkinter import *
import feedparser
import json
from time import sleep
import time
import os
startupscreen = tk.Tk()
startupscreen.title('Magic Mirror: Python Mod')
welcometext = tk.Label(startupscreen, font = ('caviar dreams', 40), bg='black', fg='white')
startupscreen.configure(background='black')
startupscreen.overrideredirect(True)
welcometext.config(text='日本')
welcometext.pack(side=LEFT, padx= 120, pady=80)
# Gets the requested values of the height and widht.
windowWidth = startupscreen.winfo_reqwidth()
windowHeight = startupscreen.winfo_reqheight()
# Gets both half the screen width/height and window width/height
positionRight = int(startupscreen.winfo_screenwidth()/3 - windowWidth/2)
positionDown = int(startupscreen.winfo_screenheight()/2 - windowHeight/2)
# Positions the window in the center of the page.
startupscreen.geometry("+{}+{}".format(positionRight, positionDown))
startupscreen.update()
decrypt = list()
global iteration
global timecount
global repull
global sleep
iteration = 0
timecount = 0
repull = 0
sleep = 0
# main window
while True:
def tick(time1=''):
time2 = time.strftime("%H")
if time2 != time1:
time1 = time2
clock_frame.config(text=time2)
clock_frame.after(200, tick)
def tickk(time3=''):
time4 = time.strftime(":%M:%S")
if time4 != time3:
time3 = time4
clock_frame2.config(text=time4)
clock_frame2.after(200, tickk)
def newz():
url = 'https://news.google.com/rss?hl=ja&gl=JP&ceid=JP:ja'
d = feedparser.parse(url)
news = list()
for i, entry in enumerate(d.entries, 1):
p = entry.published_parsed
sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)
tmp = {
"title": entry.title,
#"link": entry.link,
"sortkey": sortkey
}
news.append(tmp)
news = sorted(news, key=lambda x: x['sortkey'])
myDict = {}
for d in news:
c = d['title']
myDict[c] = myDict.get(c,0)+1
frequency = myDict.keys()
frequency = list(frequency)
for x in range(len(frequency)):
print (frequency[x])
x += 1
root = tk.Tk()
root.title('Mirror')
lab = Label(root, text=" 日本", font = ('', 40), bg='black', fg='white')
lab.pack(anchor=SW, fill=X, padx=45)
masterclock = tk.Label(root)
masterclock.pack(anchor=NW, fill=X, padx=45)
masterclock.configure(background='black')
clock_frame = tk.Label(root, font = ('caviar dreams', 130), bg='black', fg='white')
clock_frame.pack(in_=masterclock, side=LEFT)
clock_frame2 = tk.Label(root, font = ('caviar dreams', 70), bg='black', fg='white')
clock_frame2.pack(in_=masterclock, side=LEFT, anchor = N, ipady=15)
newstitle = tk.Label(root, font = ('caviar dreams', 30), bg='black', fg='white')
newstitle.pack(side=BOTTOM, anchor=W, fill=X)
source = tk.Label(root, font = ('caviar dreams', 20), bg='black', fg='white')
source.pack(side=BOTTOM, anchor=W, fill=X)
tick()
tickk()
newz() #here it doesnt work
root.attributes("-fullscreen", True)
root.configure(background='black')
startupscreen.destroy()
root.mainloop()

I don't know what you want to display but you have to use
source.config(text="some text")
root.after(1000, newz)
inside function newz
Something like this
#--- newz - start ---
def newz():
url = 'https://news.google.com/rss?hl=ja&gl=JP&ceid=JP:ja'
d = feedparser.parse(url)
news = list()
for i, entry in enumerate(d.entries, 1):
p = entry.published_parsed
sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)
tmp = {
"title": entry.title,
#"link": entry.link,
"sortkey": sortkey
}
news.append(tmp)
news = sorted(news, key=lambda x: x['sortkey'])
myDict = {}
for d in news:
c = d['title']
myDict[c] = myDict.get(c,0)+1
frequency = myDict.keys()
frequency = list(frequency)
for x in range(len(frequency)):
print(frequency[x])
source.config(text=str(frequency[x]))
x += 1
#source.config(text="some text")
root.after(1000, newz) # 1000ms = 1s
#--- newz - end ---

Related

How do I get a output into a tkinter Entry field

Im making my own cypher encryption and I want to put the result into the entry field called output. Now im just using print() so I could test if I got a result. But that was only for testing. This is one of the first times I used Python so if there are some other things I could have done better please let me know :)
this is what I have so far.
from tkinter import *
#Make frame
root = Tk()
root.geometry("500x300")
root.title("Encryption Tool")
top_frame = Frame(root)
bottom_frame = Frame(root)
top_frame.pack()
bottom_frame.pack()
#Text
headline = Label(top_frame, text="Encryption Tool", fg='black')
headline.config(font=('Courier', 27))
headline.grid(padx=10, pady=10)
Key = Label(bottom_frame, text="Key:", fg='black')
Key.config(font=('Courier', 20))
Key.grid(row=1)
Text_entry = Label(bottom_frame, text="Text:", fg='black')
Text_entry.config(font=('Courier', 20))
Text_entry.grid(row=2)
Output_text = Label(bottom_frame, text="Output:", fg='black')
Output_text.config(font=('Courier', 20))
Output_text.grid(row=3)
Key_entry = Entry(bottom_frame)
Key_entry.grid(row=1, column=1)
Text_entry = Entry(bottom_frame)
Text_entry.grid(row=2, column=1)
Output_text = Entry(bottom_frame)
Output_text.grid(row=3, column=1)
#Encryption_button
def encrypt():
result = ''
text = ''
key = Key_entry.get()
text = Text_entry.get()
formule = int(key)
for i in range(0, len(text)):
result = result + chr(ord(text[i]) + formule + i * i)
result = ''
Encryption_button = Button(bottom_frame, text="Encrypt", fg='black')
Encryption_button.config(height = 2, width = 15)
Encryption_button.grid(row = 4, column = 0, sticky = S)
Encryption_button['command'] = encrypt
#Decryption_button
def decrypt():
result = ''
text = ''
key = Key_entry.get()
text = Text_entry.get()
formule = int(key)
for i in range(0, len(text)):
result = result + chr(ord(text[i]) - formule - i * i)
print(result)
result = ''
Decryption_button = Button(bottom_frame, text="Decrypt", fg="black")
Decryption_button.config(height = 2, width = 15)
Decryption_button.grid(row = 5, column = 0, sticky = S)
Decryption_button['command'] = decrypt
#Quit_button
def end():
exit()
Quit_button = Button(bottom_frame, text="Quit", fg='black')
Quit_button.config(height = 2, width = 15)
Quit_button.grid(row = 6, column = 0, sticky = S)
Quit_button['command'] = end
root.mainloop()
The most common way to do this with tkinter would be with a StringVar() object you can connect to the Entry object (Some documentation here).
output_entry_value = StringVar()
Output_text = Entry(bottom_frame, textvariable=output_entry_value)
Output_text.grid(row=3, column=1)
then you can .set() the result in the stringvar, and it will update in the entries you connected it to:
output_entry_value.set(result)

Creating Tkinter Text boxes and inserting into a dictionary

I have a long chunk of code. I do not want to paste it all here, so let me explain what I am trying to accomplish here. Based on a number provided by the user I want to create that many text boxes and then get what is entered into that text box and insert that into the dictionary. I have tried this a few ways and just cannot get it to work correctly. The list is either empty or it only contains the last text box as the value for each key.
def multiple_choice():
def add():
top.destroy()
top = Tk()
top.title("Add Question")
w = 800
h = 800
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
top.geometry('%dx%d+%d+%d' % (w, h, x, y))
question = Label(top, text="Question to be asked?", font = "Times 14 bold", fg = "blue")
question.grid(row = 2, column = 4)
questionText = Text(top, borderwidth = 5, width=50,height=5, wrap=WORD, background = 'grey')
questionText.grid(row = 3, column = 4)
numQuestions = Label(top, text = "Number of answer choices?", font = "Times 14 bold", fg = "blue")
numQuestions.grid(row = 4, column=4)
num = Entry(top, bd = 5)
num.grid(row=5, column = 4)
answerList = {}
def multiple():
def preview():
preview = Tk()
top.title("Question Preview")
w = 500
h = 500
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
top.geometry('%dx%d+%d+%d' % (w, h, x, y))
title = Label(preview, text = "Short Answer Question Preview", font = "Times 18 bold", fg = "blue" )
title.grid(row = 0, column = 2)
qtext = "Question text will read: "
ques = Label(preview, text = qtext)
ques.grid(row=1, column = 2)
ques2 = Label( preview, text = questionText.get("1.0",END))
let = 'A'
i = 1
for word in answerList:
prev = let + ": " + word
ans = Label(preview, text = prev)
ans.grid(row=1+i, column = 2)
let = chr(ord(let) + 1)
answerCor = "The correct answer(s): "
a = Label(preview, text = answerCor)
a.grid(row=4, column = 2)
b = Label(preview, text = cor.get)
b.grid(row=5, column = 2)
if num.get().isdigit():
number = int(num.get())
AnswerChoices = Label(top, text = "Answer Choices?", font = "Times 14 bold", fg = "blue")
AnswerChoices.grid(row = 6, column=4)
i = 0
let = 'A'
while i < number:
letter = Label(top, text = let)
letter.grid(row = 8+(i*4), column = 3)
answer = Text(top, borderwidth = 5, width=50, height=3, wrap=WORD, background = 'grey')
answer.grid(row = 8+(i*4), column = 4)
answerList[let] = answer.get("1.0",END)
i = i+1
let = chr(ord(let) + 1)
print answerList
correct = Label(top, text = "Correct Answer(s) (seperated by commas)",
font = "Times 14 bold", fg = "blue")
correct.grid(row =99 , column=4)
cor = Text(top, borderwidth = 5, width=50, height=3, wrap=WORD, background = 'grey')
cor.grid(row=100, column = 4)
else:
error = Tk()
w = 500
h = 100
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
error.geometry('%dx%d+%d+%d' % (w, h, x, y))
text = "ERROR: You must enter an integer number"
Label(error,text = text, fg = "red", font = "Times 16 bold").pack()
MyButton5 = Button(top, text="Preview Question", width=20, command = preview, anchor=S)
MyButton5.grid(row=102, column=5)
MyButton4 = Button(top, text="Finish and Add Question", width=20, command = add, anchor=S)
MyButton4.grid(row=102, column=2)
but = Button(top, text="Submit", width=10, command = multiple)
but.grid(row=6, column = 4)
top.mainloop()
def button():
MyButton21 = Button(quiz, text="Short Answer Question", width=20, command = short_answer)
MyButton21.grid(row=8, column=2)
MyButton22 = Button(quiz, text="True/False Question", width=20, command = true_false)
MyButton22.grid(row=8, column=4)
MyButton23 = Button(quiz, text="Multiple Choice Question", width=20, command = multiple_choice)
MyButton23.grid(row=9, column=2)
#MyButton24 = Button(quiz, text="Matching Question", width=20, command = matching)
#MyButton24.grid(row=9, column=4)
MyButton25 = Button(quiz, text="Ordering Question", width=20, command =order)
MyButton25.grid(row=10, column=2)
MyButton26 = Button(quiz, text="Fill in the Blank Question", width=20, command = fill_blank)
MyButton26.grid(row=10, column=4)
MyButton3 = Button(quiz, text="Finsh Quiz", width=10, command = quiz)
MyButton3.grid(row=12, column=3)
quiz = Tk()
w = 700
h = 300
ws = quiz.winfo_screenwidth()
hs = quiz.winfo_screenheight()
x = 0
y = 0
quiz.geometry('%dx%d+%d+%d' % (w, h, x, y))
quiz.title("eCampus Quiz Developer")
L1 = Label(quiz, text="Quiz Title?")
L1.grid(row=0, column=0)
E1 = Entry(quiz, bd = 5)
E1.grid(row=0, column=3)
name_file = E1.get()
name_file = name_file.replace(" ", "")
name_file = name_file + ".txt"
with open(name_file,"w") as data:
MyButton1 = Button(quiz, text="Submit", width=10, command = button)
MyButton1.grid(row=1, column=3)
quiz.mainloop()
I am trying to create the dictionary using this chunk of code:
i = 0
let = 'A'
while i < number:
letter = Label(top, text = let)
letter.grid(row = 8+(i*4), column = 3)
answer = Text(top, borderwidth = 5, width=50, height=3, wrap=WORD, background = 'grey')
answer.grid(row = 8+(i*4), column = 4)
answerList[let] = answer.get("1.0",END)
i = i+1
let = chr(ord(let) + 1)
I have even tried putting a loop in the preview function but that is when the last box was the only value contained in the dictionary. Any ideas would be appreciated
Please see my commeneted snippet below which demonstrates this:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.entry = Entry(self.root) #entry to input number of entries later
self.button = Button(self.root, text="ok", command=self.command) #calls command to draw the entry boxes
self.frame = Frame(self.root)
self.entry.pack()
self.button.pack()
self.frame.pack()
def command(self):
self.frame.destroy() #destroys frame and contents
self.frame = Frame(self.root) #recreates frame
self.text = [] #empty array to store entry boxes
for i in range(int(self.entry.get())):
self.text.append(Entry(self.frame, text="Question "+str(i))) #creates entry boxes
self.text[i].pack()
self.done = Button(self.frame, text="Done", command=self.dict) #button to call dictionary entry and print
self.done.pack()
self.frame.pack()
def dict(self):
self.dict = {}
for i in range(len(self.text)):
self.dict.update({self.text[i].cget("text"): self.text[i].get()})
#the above line adds a new dict entry with the text value of the respective entry as the key and the value of the entry as the value
print(self.dict) #prints the dict
root = Tk()
App(root)
root.mainloop()
The above asks the user how many entry widgets they want to create, fills a frame with those entry widgets and then iterates through the list which contains them on the press of a button, adding a new dictionary entry for each entry widget, where the key of the dict is the attribute text for each entry and the value of the dict is the value of each entry.

Python Tkinter Variable label not updating

I am trying to make my variable on my label update, however have encountered a problem where the function of the buttons works by changing the temperature set up and down by 0.5 deg C however the labels on the temp and desired temp will not change with it.
I am working in python3.6
Here is my code, I was wondering if anyone may be able to help me please?
import os
import glob
import time
import RPi.GPIO as GPIO
from datetime import datetime
#Set gpio's
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17,GPIO.OUT)#RED
GPIO.setup(22,GPIO.OUT)#GREEN
GPIO.setup(27,GPIO.OUT)#BLUE
#grab temp probe information
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
# Read temperature from device
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines=read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.1)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000
#temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c#, temp_f
temp = read_temp()
desiredtemp = 17
deg = u'\xb0'#utf code for degree
def increase():
global desiredtemp
desiredtemp = desiredtemp + 0.5
print(desiredtemp)
def decrease():
global desiredtemp
desiredtemp = desiredtemp - 0.5
print(desiredtemp)
#Tkinter start
from tkinter import *
root = Tk()
#code to add widgets will go here....
topFrame = Frame(root)
topFrame.pack(side=TOP)
middleFrame = Frame(root)
middleFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
#Set buttons
button1 = Button(bottomFrame, text="Increase (0.5"+ deg +"C)", fg="black", command=increase)
button2 = Button(bottomFrame, text="Decrease (0.5"+ deg +"C)", fg="black", command=decrease)
#use to put buttons on screen
button1.pack(side=LEFT)
button2.pack(side=LEFT)
#Set labels
label1 = Label(topFrame, text="Desired Temp = ", fg="black")
label2 = Label(middleFrame, text="Actual Temp = ", fg="black")
label3 = Label(topFrame, text=desiredtemp, fg="black")
label4 = Label(middleFrame, text=temp, fg="black")
#use to put labels on screen
label1.pack(side=LEFT)
label2.pack(side=LEFT)
label3.pack(side=LEFT)
label4.pack(side=LEFT)
root.mainloop()
#Tkinter End
# Open file to be logged
file = open("/home/pi/Desktop/Templog.csv", "a")
if os.stat("/home/pi/Desktop/Templog.csv").st_size == 0:
file.write("Date, Time, TemperatureSensor1\n")
# Continuous print loop
while True:
print(read_temp())
if(read_temp()<desiredtemp):
GPIO.output(17,GPIO.LOW)
GPIO.output(22,GPIO.HIGH)
else:
GPIO.output(17,GPIO.HIGH)
GPIO.output(22,GPIO.LOW)
now = datetime.now()
file.write(str(now.day)+"-"+str(now.month)+"-"+str(now.year)+","+str(now.hour)+":"+str(now.minute)+":"+str(now.second)+","+str(read_temp())+"\n")
file.flush()
time.sleep(1)
You can use StringVar to associate a string variable with a Label widget. You pass the StringVar to the Label as the textvariable keyword argument and in each button callback simply update the value of the temperature and the StringVar using its set method.
Example extending your own code:
import os
import glob
import time
from datetime import datetime
from tkinter import *
temp = 18
desiredtemp = 17
deg = u'\xb0' # utf code for degree
def increase():
global desiredtemp
desiredtemp += 0.5
tmpstr.set("%s" % desiredtemp)
def decrease():
global desiredtemp
desiredtemp -= 0.5
tmpstr.set("%s" % desiredtemp)
root = Tk()
topFrame = Frame(root)
topFrame.pack(side=TOP)
middleFrame = Frame(root)
middleFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
button1 = Button(bottomFrame, text="Increase (0.5"+ deg +"C)", fg="black", command=increase)
button2 = Button(bottomFrame, text="Decrease (0.5"+ deg +"C)", fg="black", command=decrease)
button1.pack(side=LEFT)
button2.pack(side=LEFT)
tmpstr = StringVar(value="%s" % desiredtemp)
label1 = Label(topFrame, text="Desired Temp = ", fg="black")
label2 = Label(middleFrame, text="Actual Temp = ", fg="black")
label3 = Label(topFrame, textvariable=tmpstr, fg="black")
label4 = Label(middleFrame, text=temp, fg="black")
label1.pack(side=LEFT)
label2.pack(side=LEFT)
label3.pack(side=LEFT)
label4.pack(side=LEFT)
root.mainloop()
Note that use of the global keyword is generally considered a code smell, which should make you consider placing all those elements into a class.

Discussion with tkinter

from tkinter import *
window = Tk()
ia_answers= "trolol"
input_frame = LabelFrame(window, text="User :", borderwidth=4)
input_frame.pack(fill=BOTH, side=BOTTOM)
input_user = StringVar()
input_field = Entry(input_frame, text=input_user)
input_field.pack(fill=BOTH, side=BOTTOM)
ia_frame = LabelFrame(window, text="Discussion",borderwidth = 15, height = 100, width = 100)
ia_frame.pack(fill=BOTH, side=TOP)
user_says = StringVar()
user_text = Label(ia_frame, textvariable=user_says, anchor = NE, justify = RIGHT, bg="white")
user_text.pack(fill=BOTH, side=TOP)
ia_says = StringVar()
ia_text = Label(ia_frame, textvariable=ia_says, anchor = W, justify = LEFT, bg="white")
ia_text.pack(fill=BOTH, side=BOTTOM)
def Enter_pressed(event):
"""Took the current string in the Entry field."""
input_get = input_field.get()
input_user.set("")
user_says.set(input_get + "\n\n")
ia_says.set(ia_answers)
input_field.bind("<Return>", Enter_pressed)
window.mainloop()
Hi, i am trying to build a discussion Bot.
When I execute the code, the question in the input field and the answer get displayed correctly.
The problem is after entering the next sentence, the previous question/answer gets removed. Here is an example:
Hello Bot
Hello User
(then the text disappears)
How are you
Fine thank you
What i want :
Hello Bot
Hello User
(then the text stays in the frame)
How are you
Fine thank you
The issue occurs in line -
user_says.set(input_get + "\n\n")
ia_says.set(ia_answers)
You are replace users_says.set() and ia_says.set() resets the complete Labels , with the new value. Instead you should get the old value and append the new value to it and set it back, Example -
user_says.set(user_says.get() + input_get + "\n")
ia_says.set(ia_says.get() + ia_answers + "\n")
Or you can also create a new label for each new event and add it to the LabelFrame . Example -
from tkinter import *
window = Tk()
ia_answers= "trolol\n"
input_frame = LabelFrame(window, text="User :", borderwidth=4)
input_frame.pack(fill=BOTH, side=BOTTOM)
input_user = StringVar()
input_field = Entry(input_frame, text=input_user)
input_field.pack(fill=BOTH, side=BOTTOM)
ia_frame = LabelFrame(window, text="Discussion",borderwidth = 15, height = 100, width = 100)
ia_frame.pack(fill=BOTH, side=TOP)
user_says = StringVar()
user_text = Label(ia_frame, textvariable=user_says, anchor = NE, justify = RIGHT,
bg="white")
user_text.pack(fill=X)
ia_says = StringVar()
ia_text = Label(ia_frame, textvariable=ia_says, anchor = NW, justify = LEFT, bg="white")
ia_text.pack(fill=X)
user_texts = []
ia_texts = []
user_says_list = []
ia_says_list = []
def Enter_pressed(event):
"""Took the current string in the Entry field."""
input_get = input_field.get()
input_user.set("")
user_says1 = StringVar()
user_says1.set(input_get + "\n")
user_text1 = Label(ia_frame, textvariable=user_says1, anchor = NE, justify = RIGHT,
bg="white")
user_text1.pack(fill=X)
user_texts.append(user_text1)
user_says_list.append(user_says1)
ia_says1 = StringVar()
ia_says1.set(ia_answers)
ia_text1 = Label(ia_frame, textvariable=ia_says1, anchor = NW, justify = LEFT,
bg="white")
ia_text1.pack(fill=X)
ia_texts.append(ia_text1)
ia_says_list.append(ia_says1)
input_field.bind("<Return>", Enter_pressed)
window.mainloop()

Python Tkinter changing StringVar value to use it as a background indicator on a UI

I'm building a UI where the users have to select some dates. I've added a row called Date Indicator which shows a box with a color. The starting color (until the user selects both dates) is grey. This color has to change depending on the dates that the user selects.
If he selects two dates where the days between them are more than two weeks, the box has to became green.
If he selects two dates where the days between them are less than two weeks, the box has to became yellow.
If he selects two dates where the days between them are less than one week, the box has to became red.
This is a Photoshoped result for the desired solution:
The code seems to be long, but you only have to check it until the tkCalendar class. From there to the bottom is just the calendar code you dont need to change. (And yes, there are some imports you dont need to use for this code, I maintain them because I've to use them for other stuff, but you can remove them)
# -*- coding: utf-8 -*-
import os
from Tkinter import *
import Image
import ImageTk
import tkFileDialog
import xlrd
import csv
from tkMessageBox import *
from win32com.client import Dispatch
import datetime
import time
import calendar
year = time.localtime()[0]
month = time.localtime()[1]
day =time.localtime()[2]
strdate = (str(year) + "/" + str(month) + "/" + str(day))
fnta = ("Helvetica", 10)
fnt = ("Helvetica", 10)
fntc = ("Helvetica", 10, 'bold')
strtitle = "Calendario"
strdays= "Do Lu Ma Mi Ju Vi Sa"
dictmonths = {'1':'Ene','2':'Feb','3':'Mar','4':'Abr','5':'May',
'6':'Jun','7':'Jul','8':'Ago','9':'Sep','10':'Oct','11':'Nov',
'12':'Dic'}
class Planificador(Frame):
def __init__(self,master):
Frame.__init__(self, master)
self.master = master
self.initUI()
def initUI(self):
self.master.title("Planner")
self.frameOne = Frame(self.master)
self.frameOne.grid(row=0,column=0)
self.frameTwo = Frame(self.master)
self.frameTwo.grid(row=0, column=1)
self.frameThree = Frame(self.master)
self.frameThree.grid(row=0, column=2)
self.frameFour = Frame(self.master)
self.frameFour.grid(row=1,column=0, sticky=N)
self.frameFive = Frame(self.master)
self.frameFive.grid(row=1, column=1)
self.frameSix = Frame(self.master)
self.frameSix.grid(row=1, column=2, sticky=N)
self.frameSeven = Frame(self.master)
self.frameSeven.grid(row=2,column=0)
self.frameEight = Frame(self.master)
self.frameEight.grid(row=2, column=1, sticky=S)
self.frameNine = Frame(self.master)
self.frameNine.grid(row=2, column=2)
self.start_date_menu()
def start_date_menu(self):
self.initial_num_elements = 4
self.TEXT_MENU_ROW = 0 # initial date menu grid row
self.COL_WIDTH = 10 # width of each subcolumn of dates
for frame in (self.frameFour, self.frameSix):
self.dayintext = Label(frame, text="Day in",
width=self.COL_WIDTH, justify="center")
self.dayintext.grid(row=self.TEXT_MENU_ROW, column=0)
self.dayouttext = Label(frame, text="Day out", width=self.COL_WIDTH,
justify="center")
self.dayouttext.grid(row=self.TEXT_MENU_ROW, column=1)
self.status = Label(frame, text="Date indicator", width=self.COL_WIDTH,
justify="center")
self.status.grid(row=self.TEXT_MENU_ROW, column=2)
self.dates = [self.create_all_entrys(aux_index)
for aux_index in xrange(self.initial_num_elements)]
self.anadirpiezas = Button(self.frameEight, text="add more",
command=self.addone, width=self.COL_WIDTH)
self.anadirpiezas.grid(row=0, column=3)
def addone(self):
self.dates.append(self.create_all_entrys(len(self.dates)))
self.printdates()
def printdates(self):
print "IN:"
for i in xrange(self.initial_num_elements):
print self.dates[i][0].get() # col 0
print "OUT:"
for i in xrange(self.initial_num_elements):
print self.dates[i][2].get() # col 2
def create_all_entrys(self, aux_index):
menu_col = aux_index % 2 # left/right column of the date frame
menu_row = self.TEXT_MENU_ROW + aux_index/2 + 1
frame = self.frameSix if aux_index % 2 else self.frameFour
in_var = StringVar(value="--------")
in_btn = Button(frame, textvariable=in_var, width=self.COL_WIDTH,
command=lambda v=in_var: self.fnCalendar(v))
in_btn.grid(row=menu_row, column=0)
out_var = StringVar(value="--------")
out_btn = Button(frame, textvariable=out_var, width=self.COL_WIDTH,
command=lambda v=out_var: self.fnCalendar(v))
out_btn.grid(row=menu_row, column=1)
self.colorvar = StringVar()
self.colorvar.set('grey')
self.status_color = Label(frame, width=2, bg=self.colorvar.get())
self.status_color.grid(row=menu_row,column=2)
return in_var, in_btn, out_var, out_btn
def fnCalendar(self, datebar):
tkCalendar(self.master, year, month, day, datebar)
class tkCalendar :
def __init__ (self, master, arg_year, arg_month, arg_day,
arg_parent_updatable_var):
print arg_parent_updatable_var.get()
self.update_var = arg_parent_updatable_var
top = self.top = Toplevel(master)
top.title("Choose a date")
try : self.intmonth = int(arg_month)
except: self.intmonth = int(1)
self.canvas =Canvas (top, width =200, height =220,
relief =RIDGE, background ="#ece9d8", borderwidth =0)
self.canvas.create_rectangle(0,0,303,30, fill="#ece9d8",width=0 )
self.canvas.create_text(100,17, text="Choose!", font=fntc, fill="#BA1111")
stryear = str(arg_year)
self.year_var=StringVar()
self.year_var.set(stryear)
self.lblYear = Label(top, textvariable = self.year_var,
font = fnta, background="#ece9d8")
self.lblYear.place(x=85, y = 30)
self.month_var=StringVar()
strnummonth = str(self.intmonth)
strmonth = dictmonths[strnummonth]
self.month_var.set(strmonth)
self.lblYear = Label(top, textvariable = self.month_var,
font = fnta, background="#ece9d8")
self.lblYear.place(x=85, y = 50)
#Variable muy usada
tagBaseButton = "Arrow"
self.tagBaseNumber = "DayButton"
#draw year arrows
x,y = 40, 43
tagThisButton = "leftyear"
tagFinalThisButton = tuple((tagBaseButton,tagThisButton))
self.fnCreateLeftArrow(self.canvas, x,y, tagFinalThisButton)
x,y = 150, 43
tagThisButton = "rightyear"
tagFinalThisButton = tuple((tagBaseButton,tagThisButton))
self.fnCreateRightArrow(self.canvas, x,y, tagFinalThisButton)
#draw month arrows
x,y = 40, 63
tagThisButton = "leftmonth"
tagFinalThisButton = tuple((tagBaseButton,tagThisButton))
self.fnCreateLeftArrow(self.canvas, x,y, tagFinalThisButton)
x,y = 150, 63
tagThisButton = "rightmonth"
tagFinalThisButton = tuple((tagBaseButton,tagThisButton))
self.fnCreateRightArrow(self.canvas, x,y, tagFinalThisButton)
#Print days
self.canvas.create_text(100,90, text=strdays, font=fnta)
self.canvas.pack (expand =1, fill =BOTH)
self.canvas.tag_bind ("Arrow", "<ButtonRelease-1>", self.fnClick)
self.canvas.tag_bind ("Arrow", "<Enter>", self.fnOnMouseOver)
self.canvas.tag_bind ("Arrow", "<Leave>", self.fnOnMouseOut)
self.fnFillCalendar()
def fnCreateRightArrow(self, canv, x, y, strtagname):
canv.create_polygon(x,y, [[x+0,y-5], [x+10, y-5] , [x+10,y-10] ,
[x+20,y+0], [x+10,y+10] , [x+10,y+5] , [x+0,y+5]],
tags = strtagname , fill="black", width=0)
def fnCreateLeftArrow(self, canv, x, y, strtagname):
canv.create_polygon(x,y, [[x+10,y-10], [x+10, y-5] , [x+20,y-5] ,
[x+20,y+5], [x+10,y+5] , [x+10,y+10] ],
tags = strtagname , fill="black", width=0)
def fnClick(self,event):
owntags =self.canvas.gettags(CURRENT)
if "rightyear" in owntags:
intyear = int(self.year_var.get())
intyear +=1
stryear = str(intyear)
self.year_var.set(stryear)
if "leftyear" in owntags:
intyear = int(self.year_var.get())
intyear -=1
stryear = str(intyear)
self.year_var.set(stryear)
if "rightmonth" in owntags:
if self.intmonth < 12 :
self.intmonth += 1
strnummonth = str(self.intmonth)
strmonth = dictmonths[strnummonth]
self.month_var.set(strmonth)
else :
self.intmonth = 1
strnummonth = str(self.intmonth)
strmonth = dictmonths[strnummonth]
self.month_var.set(strmonth)
intyear = int(self.year_var.get())
intyear +=1
stryear = str(intyear)
self.year_var.set(stryear)
if "leftmonth" in owntags:
if self.intmonth > 1 :
self.intmonth -= 1
strnummonth = str(self.intmonth)
strmonth = dictmonths[strnummonth]
self.month_var.set(strmonth)
else :
self.intmonth = 12
strnummonth = str(self.intmonth)
strmonth = dictmonths[strnummonth]
self.month_var.set(strmonth)
intyear = int(self.year_var.get())
intyear -=1
stryear = str(intyear)
self.year_var.set(stryear)
self.fnFillCalendar()
def fnFillCalendar(self):
init_x_pos = 20
arr_y_pos = [110,130,150,170,190,210]
intposarr = 0
self.canvas.delete("DayButton")
self.canvas.update()
intyear = int(self.year_var.get())
monthcal = calendar.monthcalendar(intyear, self.intmonth)
for row in monthcal:
xpos = init_x_pos
ypos = arr_y_pos[intposarr]
for item in row:
stritem = str(item)
if stritem == "0":
xpos += 27
else :
tagNumber = tuple((self.tagBaseNumber,stritem))
self.canvas.create_text(xpos, ypos , text=stritem,
font=fnta,tags=tagNumber)
xpos += 27
intposarr += 1
self.canvas.tag_bind ("DayButton", "<ButtonRelease-1>", self.fnClickNumber)
self.canvas.tag_bind ("DayButton", "<Enter>", self.fnOnMouseOver)
self.canvas.tag_bind ("DayButton", "<Leave>", self.fnOnMouseOut)
def fnClickNumber(self,event):
owntags =self.canvas.gettags(CURRENT)
for x in owntags:
if (x == "current") or (x == "DayButton"): pass
else :
strdate = (str(self.year_var.get()) + "/" +
str(self.intmonth) + "/" +
str(x))
self.update_var.set(strdate)
self.top.withdraw()
def fnOnMouseOver(self,event):
self.canvas.move(CURRENT, 1, 1)
self.canvas.update()
def fnOnMouseOut(self,event):
self.canvas.move(CURRENT, -1, -1)
self.canvas.update()
if __name__ == "__main__":
root = Tk()
aplicacion = Planificador(root)
root.mainloop()
I'm totally lost trying to do this. I know I've to change self.colorvar but I dont know how to do it. I tryed to self.colorvar.set('red') for example but I cant make it work the way I explaned above. The in and out dates can be found on the printdates function. You help is much appreciated.
I don't think you can link the bg option to a StringVar. You can only do it with the option textvariable. The way you should do it is via the Label.config() method.
So you could write:
self.status_color.config(bg='red')
or, if you want to keep using the colorvar:
self.colorvar.set('red')
self.status_color.config(bg=self.colorvar.get())
That should work, and I guess that you can figure out the 2 week thing.
EDIT:
You can also 'link' the StringVar self.colorvar to a function that changes self.status_color (with the trace method); so that whenever colorvar is changed, your function will be called and it will change the status color.
This is my suggestion:
def myFunc(*args):
self.status_color.config(bg=self.colorvar.get())
self.colorvar.trace('w',self.myFunc)
Now every time you call self.colorvar.set(), you will be also calling self.myFunc.
EDIT:
As for the week thing, I'm not going to answer completely as it seems easy. Just get an integer for month and day of IN and OUT and do something like this:
monthdiff = monthout-monthin
if monthdiff!=0:
dayout += monthdiff*30 #or 31, depending on the month. Just add an if/else
weeks = ((dayout-dayin)//7)+1 #For python2.7 use only one slash
And then your if/else with the colour changing function. Be careful with January too, just add one if more. And I guess you can parse the IN and OUT strings to get the month and day yourself.

Categories