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

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

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

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

Tkinter

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

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

PyCharm

エディター・開発ツール

Q&A

解決済

2回答

2044閲覧

[Python3]在庫管理システムのログイン,ログアウトがうまくいかない

MM921

総合スコア14

Python 3.x

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

Tkinter

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

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

PyCharm

エディター・開発ツール

1グッド

0クリップ

投稿2020/11/20 04:43

編集2020/11/20 05:51

前提・実現したいこと

いつもお世話になっております。
これはログイン画面で名前を入力した後,計算画面で在庫計算を行う,そしてBackボタンを押して一枚目に戻る,という流れです。二回目のログインがうまくいきません。
これを改善して正しくログイン,ログアウトが行えるようにしたいです。
↓ログイン画面(1枚目)
![!イメージ説明
↓計算画面(2枚目)
イメージ説明

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

Backボタンを押してログイン画面に戻った後,エントリーボックスに一回目と違う名前を入れても一回目に入れた名前と同じになります。
例)1回目に「田中」と入れて,Backボタンでログイン画面に戻ってログアウトした。
(このログアウトとは,「田中さんが退室しました」と出庫管理という別ファイルに履歴に書かれることを指します。)
その後「有吉」と入れてログインしても,ファイルには「有吉」と表記されずに「田中」と表記されていた。

