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

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

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

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

Q&A

解決済

1回答

1285閲覧

PythonでTkinterを使用して、前のラベルと重な手表示させない方法

rereha

総合スコア7

Python

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

0グッド

0クリップ

投稿2022/12/15 02:12

前提

ここに質問の内容を詳しく書いてください。
PythonでTkinterを使用して、同じ場所に複数回別のラベルを表示させると前のラベルと重なって表示されます。これを回避するためにbox_deleteという関数を用意して消そうとしましたが上手く機能していません。どうしたら前の文字を消して新しい文字を上に乗せることが出来ますか?

python

1 2# tkinterのインポート 3import tkinter as tk 4import tkinter.ttk as ttk 5from tkinter import messagebox 6import numpy as np 7import pandas as pd 8import math 9import os 10#条件に一致するファイルの取得 11import glob 12 13def box_delete(): 14 if c==1: 15 label1.place_forget() 16 elif c==2: 17 label2.place_forget() 18 elif c==3: 19 label3.place_forget() 20 else: 21 pass 22 23def enter_data(event): 24 if (combobox1.get())=='丸': 25 box_delete() 26 c=1 27 28 label1=tk.Label(root2,text='あいうえお') 29 label1.place(x=60,y=210) 30 print(c) 31 elif (combobox1.get())=='板': 32 box_delete() 33 c=2 34 35 label2=tk.Label(root2,text='さし') 36 37 label2.place(x=60,y=210) 38 print(c) 39 40 41 elif (combobox1.get())=='六角': 42 box_delete() 43 c=3 44 45 label3=tk.Label(root2,text='たちつてとかき') 46 label3.place(x=60,y=210) 47 print(c) 48 49root2 = tk.Tk() 50root2.title('なにぬねの') 51root2.geometry('480x840') 52 53 54 55module1 = ('丸','板', '六角') 56variable1 = tk.StringVar() 57combobox1 = ttk.Combobox(root2, height=3,textvariable= variable1, values=module1) 58combobox1.place(x=90,y=170) 59combobox1.bind('<<ComboboxSelected>>', enter_data) 60 61label32=tk.Label(root2,text='形を選択') 62label32.place(x=30,y=170) 63c=0 64print(c) 65 66root2.mainloop()

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

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

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

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

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

guest

回答1

0

ベストアンサー

ウィジェット生成時の name を利用した、簡単な解決方法

name で毎回同じ名前を付けることで
同名のウィジェットの重複を防げます。

python

1label1=tk.Label(root2,text='あいうえお', name="label") 2label2=tk.Label(root2,text='さし', name="label") 3label3=tk.Label(root2,text='たちつてとかき', name="label")

追記: デメリットが一応あり、クラス化する際は固定で同じ名前をつけると、
クラスの再利用がしにくくなる状況があります。今回は関係なし。


現状のアプローチで前のウィジェットを削除する方法

label ウィジェットの destroy() メソッドを呼び出すことで破棄できます。
place_forget の場合は「非表示」なので、2度目以降に新規ウィジェットを生成してはいけません。

問題点は、label1~3 は関数内で宣言されたローカル変数の為、
他の関数からは参照できません。(name を付けると、root2 から nametowidgetメソッド で参照する方法はあります)
解決方法はいくつかあり

  • label変数をグローバル変数にして(双方の関数内でグローバル宣言、関数外で変数を初期化)box_delete 内で destroy する。
  • 予め3つのラベルを関数外で生成して、イベント時に一旦全部非表示してから、必要なものを place で表示

必ず、「生成・破棄」もしくは「place/forget で表示・非表示」のどちらかにします。

生成・破棄する方法
おそらく質問のコードで実装したい方法の場合は、注意点は変数のスコープ。

python

1label = None 2 3def enter_data(): 4 # グローバル変数への代入なので、グローバル宣言 5 global label 6 7 if label: # box_delete 8 label.destroy() 9 10 # ※ 同じ位置に表示する為、同時に複数存在しないなら同じ変数に格納し、 11 # 変数の管理を簡易化します。 12 13 if ...: 14 label = tk.Label(...) 15 elif ...: 16 label = tk.Label(...) 17 elif ...: 18 label = tk.Label(...)

表示非表示(place_forget)するアプローチ

python

1 2# グローバル変数で予め定生成しておく、place で表示はしない 3label1 = tk.Label(..., text="あいうえお") 4label2 = tk.Label(..., text="さし") 5label3 = tk.Label(..., text="かきくけこ") 6labels = {"丸": label1, "板": label2, "六角": label3} # 辞書にまとめておくと、一括して処理できるので、長いif文を省けます 7 8def enter_data(): 9 # box_delete 一旦全てのラベルを非表示 10 for label in labels.values(): 11 label.place_forget() 12 13 if label := labels.get(combobox1.get(), None): 14 label.place(6, 210)

追記: 目的の挙動を達成するためだけなら
Label ウィジェットは予め関数外に作成しておき、label.config(text="あいうえお") のように
ウィジェットはそのままで、表示する文字のみ変更する方法をお勧めします。

python

1# python 3.10+ 2 3from enum import Enum 4import tkinter as tk 5from tkinter import ttk 6 7 8class Shape(Enum): 9 CIRCLE, SQUARE, HEXAGON = "丸", "板", "六角" 10 11 @classmethod 12 def values(cls) -> list[str]: 13 return [x.value for x in cls] 14 15labels = { 16 Shape.CIRCLE: "あいうえお", 17 Shape.SQUARE: "かきくけこ", 18 Shape.HEXAGON: "さしすせそ", 19} 20 21def onComboboxSelected(event): 22 key = event.widget.get() 23 if value := labels.get(key, None): 24 label.config(text=value) 25 26 27root = tk.Tk() 28root.geometry("600x300") 29label = tk.Label(root) 30label.place(x=210, y=60) 31combo = ttk.Combobox(root, values=Shape.values()) 32combo.bind("<<ComboboxSelected>>", onComboboxSelected) 33combo.pack() 34root.mainloop()

投稿2022/12/15 03:24

編集2022/12/15 04:51
teamikl

総合スコア8664

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

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

rereha

2022/12/15 06:51

ありがとうございました。一番最初の回答で前に進めました。大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問