質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

PyCharm

エディター・開発ツール

Q&A

解決済

3回答

2056閲覧

Python tkinter Date型のEntryにあるNoneが今日の日付に変換される

yoshiyoshi

総合スコア5

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

PyCharm

エディター・開発ツール

0グッド

0クリップ

投稿2022/08/16 00:57

前提

PythonでDBにある納期設定日を変更するプログラムを作成しています
日付が入力されていないデータ(None)が一部にあり、DBに上書きする際に
Entryからデータを取得しようとするとなぜか今日の日付が勝手に入力されます
どのようにすればNoneのまま取得できるのかご教示いただけないでしょうか

実現したいこと

日付がNoneの時はNoneのまま処理を行いたい

発生している問題・エラーメッセージ

Entryの値がNoneとなっていても
dl1 = entry31.get_date()
(もしくは dl1 = entry31.get() としても)
とすると dl1に今日の日付が入ってしまいます

if で Noneの時だけ何か処理を変えればよいのかと思い
if entry31 is None:
entry31.delete()
else:
dl1 = entry31.get_date()
としても Noneと判定されずに elseに流れ今日の日付が入力されます

該当のソースコード

Python 入りきらなかったので一部略

1 2def open_tree(): 3 global tree 4 global Name 5 global dst 6 global ded 7 global open_form_window 8 9 sql = f"SELECT [Id],[Co_Name],FORMAT([希望納期],'yyyy/MM/dd'),FORMAT([目標納期],'yyyy/MM/dd'),FORMAT([回答納期],'yyyy/MM/dd'),FORMAT([出荷予定日],'yyyy/MM/dd') FROM [Test].[dbo].[Tr_Slip_table]; " 10 11 print(sql) 12 13 open_form_window = tk.Toplevel() 14 open_form_window.title('納期一覧') 15 open_form_window.configure(bg='khaki') 16 open_form_window.overrideredirect(True) 17 root_x, root_y = root.winfo_x(), root.winfo_y() 18 open_form_window.geometry(f'450x240+{root_x - 0}+{root_y - 240}') 19 print(root.__dict__) 20 form = ttk.Frame(open_form_window) 21 22 new_frame1 = tk.Frame(open_form_window, bg='khaki', pady=2) 23 new_frame1.pack(fill='both', expand=True) 24 25 form.pack() 26 open_form_window.attributes("-topmost", True) 27 tree = ttk.Treeview(open_form_window) 28 29 tree["columns"] = (1, 2, 3, 4, 5, 6) 30 31 tree["show"] = "headings" 32 tree["displaycolumns"] = [1, 2, 3, 4, 5, 6] 33 34 tree.column(1, width=40, anchor=tk.CENTER) 35 tree.column(2, width=50, anchor=tk.E) 36 tree.column(3, width=50, anchor=tk.E) 37 tree.column(4, width=50, anchor=tk.CENTER) 38 tree.column(5, width=50, anchor=tk.E) 39 tree.column(6, width=50, anchor=tk.E) 40 41 tree.heading(1, text="製番") 42 tree.heading(2, text="得意先名") 43 tree.heading(3, text="希望納期") 44 tree.heading(4, text="目標納期") 45 tree.heading(5, text="回答納期") 46 tree.heading(6, text="出荷予定") 47 48 tree.pack(padx=(5,5), pady=(5,5), fill='both', expand=True) 49 50 for item in tree.get_children(): 51 tree.delete(item) 52 53 for row in cursor.execute(sql): 54 row = list(row) 55 tree.insert("", "end", values=row) 56 tree.bind('<Double-1>', getVule) 57 58def getVule(event): 59 selected_items = tree.selection() 60 if not selected_items: 61 return 62 values = tree.item(selected_items[0], 'values') 63 with open('log.txt', 'a') as f: 64 print(values, file=f) 65 66 global open_form_window2 67 global nouki1 68 global nouki2 69 global nouki3 70 global nouki4 71 global label12 72 global entry31 73 global entry32 74 global entry33 75 global entry34 76 77 if open_form_window2: open_form_window2.destroy() 78 79 open_form_window2 = tk.Toplevel() 80 open_form_window2.title('納期変更') 81 open_form_window2.configure(bg='khaki') 82 open_form_window2.overrideredirect(True) 83 root_x, root_y = root.winfo_x(), root.winfo_y() 84 open_form_window2.geometry(f'450x80+{root_x - 0}+{root_y - 325}') 85 print(root.__dict__) 86 form = ttk.Frame(open_form_window2) 87 88 new_frame2 = tk.Frame(open_form_window2, bg='khaki', pady=2) 89 label11 = tk.Label(new_frame2, text="製番", font=("", 9), fg='black', bg="antique white", height=1, width=8) 90 label12 = tk.Label(new_frame2, text=values[0], font=("", 10), fg='black', bg="antique white", height=1, width=8) 91 label13 = tk.Label(new_frame2, text="得意先名", font=("", 9), fg='black', bg="antique white", height=1, width=10) 92 label14 = tk.Label(new_frame2, text=values[1], font=("", 10), fg='black', bg="antique white", height=1, width=20) 93 button2 = tk.Button(new_frame2, text="上書き", font=("", 10), width=8, bg="#e6e6fa", command=update_nouki) 94 label11.pack(side=tk.LEFT, padx=2) 95 label12.pack(side=tk.LEFT, padx=2) 96 label13.pack(side=tk.LEFT, padx=2) 97 label14.pack(side=tk.LEFT, padx=2) 98 button2.pack(side=tk.RIGHT, expand=None, padx=5) 99 new_frame2.pack(fill='both', expand=None) 100 101 new_frame3 = tk.Frame(open_form_window2, bg='khaki', pady=5) 102 label21 = tk.Label(new_frame3, text="希望納期", font=("", 9), fg='black', bg="antique white", height=1, width=11) 103 label22 = tk.Label(new_frame3, text="目標納期", font=("", 9), fg='black', bg="antique white", height=1, width=11) 104 label23 = tk.Label(new_frame3, text="回答納期", font=("", 9), fg='black', bg="antique white", height=1, width=11) 105 label24 = tk.Label(new_frame3, text="出荷予定", font=("", 9), fg='black', bg="antique white", height=1, width=11) 106 button3 = tk.Button(new_frame3, text="希望", font=("", 9), width=9, bg="#e6e6fa", command=update_dl1) 107 label21.pack(side=tk.LEFT, padx=15) 108 label22.pack(side=tk.LEFT, padx=7) 109 label23.pack(side=tk.LEFT, padx=7) 110 label24.pack(side=tk.LEFT, padx=7) 111 button3.pack(side=tk.RIGHT, expand=None, padx=5) 112 new_frame3.pack(fill='both', expand=None) 113 114 style = ttk.Style() 115 style.theme_use('clam') 116 style.configure('my.DateEntry', 117 fieldbackground='light green', 118 background='dark green', 119 foreground='black', 120 arrowcolor='white') 121 122 root.data_entry_date = DateEntry(style='my.DateEntry', showweeknumbers=False) 123 root.data_entry_date.place(x=250, y=230) 124 125 root.calender_date = DateEntry(showweeknumbers=False) 126 root.calender_date.place(x=500, y=230) 127 root.calender_date.pack() 128 129 new_frame4 = tk.Frame(open_form_window2, bg='khaki', pady=0) 130 entry31 = DateEntry(new_frame4, style='my.DateEntry', showweeknumbers=False, locale='ja_JP.UTF-8', width=11) 131 entry32 = DateEntry(new_frame4, style='my.DateEntry', showweeknumbers=False, locale='ja_JP.UTF-8', width=11) 132 entry33 = DateEntry(new_frame4, style='my.DateEntry', showweeknumbers=False, locale='ja_JP.UTF-8', width=11) 133 entry34 = DateEntry(new_frame4, style='my.DateEntry', showweeknumbers=False, locale='ja_JP.UTF-8', width=11) 134 entry31.pack(side=tk.LEFT, padx=15) 135 entry32.pack(side=tk.LEFT, padx=5) 136 entry33.pack(side=tk.LEFT, padx=5) 137 entry34.pack(side=tk.LEFT, padx=5) 138 new_frame4.pack(fill='both', expand=None) 139 form.pack() 140 open_form_window2.attributes("-topmost", True) 141 142 entry31.delete(0, "end") 143 entry32.delete(0, "end") 144 entry33.delete(0, "end") 145 entry34.delete(0, "end") 146 147 if uwagaki == 0: 148 entry31.insert(0, values[2]) 149 entry32.insert(0, values[3]) 150 entry33.insert(0, values[4]) 151 entry34.insert(0, values[5]) 152 else: 153 entry31.insert(0, nouki1) 154 entry32.insert(0, nouki2) 155 entry33.insert(0, nouki3) 156 entry34.insert(0, nouki4) 157 158def update_nouki(): 159 global nouki1 160 global nouki2 161 global nouki3 162 global nouki4 163 global uwagaki 164 print(entry31.get_date()) 165 idno = label12.cget("text") 166 if entry31 is None: 167 entry31.delete() 168 else: 169 dl1 = entry31.get_date() 170 171 dl2 = entry32.get_date() 172 dl3 = entry33.get() 173 dl4 = entry34.get_date() 174 175 sql = f"UPDATE [Test].[dbo].[Tr_Slip_table] SET [希望納期] = '{dl1}',[目標納期] = '{dl2}',[回答納期] = '{dl3}',[出荷予定日] = '{dl4}' WHERE [Id]={idno};" 176 res = tkinter.messagebox.askyesnocancel(title="上書き確認", message="表示の内容で更新します。納期情報を残しておきますか?") 177 print(res) 178 if res == True: 179 cursor.execute(sql) 180 cursor.commit() 181 nouki1 = entry31.get_date() 182 nouki2 = entry32.get_date() 183 nouki3 = entry33.get_date() 184 nouki4 = entry34.get_date() 185 uwagaki = 1 186 print(nouki1) 187 print(type(nouki1)) 188 open_tree() 189 elif res == False: 190 print(sql) 191 cursor.execute(sql) 192 cursor.commit() 193 nouki1 = "" 194 nouki2 = "" 195 nouki3 = "" 196 nouki4 = "" 197 uwagaki = 0 198 open_tree() 199 else: tkinter.messagebox.showinfo(title="取り消し", message="処理を取り消しました") 200 201def update_dl1(): 202 global entry31 203 global entry32 204 global entry34 205 start_date = entry31.get_date() 206 207 if is_holiday_or_weekend(start_date) == True: 208 res = tkinter.messagebox.askokcancel(title="タイトル", message="休日です処理を中止します") 209 if res == True: 210 return 211 else: 212 print(res) 213 else: 214 print(start_date) 215 216 start_date = start_date + datetime.timedelta(days=-1) 217 while is_holiday_or_weekend(start_date) == True: 218 start_date = start_date + datetime.timedelta(days=-1) 219 220 entry32.delete(0, "end") 221 entry32.insert(0, start_date) 222 entry34.delete(0, "end") 223 entry34.insert(0, start_date) 224 print(start_date) 225 226def is_holiday_or_weekend(date): 227 return date.weekday() == 6 or date.weekday() == 5 or jpholiday.is_holiday(date) 228 229def close_tree(): 230 global open_form_window 231 232 if open_form_window: open_form_window.destroy() 233 234open_form_window = None 235open_form_window2 = None 236root = tk.Tk() 237root.title("納期変更アプリ") 238root.geometry("450x40") 239root.geometry('+1300+900') 240root.configure(bg='khaki1') 241root.overrideredirect(True) 242 243frame1 = tk.Frame(root, pady=5, padx=5, relief=tk.RAISED, bd=2, bg='khaki') 244label1 = tk.Label(frame1, text="納期変更アプリ", font=("", 10), fg='black', bg="antique white", height=1, width=12) 245 246button1 = tk.Button(frame1, text="読込", font=("", 10), width=8, bg="#e6e6fa", command=open_tree) 247 248button3 = tk.Button(frame1, text="×", font=("", 8, "bold"), width=1, fg='white', bg='red', command=root.destroy) 249label1.pack(side=tk.LEFT) 250 251button1.pack(side=tk.LEFT, expand=True) 252 253button3.pack(side=tk.RIGHT) 254frame1.pack(fill=tk.BOTH, expand=True) 255 256 257nouki1 = "" 258nouki2 = "" 259nouki3 = "" 260nouki4 = "" 261uwagaki = 0 262 263if login(): 264 root.attributes("-topmost", True) 265 266else: 267 root.title("納期変更アプリ(接続エラー)") 268 button1['state'] = 'disabled' 269 button2['state'] = 'disabled' 270 271root.mainloop() 272

