簡體   English   中英

Python Tkinter更改StringVar值以將其用作UI上的背景指示符

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

我正在構建一個用戶必須選擇一些日期的UI。 我添加了一個名為“ Date Indicator的行,該行顯示了一個帶有顏色的框。 起始顏色(直到用戶選擇兩個日期)為grey 此顏色必須根據用戶選擇的日期進行更改。

  • 如果他選擇兩個日期之間的日期超過兩個星期的日期 ,則該框必須變為綠色
  • 如果他選擇兩個日期之間的時間少於兩周的日期 ,則方框必須變成黃色
    如果他選擇兩個日期之間的日期少於一周的日期 ,則該框必須變為紅色

這是所需解決方案的Photoshoped結果: 在此處輸入圖片說明

該代碼似乎很長,但是您只需要檢查它,直到tkCalendar類即可。 從那里到底部只是您不需要更改的日歷代碼。 (是的,此代碼不需要使用某些imports ,我會維護它們,因為我必須將它們用於其他用途,但是您可以刪除它們)

# -*- 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()

我完全迷路了。 我知道我必須更改self.colorvar但我不知道該怎么做。 例如,我嘗試了self.colorvar.set('red') ,但無法按照上面的說明進行操作。 可以在printdates函數上找到inout日期。 非常感謝您的幫助。

我認為您不能將bg選項鏈接到StringVar。 您只能使用選項textvariable進行操作。 您應該通過Label.config()方法執行此操作。

所以你可以這樣寫:

self.status_color.config(bg='red')

或者,如果您想繼續使用colorvar:

self.colorvar.set('red')
self.status_color.config(bg=self.colorvar.get())

那應該起作用,我想您可以弄清楚2周的事情。

編輯

您也可以將StringVar self.colorvar“鏈接”到一個更改self.status_color的函數(使用trace方法); 這樣,無論何時更改colorvar,都會調用您的函數,並且它將更改狀態顏色。 這是我的建議:

def myFunc(*args):
    self.status_color.config(bg=self.colorvar.get())

self.colorvar.trace('w',self.myFunc)

現在,每次調用self.colorvar.set()時,您還將調用self.myFunc。

編輯:

至於一周的事情,我似乎不容易完全回答。 只需獲取IN和OUT月份和日期的整數,然后執行以下操作:

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

然后您的if / else具有換色功能。 也要注意一月,如果再加上一個就多。 而且我想您可以解析IN和OUT字符串來自己獲取月份和日期。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM