🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
canvas

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

Python

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

Q&A

解決済

4回答

1216閲覧

PythonのsubprocessとCanvas

goldbug

総合スコア5

canvas

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

Python

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

0グッド

0クリップ

投稿2019/12/05 00:54

前提・実現したいこと

Pythonのtkinterを使い、Canvas上に文字を表示させたいのですが、main.pyでCanvasを作り、そこからimport subprocessで呼び出したtest.pyでCanvas上に文字を表示させる仕組みにしたいです。ところがエラーが出てうまくいきません。改善策はあるでしょうか?

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

File "test.py", line 1, in <module>
canvas.create_text(140, 140, text="test")
NameError: name 'canvas' is not defined

該当のソースコード

main.pyのコード

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=300, bg="white")
canvas.pack()

import subprocess
subprocess.run(['python','test.py'])

test.pyのコード

canvas.create_text(140, 140, text="test")

試したこと

ここに問題に対して試したことを記載してください。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答4

0

プロセスはオブジェクトを共有しません。
プロセスAで作ったオブジェクトは、プロセスBからは見えません。
2つの端末画面を開いて、それぞれでpythonコマンドを実行しているのと同じ状態です。

投稿2019/12/05 05:22

shiracamus

総合スコア5406

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

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

0

こういう場合、オブジェクトを共有するよりは、テキストを共有する方が良いと思います。
マルチプロセスにして負荷分散を行うなどといった場合もあろうかと思いますが、そういった場合でも情報表示と計算をわけ、情報表示(UI部)には、計算結果を渡すといった構成をとります。
今回は、test.pyでテキストを生成して、main.pyがテキストを取得待ちをして、テキストが取得できたらCanvasへ表示するという形かと。

で、そのテキスト情報をどのように共有するかですが、色々あって、今回の場合はPipeを利用するのが簡単そうです。
「python pipe subprocess」などでググれば色々と出てくると思いますが、以下がとりあえず参考になるかと。
https://qiita.com/caprest/items/0245a16825789b0263ad

投稿2019/12/05 04:21

t_obara

総合スコア5488

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

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

0

ベストアンサー

質問者さんがしようとしておられることはいわば曲芸です。

tkinterによるGUIを実現する場合、同一のプロセス内の同一のスレッドで全ての処理を行うのが普通です。それをあえて「別のプロセスから制御する」というのは不可能でないにしてもとても難しくtkinterおよびそれが内部的に制御しているTcl/Tkのメカニズムを熟知した上で取り組んで初めて可能だと思います。自分はそのようなことが実際に可能かどうかを知りませんが、よほどの理由がない限りそうした曲芸に取り組むのはお勧めしません。

もしGUIプログラムを複数のソースファイルに分割して実装したいというのが目的ならば、とりあえずsubprocessを使うのではなくtest.pyをメインプログラムから直接importして同じプロセス・同じスレッドの中で呼び出すようにしてはいかがでしょうか?

main.py

python

1import tkinter as tk 2import mytest 3 4root = tk.Tk() 5canvas = tk.Canvas(root, width=300, height=300, bg="white") 6canvas.pack() 7 8mytest.create_text(canvas) # importした別モジュールの関数を呼び出す 9 # そのモジュールにはmain.py側にある変数は見えないので 10 # 関数の引数に渡すのが常套手段 11 12root.mainloop() # これを呼び出さないとGUIが動き始めません。

mytest.py (pythonの標準モジュールにtestってのがあるので混乱を避けるためここではmytestにした)

python

1def create_text(canvas): 2 canvas.create_text(140, 140, text="test")

上記の二つのソースファイルを同一のディレクトリーに格納した上でmain.pyを動かせばとりあえず動くと思います。

cmd

1c:\path-to-project> python main.py

投稿2019/12/05 03:02

KSwordOfHaste

総合スコア18402

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

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

goldbug

2019/12/05 06:27

importしたmytest.pyからうまく呼び出せました。 コードを一つのファイルにまとめるか、別ファイルから呼び出すか、よく検討してみます。 ありがとうございました。
guest

0

canvas が存在しない、といってます。
あなたが使っているそのcanvasはどこで定義されてるものでしょう

投稿2019/12/05 01:14

y_waiwai

総合スコア88038

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

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

goldbug

2019/12/05 01:28

main.pyで定義しています。その定義がtest.pyには伝わっていないようで、伝える手段がないか模索しています。
y_waiwai

2019/12/05 01:30

ならそれを質問に書きましょう。 それではそもそも無理です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問