# -*- coding: utf-8 -*- import tkinter from tkinter import* try: import tkinter as tk except: import tkinter as tk import datetime window = tkinter.Tk() window.geometry("1358x750") window.title("Screen Transition") f1 = open('マジック赤.txt') f2 = open('マジック青.txt') f3 = open('マジック黒.txt') data1 = f1.read() data2 = f2.read() data3 = f3.read() f1.close() f2.close() f3.close() canvas1 = tkinter.Canvas(bd=0, width=1366, height=768) titleLabel_j = tk.Label(canvas1, text=" ※@で画面を閉じる ", font=('Helvetica', '13'), fg='gray8') titleLabel_j.place(relx=0.85, rely=0.01) canvas1.place(x=0, y=0) # キャンバス label_a = tkinter.Label(canvas1, text="こんにちは。前室在庫管理システムです。", font=('BIZ UDゴシック', '25', 'bold'), bg="misty rose", fg='firebrick4') label_a.place(relx=0.29, rely=0.25) label_b = tkinter.Label(canvas1, text="下記のボックスにカーソルを置いて,別紙の社員QRコードをかざしてログインしてください。", font=('BIZ UDゴシック', '15'), fg= 'gray4') # テキスト label_b.place(relx=0.23, rely=0.35) label1 = tkinter.Label(canvas1, text="↓Name Here↓", font=('BIZ UDゴシック', '23'), fg='gray4') label1.place(relx=0.42, rely=0.42) button = tkinter.Button(canvas1, text=" Go ", font=('BIZ UDゴシック', '15'), command=lambda: transition_button1(canvas1), fg='gray4') button.place(relx=0.45, rely=0.53) button_kaisetsu = tkinter.Button(canvas1, text="使い方の詳細", font=('BIZ UDゴシック', '15'), command=lambda: kaisetsuPage(), fg='gray4') button_kaisetsu.place(relx=0.85, rely=0.05) entry1 = tkinter.Entry(canvas1, font=('Helvetica', '20')) entry1.place(relx=0.39, rely=0.47) def kaisetsuPage(): window = tkinter.Tk() window.geometry("500x600") def transition_button1(widget): widget.place_forget() canvas2 = tkinter.Canvas(bd=0, width=1366, height=768) canvas2.place(x=0, y=0) #Top Widget上に Scrollbar を生成して配置 bar = tk.Scrollbar(window, orient=tk.VERTICAL) bar.pack(side=tk.RIGHT, fill=tk.Y) bar.config(command=canvas2.yview) # Canvas Widget をTopWidget上に配置 canvas2.config(yscrollcommand=bar.set) canvas2.config(scrollregion=(0, 0, 500, 900)) canvas2.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # Frame Widgetを 生成 frame = tk.Frame(canvas2) # Frame Widgetを Canvas Widget上に配置() canvas2.create_window((0, 0), window=frame, anchor=tk.NW, width=1366, height=768) # Frame Widget上に各種ラベルを表示 aaa = tk.Label(frame, text='マジック', font=('Helvetica', '15')) aaa.place(x=63, y=80) bbb = tk.Label(frame, text='bbb', font=('Helvetica', '15')) bbb.place(x=63, y=130) ccc = tk.Label(frame, text='ccc', font=('Helvetica', '15')) ccc.place(x=63, y=180) ddd = tk.Label(frame, text='ddd', font=('Helvetica', '15')) ddd.place(x=63, y=230) eee = tk.Label(frame, text='eee', font=('Helvetica', '15')) eee.place(x=63, y=280) fff = tk.Label(frame, text='fff', font=('Helvetica', '15')) fff.place(x=63, y=330) t0 = Text(width=30, height=40) t0.place(relx=0.8, rely=0.2) titleLabel5 = tk.Label(frame, text=data1, font=('Helvetica', '15')) titleLabel5.place(x=300, y=78) titleLabel6 = tk.Label(frame, text=data2, font=('Helvetica', '15')) titleLabel6.place(x=300, y=128) titleLabel7 = tk.Label(frame, text=data3, font=('Helvetica', '15')) titleLabel7.place(x=300, y=178) sptxt1 = StringVar() sp1 = Spinbox(frame, textvariable=sptxt1, from_=0, to=10, increment=1) sp1.place(x=485, y=80) sptxt2 = StringVar() sp2 = Spinbox(frame, textvariable=sptxt2, from_=0, to=10, increment=1) sp2.place(x=485, y=130) sptxt3 = StringVar() sp3 = Spinbox(frame, textvariable=sptxt3, from_=0, to=10, increment=1) sp3.place(x=485, y=180) date = datetime.datetime.now() print(date.year, "年", date.month, "月", date.day, "日", date.hour, "時", date.minute, "分", date.second, "秒") print(entry1.get(), "さんこんにちは!") file = "出庫履歴.txt" f4 = open(file, "a", encoding="utf_8") print(date.year, "年", date.month, "月", date.day, "日", date.hour, "時", date.minute, "分", date.second, "秒", file=f4) print(entry1.get(), "さんが入室しました。", file=f4) titleLabel_1 = tk.Label(canvas2, text=" 出庫したい備品の個数を指定して「出庫」ボタンを押してください。 ", font=('BIZ UDゴシック', '15'), bg="misty rose", fg='gray4') titleLabel_1.place(relx=0, rely=0) titleLabel_2 = tk.Label(canvas2, text=" 備品名 備品個数 必要個数 ", font=('BIZ UDゴシック', '25', 'bold'), bg="misty rose", fg='firebrick4') titleLabel_2.place(relx=0, rely=0.035) back_button = tkinter.Button(canvas2, text=" back ", command=lambda:transition_button2(canvas1), font=('BIZ UDゴシック', '13')) # 遷移ボタン back_button.place(relx=0.9, rely=0.01) kakutei_button = tk.Button(canvas2, text="確定",font=('BIZ UDゴシック', '13'), command=lambda:Kakutei(canvas2)) kakutei_button.place(relx=0.4, rely=0.85) def Kakutei(widget): f1 = open('マジック赤.txt') data1 = f1.read() f1.close() o = int(data1) p = int(sp1.get()) a = o - p titleLabel5.destroy() f1 = open('マジック赤.txt', 'w') print(a, file=f1) titleLabel10 = tk.Label(frame, text=a, font=('Helvetica', '15')) titleLabel10.place(x=300, y=78) f2 = open('マジック青.txt') data2 = f2.read() f2.close() q = int(data2) r = int(sp2.get()) b = q - r titleLabel6.destroy() f2 = open('マジック青.txt', 'w') print(b, file=f2) titleLabel8 = tk.Label(frame, text=b, font=('Helvetica', '15')) titleLabel8.place(x=300, y=128) f3 = open('マジック黒.txt') data3 = f3.read() f3.close() s = int(data3) t = int(sp3.get()) c = s - t titleLabel7.destroy() f3 = open('マジック黒.txt', 'w') print(c, file=f3) titleLabel9 = tk.Label(frame, text=c, font=('Helvetica', '15')) titleLabel9.place(x=300, y=178) print("残り在庫") print("マジック赤", a, "個", " (-", p, "個)") print("マジック青", b, "個", " (-", r, "個)") print("マジック黒", c, "個", " (-", t, "個)") file = "出庫履歴.txt" f4 = open(file, "a", encoding="utf_8") print("マジック赤", a, "個", " (-", p, "個)", file=f4) print("マジック青", b, "個", " (-", r, "個)", file=f4) print("マジック黒", c, "個", " (-", t, "個)", file=f4) t0.insert(tk.END, "マジック赤") t0.insert(tk.END, a) t0.insert(tk.END, "個 ") t0.insert(tk.END, " (-") t0.insert(tk.END, p) t0.insert(tk.END, "個)\n") t0.insert(tk.END, "マジック青") t0.insert(tk.END, b) t0.insert(tk.END, "個 ") t0.insert(tk.END, " (-") t0.insert(tk.END, r) t0.insert(tk.END, "個)\n") t0.insert(tk.END, "マジック黒") t0.insert(tk.END, c) t0.insert(tk.END, "個 ") t0.insert(tk.END, " (-") t0.insert(tk.END, t) t0.insert(tk.END, "個)\n") # back_button実行結果 def transition_button2(widget): canvas2.pack_forget() back_button.pack_forget() bar.pack_forget() frame.pack_forget() aaa.pack_forget() bbb.pack_forget() ccc.pack_forget() ddd.pack_forget() eee.pack_forget() fff.pack_forget() titleLabel_1.pack_forget() titleLabel_2.pack_forget() print("お疲れさまでした!") file = "出庫履歴.txt" f4 = open(file, "a", encoding="utf_8") print(entry1.get(), "さんが退室しました。", file=f4) # 画面1の復元 canvas1 = tkinter.Canvas(bd=0, width=1366, height=768) titleLabel_j = tk.Label(canvas1, text=" ※@で画面を閉じる", font=('Helvetica', '13'), fg='gray8') titleLabel_j.place(relx=0.85, rely=0.01) canvas1.place(x=0, y=0) # キャンバス label_a = tkinter.Label(canvas1, text="こんにちは。前室在庫管理システムです。", font=('BIZ UDゴシック', '25','bold'), bg="misty rose", fg='firebrick4') label_a.place(relx=0.29, rely=0.25) label_b = tkinter.Label(canvas1, text="下記のボックスにカーソルを置いて,別紙の社員QRコードをかざしてログインしてください。", font=('BIZ UDゴシック', '15'), fg='gray4') # テキスト label_b.place(relx=0.23, rely=0.35) label1 = tkinter.Label(canvas1, text="↓Name Here↓", font=('BIZ UDゴシック', '23'), fg='gray4') label1.place(relx=0.42, rely=0.42) button = tkinter.Button(canvas1, text="Go", font=('BIZ UDゴシック', '15'), command=lambda:transition_button1(canvas1), fg='gray4') button.place(relx=0.45, rely=0.53) entry2 = tkinter.Entry(canvas1, font=('Helvetica', '20')) entry2.place(relx=0.39, rely=0.47) button_kaisetsu = tkinter.Button(canvas1, text="使い方の詳細", font=('BIZ UDゴシック', '15'), command=lambda: kaisetsuPage(), fg='gray4') button_kaisetsu.place(relx=0.85, rely=0.05) if __name__ == "__main__": def process_b(): quit() def key(event): if event.char == "@": process_b() window.bind("<Key>", key) window.focus_set() window.mainloop()