試したこと

dl1 = entry31.get_date() で日付でとるのがダメなのかと思い
dl1 = entry31.get() でも同じ結果
Noneでなく空白で試しても同じく今日の日付が代入される
Noneを検出してNoneの時だけ処理を変えることを検討したが、そもそもNoneを検出できない

補足情報(FW/ツールのバージョンなど)

Python 3.10.0
PyCharm 2021.3.2 (Community Edition)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoshiyoshi

2022/08/16 06:16

できる範囲で不要なところを削ってみました もう一度ご確認いただけないでしょうか SQLSERVERよりSQLにて情報を取り出しております import tkinter as tk from tkinter import ttk from tkcalendar import DateEntry import pyodbc import datetime, jpholiday import tkinter.filedialog DRIVER = '{SQL Server}' SQL_SERVER = 'SV03' PORT = 3306 DB_NAME = 'Test' TABLE_NAME = '[Test].[dbo].[Tr_Slip_table]' USER = '' PASSWORD = '' TRUSTED_CONNECTION = 'yes' def login(): global cursor cmd = f'DRIVER={DRIVER};SERVER={SQL_SERVER};DATABASE={DB_NAME};PORT={PORT};' print("cmd") if USER: cmd += f'USER={USER};' if PASSWORD: cmd += f'PASSWORD={PASSWORD};' if TRUSTED_CONNECTION: cmd += f'Trusted_Connection={TRUSTED_CONNECTION};' try: connect = pyodbc.connect(cmd, charset='utf8') except pyodbc.Error: return False cursor = connect.cursor() return True def open_tree(): global tree global Name global dst global ded global open_form_window sql = f"SELECT [Id],FORMAT([希望納期],'yyyy/MM/dd') FROM [Test].[dbo].[Tr_Slip_table]; " open_form_window = tk.Toplevel() open_form_window.title('納期一覧') open_form_window.configure(bg='khaki') open_form_window.overrideredirect(True) root_x, root_y = root.winfo_x(), root.winfo_y() open_form_window.geometry(f'450x240+{root_x - 0}+{root_y - 240}') print(root.__dict__) form = ttk.Frame(open_form_window) new_frame1 = tk.Frame(open_form_window, bg='khaki', pady=2) new_frame1.pack(fill='both', expand=True) form.pack() open_form_window.attributes("-topmost", True) tree = ttk.Treeview(open_form_window) tree["columns"] = (1, 2) tree["show"] = "headings" tree["displaycolumns"] = [1, 2] tree.column(1, width=40, anchor=tk.CENTER) tree.column(2, width=50, anchor=tk.E) tree.heading(1, text="製番") tree.heading(2, text="希望納期") tree.pack(padx=(5,5), pady=(5,5), fill='both', expand=True) # TreeViewのデータをクリア for item in tree.get_children(): tree.delete(item) for row in cursor.execute(sql): row = list(row) tree.insert("", "end", values=row) tree.bind('<Double-1>', getVule) def getVule(event): selected_items = tree.selection() if not selected_items: return values = tree.item(selected_items[0], 'values') with open('log.txt', 'a') as f: print(values, file=f) global open_form_window2 global nouki1 global label12 global entry31 if open_form_window2: open_form_window2.destroy() open_form_window2 = tk.Toplevel() open_form_window2.title('納期変更') open_form_window2.configure(bg='khaki') open_form_window2.overrideredirect(True) root_x, root_y = root.winfo_x(), root.winfo_y() open_form_window2.geometry(f'450x80+{root_x - 0}+{root_y - 325}') print(root.__dict__) form = ttk.Frame(open_form_window2) new_frame2 = tk.Frame(open_form_window2, bg='khaki', pady=2) label11 = tk.Label(new_frame2, text="製番", font=("", 9), fg='black', bg="antique white", height=1, width=8) label12 = tk.Label(new_frame2, text=values[0], font=("", 10), fg='black', bg="antique white", height=1, width=8) button2 = tk.Button(new_frame2, text="上書き", font=("", 10), width=8, bg="#e6e6fa", command=update_nouki) label11.pack(side=tk.LEFT, padx=2) label12.pack(side=tk.LEFT, padx=2) button2.pack(side=tk.RIGHT, expand=None, padx=5) new_frame2.pack(fill='both', expand=None) new_frame3 = tk.Frame(open_form_window2, bg='khaki', pady=5) label21 = tk.Label(new_frame3, text="希望納期", font=("", 9), fg='black', bg="antique white", height=1, width=11) label21.pack(side=tk.LEFT, padx=15) new_frame3.pack(fill='both', expand=None) # カレンダーのスタイル style = ttk.Style() style.theme_use('clam') style.configure('my.DateEntry', fieldbackground='light green', background='dark green', foreground='black', arrowcolor='white') root.data_entry_date = DateEntry(style='my.DateEntry', showweeknumbers=False) root.data_entry_date.place(x=250, y=230) root.calender_date = DateEntry(showweeknumbers=False) root.calender_date.place(x=500, y=230) root.calender_date.pack() new_frame4 = tk.Frame(open_form_window2, bg='khaki', pady=0) entry31 = DateEntry(new_frame4, style='my.DateEntry', showweeknumbers=False, locale='ja_JP.UTF-8', width=11) entry31.pack(side=tk.LEFT, padx=15) new_frame4.pack(fill='both', expand=None) form.pack() open_form_window2.attributes("-topmost", True) entry31.delete(0, "end") if uwagaki == 0: entry31.insert(0, values[1]) else: entry31.insert(0, nouki1) def update_nouki(): global nouki1 global uwagaki idno = label12.cget("text") if entry31 is None: entry31.delete() else: dl1 = entry31.get_date() sql = f"UPDATE [Test].[dbo].[Tr_Slip_table] SET [希望納期] = '{dl1}' WHERE [Id]={idno};" res = tkinter.messagebox.askyesnocancel(title="上書き確認", message="表示の内容で更新します。納期情報を残しておきますか?") print(res) if res == True: cursor.execute(sql) cursor.commit() nouki1 = entry31.get_date() uwagaki = 1 open_tree() elif res == False: cursor.execute(sql) cursor.commit() nouki1 = "" uwagaki = 0 open_tree() else: tkinter.messagebox.showinfo(title="取り消し", message="処理を取り消しました") def is_holiday_or_weekend(date): return date.weekday() == 6 or date.weekday() == 5 or jpholiday.is_holiday(date) def close_tree(): global open_form_window if open_form_window: open_form_window.destroy() open_form_window = None open_form_window2 = None root = tk.Tk() root.title("納期変更アプリ") root.geometry("450x40") root.geometry('+1300+900') root.configure(bg='khaki1') root.overrideredirect(True) frame1 = tk.Frame(root, pady=5, padx=5, relief=tk.RAISED, bd=2, bg='khaki') label1 = tk.Label(frame1, text="納期変更アプリ", font=("", 10), fg='black', bg="antique white", height=1, width=12) button1 = tk.Button(frame1, text="読込", font=("", 10), width=8, bg="#e6e6fa", command=open_tree) button3 = tk.Button(frame1, text="×", font=("", 8, "bold"), width=1, fg='white', bg='red', command=root.destroy) label1.pack(side=tk.LEFT) button1.pack(side=tk.LEFT, expand=True) button3.pack(side=tk.RIGHT) frame1.pack(fill=tk.BOTH, expand=True) nouki1 = "" uwagaki = 0 if login(): root.attributes("-topmost", True) else: root.title("納期変更アプリ(接続エラー)") button1['state'] = 'disabled' button2['state'] = 'disabled' root.mainloop()
guest

