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

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

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

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Tkinter

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

Python

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

Q&A

解決済

1回答

1895閲覧

Tkinterのcanvas.create_textにて自動で改行したい

Tom_yamada

総合スコア9

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Tkinter

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

Python

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

0グッド

0クリップ

投稿2023/03/08 02:13

実現したいこと

openpyxlで読み込んだExcelファイルをTkinterのcanvasに表示する.
その際,セルごとに自動で改行するようにしたい.

前提

canvas.create_textを使って複数行のエクセルの中身を表示しようとするとすべて同じ座標に表示されて重なってしまいます.

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

イメージ説明
このように文字が重なってしまいます.

該当のソースコード

python

1import tkinter 2import openpyxl 3 4class Application(tkinter.Tk): 5 def __init__(self): 6 super().__init__() 7 8 # キャンバスのサイズ 9 self.canvas_width = 850 10 self.canvas_height = 490 11 12 self.after_canvas = tkinter.Canvas( 13 self, 14 width=self.canvas_width, 15 height=self.textcanvas_height, 16 bg="white" 17 ) 18 self.after_canvas.grid(row=2, column=1) 19 yscroll = tkinter.Scrollbar(self, orient=tkinter.VERTICAL, command=self.after_canvas.yview) 20 self.after_canvas["yscrollcommand"] = yscroll.set 21 yscroll.grid(row=2, column=2, sticky=tkinter.N+tkinter.S) 22 23 # ボタンを配置するフレームの作成と配置 24 self.button_frame = tkinter.Frame() 25 self.button_frame.grid(row=1, column=3) 26 27 # ファイル読み込みボタンの作成と配置 28 self.load_button = tkinter.Button( 29 self.button_frame, 30 text="load", 31 command=self.push_load_button 32 ) 33 self.load_button.pack(pady=10, ipady=10, ipadx=20) 34 35 #以下openpyxlの処理 36 def push_load_button(self): 37 wb = openpyxl.load_workbook('\test.xlsx') 38 active_sheet = wb.active 39 sheet_range = active_sheet['B2':'B4'] 40 41 # 範囲内のテキストを順次表示 42 for row in sheet_range: 43 for cell in row: 44 cell_value = cell.value 45 if cell.value is not None: # 改行できない 46 self.after_canvas.create_text(200, 30, text=cell.value + "\n", anchor="nw", fill="black", font=20) 47 48 49app = Application() 50app.mainloop()

試したこと

座標を固定してしまっていることは分かるのですがそれがいい感じに重ならないようにする方法が知りたいです.よろしくお願いいたします.

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

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

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

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

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

melian

2023/03/08 03:15

フォントの高さ分だけずらして行くという方法でもよいかと。 y = 30 for row in sheet_range:  for cell in row:   if cell.value is not None:    self.after_canvas.create_text(200, y, text=cell.value, anchor="nw", fill="black", font=20)    y += 20
Tom_yamada

2023/03/08 03:39

なるほど,これでしたらずらす値を変えることで行間も調整できそうです! ありがとうございます!
guest

回答1

0

ベストアンサー

以下のような感じで改行\nで連結された文字列を1つだけつくって、1回だけcreate_textすればよいかと思います。

Python

1 def push_load_button(self): 2 texts = [] 3 for t in ['あいう','abc', None, 'かきく']: 4 if t is not None: 5 texts.append(t) 6 self.after_canvas.create_text(200, 30, text='\n'.join(texts), anchor="nw", fill="black", font=20)

イメージ説明

追記:ChatGPTの回答

tkinterのcanvasにcreate_textで複数行の文字列を表示する場合、その行間を調整することはできますか

はい、TkinterのCanvasウィジェットのcreate_text()メソッドを使用して複数行のテキストを描画する場合、行間のスペースを調整することができます。具体的には、create_text()メソッドのanchor引数を使用して、テキストの描画位置を調整し、またfont引数を使用して、フォントサイズやフォント種類を指定することができます。

以下の例では、create_text()メソッドを使用して、複数行のテキストを描画する方法を示します。この例では、テキストの行間を10ピクセルに設定しています。

Python

1import tkinter as tk 2 3root = tk.Tk() 4 5canvas = tk.Canvas(root, width=200, height=200) 6canvas.pack() 7 8text = "This is a\nmultiline\ntext string." 9 10# テキストの描画位置を中央に設定し、フォントサイズを14に設定 11canvas.create_text(100, 100, text=text, font=("Arial", 14), anchor="center", justify="center", spacing=10) 12 13root.mainloop()

上記の例では、create_text()メソッドのspacing引数を使用して、行間のスペースを設定しています。この引数の値を変更することで、行間のスペースを調整することができます。ただし、この引数は、Tkinter 8.6以降でのみ使用可能です。Tkinterのバージョンが古い場合は、この方法は使用できません。

表示された文字列がキャンバスの範囲外に描画される場合、スクロールバーで全体を表示させることはできますか

はい、TkinterのCanvasウィジェットは、スクロールバーを追加して、Canvas上の全体を表示させることができます。

以下の例では、Canvasにテキストを描画し、テキストがキャンバスの範囲外に描画された場合、スクロールバーを使用してCanvasの全体を表示させる方法を示します。

Python

1import tkinter as tk 2 3root = tk.Tk() 4 5canvas = tk.Canvas(root, width=200, height=200) 6canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) 7 8# スクロールバーの設定 9scrollbar = tk.Scrollbar(root, orient=tk.VERTICAL, command=canvas.yview) 10scrollbar.pack(side=tk.RIGHT, fill=tk.Y) 11canvas.configure(yscrollcommand=scrollbar.set) 12 13# テキストを描画 14text = "This is a\nmultiline\ntext string." 15text_item = canvas.create_text(100, 100, text=text, font=("Arial", 14), anchor="center") 16 17# Canvasの範囲を設定 18canvas.configure(scrollregion=canvas.bbox("all")) 19 20root.mainloop()

この例では、Canvasにテキストを描画し、キャンバスの範囲外に描画された場合、スクロールバーを使用してCanvasの全体を表示させています。スクロールバーの設定は、Scrollbarウィジェットを作成し、Canvasのyscrollcommand引数にScrollbarのset()メソッドを設定することで行います。また、Canvasのscrollregion引数に、Canvas内の全体範囲を指定することで、スクロールバーを使用して全体を表示させることができます。

上記の例では、Canvasを左側に配置し、スクロールバーを右側に配置していますが、ウィンドウのレイアウトに合わせて適切な配置を設定してください。

投稿2023/03/08 02:28

編集2023/03/08 04:20
can110

総合スコア38266

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

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

Tom_yamada

2023/03/08 03:36

ご回答ありがとうございます。 このような方法があったんですね!表示できました! ちなみにこちら行間を変える方法ってありますか? また,今の状態だとY方向のスクロールバーは機能していないのでしょうか... 重ねての質問になってしまい申し訳ありません.
can110

2023/03/08 04:16 編集

canvasの属性、設定、あるいは create_textの引数なりで制御できるのかもしれません。 調べてみたらtkinter8.6以上のcreate_textではspacingという引数で行間は指定できるようです。 また、スクロールバーについてはcreate_textのあとに以下のような感じでスクロール範囲を更新してあげればよいようです。 self.after_canvas.configure(scrollregion=self.after_canvas.bbox("all"))
Tom_yamada

2023/03/08 04:43

ご丁寧にありがとうございます! 参考にさせていただきます🙇‍♂️
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問