試したこと

上記のentry1.get()の名前をかえましたがエラーがでました。
お手数ですが何卒よろしくお願いします。

teamikl👍を押しています

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

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

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

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

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

teamikl

2020/11/22 11:03

> 上記のentry1.get()の名前をかえましたがエラーがでました。 どのように名前を変え、どんなエラーがでました? entry2 にすると UnboundLocalError が出ると思います。 ---- 多数のファイルを読み込んでいて、コードをそのまま実行できないので、 実行に必要な手順を記載するか、 そのままコピー&ペーストのみで実行できるように、 問題の再現に必要な部分のみの最小限のコードを掲載してください。
MM921

2020/11/24 01:42

teamiklさん,ご回答,ご指摘ともにありがとうございます。 申し訳ありません。文字数の関係で詳しくかけておりませんでした。 おっしゃっているようにentry2.get()というように変えたところ上記のようなエラーが起きました。
guest

回答2

0

ベストアンサー

暫定的な対策案1: global 宣言をする

python

1 def transition_button2(widget): 2 global entry1 3 4 ... 5 6 print(entry1.get(), "さんが退室しました。", file=f4) 7 8 # 画面1の復元 9 10 ... 11 12 entry1 = tkinter.Entry(canvas1, font=('Helvetica', '20')) 13 entry1.place(relx=0.39, rely=0.47)