回答3

0

ベストアンサー

抜粋の場合、範囲外に問題があることもあるので、
問題箇所を分かりやすくするために、問題が再現できる実行可能な最小限のコードを
質問用に作成して掲載してください。(DateEntry を一つのみ配置したコードで挙動を確かめる)

外部ライブラリだと思いますが、DateEntry が未定義です。
ウィジェットから値を取り出すときの問題なのか、
データベースに値を入れる時のデフォルト値なのかが不明瞭です。
(今回の件では恐らく違いますが、例えば問題がデータベースのテーブルの制約だった場合は、
掲載コードの範囲外の情報になってきます)

問題点
DateEntryを tkcalendar.dateentry ライブラリのもの場合、
コンストラクタで内部的に現在の日付を予め保持します。

対策
_set_text メソッドで予め空文字列を設定しておくことで
getメソッドで所得できるデフォルトの値を上書きできます。

アンダーバー付きのメソッドなので、手順としては DateEntry のサブクラスを作成し、
そのコンストラクタ内でデフォルト値を設定すると良いです。外部からの呼び出しは可能ですが非推奨。

但し、一度でもカレンダーを開くと今日の日付が設定されてしまうので、
その辺も対応したい場合は、ユーザーが日付選択をキャンセル出来るようにするなど
目的の挙動に合わせたカスタマイズが必要になってきます。