※ コードは実行できてません。未確認

算定的な対策案2: StringVar を使う

python

1 2nameVar = tkinter.StringVar() 3entry1 = tkinter.Entry(canvas1, textvar=nameVar, font=('Helvetica', '20')) 4 5... 6 7 def transition_button2(widget): 8 ... 9 10 print(nameVar.get(), "さんこんにちは!") 11 12 # 画面1の復元 13 14 # StringVar の内容を消去。オブジェクトは破棄せずに使いまわす 15 nameVar.set("") 16 17 entry1 = tkinter.Entry(canvas1, textvar=nameVar, font=('Helvetica', '20')) 18 entry1.place(relx=0.39, rely=0.47) 19

※ コードは実行できてません。未確認


根本的な対策(大幅な変更が必用です)

画面1の復元は、初期化時と2回目以降を同じコードで出来るように
別関数に切り出した方が良いです。

現状のコードでは、非表示なだけで残ってるウィジェットがいくつかあり、
何度も呼び出されると、未開放のウィジェットが蓄積されていく問題があります。
何千何万回規模で呼び出したりしない限り、問題になる事はありませんが、
プログラムが複雑になってる要因でもあるので、改善可能な点です。

より根本的な対策では、
画面をFrame上に構築し、予めレイヤーの様に重ねておいて、
tkraiseメソッドで上に持ってくることで表示を切り替える、画面遷移の実装方法がお勧めです。
画面毎のコードの管理もしやすくなり、上記の問題も解消します。

投稿2020/11/22 11:51

編集2020/11/22 11:53
teamikl

総合スコア8760

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

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

0

詳しくは見ていませんが……

entry1 = tkinter.Entry(canvas1, font=('Helvetica', '20'))

entry1はcanvas1に関連して作成されているようですが

# 画面1の復元 canvas1 = tkinter.Canvas(bd=0, width=1366, height=768)

ここでcanvas1は新しいものを作成しているようなので、
entry1も設定しなおせば、つじつまが合うのではないでしょうか……。

投稿2020/11/20 15:19

gasbombe

総合スコア204

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

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

teamikl

2020/11/22 11:22

加えて、最初のcanvas1 はグローバル変数 transition_button2関数内のcanvas1 はローカル変数になっている点も注意が必要です。 「entry1を設定しなおす」という部分の具体的な方法が、 現状のコードからは難しそうに思います。(解決策の方向としては同意です。 tkinter ではウィジェットの親を変更することはできない為、 より根本的なところ(ページ遷移の実装方法自体)からの改変が必用になりそうです。 暫定的な対策(少ないコード変更)で、何とかなりそうな方法は、 - entry の変数を、関数内でグローバル宣言をする。  (※プログラムの変数の状態の把握が複雑になる為、あまり良い方法ではない) - Entry に対し tkinter.StringVar を使う、等でしょうか。  StringVar は破棄せずにグローバルで、entry1.get の代わりに用います。 根本的な対策は、 ウィジェットを毎回破棄・生成するような画面遷移ではなく、 画面毎のウィジェットを予め作成しておき、表示非表示を切り替える方式がお勧めです。 (大幅な変更が必用になります)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問