投稿2022/08/16 01:55

編集2022/08/16 01:57
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

提示コードを詳しく確認できていませんが、おそらくTkcalendar DateEntry - Allow Widget to Return No Selection as Blankの回答にあるように、tkcalendar.DateEntryの派生クラスを利用することで実現できるかと思います。

投稿2022/08/16 01:22

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ご回答有難うございました。

ご提案頂いたサブクラスの定義が出来れば良かったのですが、何回チャレンジしても成功せず諦めました。

ただDateEntryのデフォルト値が悪さをしている事を教えて頂けたのでそれをヒントにひとまず解決しました。

邪道なやり方だと思いますが、事前にNoneもしくは空白かを確認し、通常の日付が入力されている時と処理を変えました。

dl1の引き渡し時に Noneは’null’とするとエラー 日付は’日付’が無いとエラーとなり、日付のdl1に’’を付与しようとしたので上手くいかず冗長になってしまいましたが、一応これで目的としていた処理が出来ました。

まだテスト用に一項目だけにした環境で実行できただけで、実際のプログラムで動くか判りませんが、ひとまず御礼と報告まで

python

1 if entry31.get() == 'None': 2 dl1 = 'null' 3 sql = f"UPDATE [Test].[dbo].[Tr_Slip_table] SET [希望納期] = {dl1} WHERE [Id]={idno};" 4 print(sql) 5 elif entry31.get() == '': 6 dl1 = 'null' 7 sql = f"UPDATE [Test].[dbo].[Tr_Slip_table] SET [希望納期] = {dl1} WHERE [Id]={idno};" 8 print(sql) 9 else: 10 dl1 = entry31.get_date() 11 sql = f"UPDATE [Test].[dbo].[Tr_Slip_table] SET [希望納期] = '{dl1}' WHERE [Id]={idno};" 12 print(sql) 13コード

投稿2022/08/18 02:02

yoshiyoshi

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問