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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

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

Q&A

解決済

1回答

729閲覧

pythonで出力されるjsonデータを別のpythonファイルで受け取り、tkinerに表示したい

Kazuhiro-ch

総合スコア85

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

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

0グッド

0クリップ

投稿2022/10/27 03:13

バイナリファイルを変換して出力されるjsonログを別のファイルで受け取ると、jsonデータの一つ分しか取得できない。

##やりたいことの全体像
システムから出力されるバイナリファイルをjsonに変換するpythonファイルがある。現在、その出力されたjsonデータはコマンド上に表示させているが、今後は別のpythonファイルで受け取り、tkinterに表示したい。

##困っていること

現在、データを受け取り、表示させるところまでは完成したが、正しく表示されない。数十〜数百行あるデータの1つのみを取得し、culc_関数により同じデータ100件が表示されてしまう。

python

1#logger.py こちらを主として動かす 2from tkinter import messagebox 3import tkinter 4from tkinter import * 5from tkinter import ttk 6from tkinter import filedialog 7import os 8import datetime 9import to_json 10def writeToLog(msg): 11 numlines = int(log.index('end - 1 line').split('.')[0]) 12 log['state'] = 'normal' 13 #if numlines==24: 14 # #log.delete(1.0, 2.0) 15 if log.index('end-1c')!='1.0': 16 log.insert('end', '\n') 17 log.insert('end', msg) 18 log['state'] = 'disabled' 19def calc_(): 20 for i in range(100): 21 writeToLog(str(i)) 22if __name__ == '__main__': 23 # ウィンドウを作成 24 root = tkinter.Tk() 25 root.title("ツール名") 26 # アプリの名前 27 root.geometry("800x600") # アプリの画面サイズ 28 # Frame1の作成 29 frame1 = ttk.Frame(root, padding=10) 30 frame1.grid() 31 # # 検索ボタンの作成 32 refer_button = ttk.Button(frame1, text=u'出力ボタン', command=calc_) 33 refer_button.grid(row=3, column=1) 34 log = Text(root, state='disabled',borderwidth=5, width=110, height=30, wrap='none', padx=10,pady=10) 35 ys = ttk.Scrollbar(root, orient = 'vertical', command = log.yview) 36 log['yscrollcommand'] = ys.set 37 #log.insert('end', "Lorem ipsum...\n...\n...") 38 log.grid(row=4, column=0) 39 ys.grid(column = 1, row = 4, sticky = 'ns') 40 # ウィンドウを動かす 41 root.mainloop() 42

python

1#to_json.py ファイルの読み込み、出力を行う 2with log.file(sys.argv[1]) as log: 3 for msg in log: 4 if msg: 5 msg = output(msg) 6

ちなみに別ファイルに呼び出した時点で、データは一つになってしまっているようです。

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

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

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

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

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

teamikl

2022/10/27 04:12

インデント幅はスペース4つでお願いします。 例: for の後のif 字下げされてないように見えるが、 Tab 混在してる場合もあるので判別しにくい
Kazuhiro-ch

2022/10/27 04:22

すいません。諸事情があり、スマホからの投稿だったため、インデントがずれてしまったものとおもいます。申し訳ございません。
teamikl

2022/10/27 05:09 編集

いくつか確認したい点があります。 to_json 内での logオブジェクト, output 関数の定義は何処でしょう? to_json.py には関数定義はなく、 import した時点で実行されるのを想定していますか?
teamikl

2022/10/27 04:50 編集

>スマホからの投稿 なるほど、環境によってはそういうこともあるのですね。 一応インデントが曖昧な箇所はその2箇所だけだったので、 インデントによりどっちか解らないという状況はなく、支障なさそうです。 output 関数がなかったので、to_json をコメントアウトし、 インデントを修正し実行すると、0~99まで出力されました。 >culc_関数により同じデータ100件が表示されてしまう。 という状態は確認できませんでした。
Kazuhiro-ch

2022/10/27 05:08

> output 関数の定義はどこ これは外部からインポートするものでこの関数がjsonに変換するものです。そのため、to_jsonはファイルを受け取り、関数を処理し、吐き出すというプログラムになります。 > インデント修正、実行→0~99まで出力された。 はい。これはインターネットから拾ったものでそれが基本的な動作となります。また機能するはずです。ただ、jsonのmsgを受け取り、出力するとおかしくなってしまったいるようです。 もしかしたら受け渡しの方法が間違えているのかもしれません。loggerの方にどう渡せばいいのかわかっておらず、進めてしまっています。
teamikl

2022/10/27 05:16

肝心な受け渡しの部分が掲載されてませんね。 logger.py 側からは to_json は import だけして、値は参照してません。 > 。ただ、jsonのmsgを受け取り、出力するとおかしくなってしまったいるようです。 このおかしくなったときのコードを 試したこととして、質問に記載してください。 例えば、 for msg in ...  msg = output(msg) なので、もし msg をfor 文の後に渡しているのでしたら 繰り返しの度に msg は上書きされて、最後の msg のみが渡されることになります。 現状のコードからは問題の現象を再現できないので、 推測になってしまいます。
Kazuhiro-ch

2022/10/27 08:12

おっしゃられている通りみたいでした。 forの最終msgのみを受け取り、出力していました。 for文でログを蓄積→出力もしくはそのまま出力ということはできますでしょうか? もしよろしければやり方のヒントだけでも教えていただければとおもいます。
teamikl

2022/10/27 08:52

現状の構造のまま対応するなら、 リストに蓄積することで全てのデータを渡せますが、 to_json.py の内容は、関数として実装して logger.py から呼び出す形にじそすしたほうが良いです。 回答にサンプルコードを掲載します。
Kazuhiro-ch

2022/10/28 00:56

ご回答ありがとうございます。 with構文をdef関数にまとめた際に、importしたファイル(with log)が変数となり、local variable 'log' referenced before assignmentと出るのですが、どうすれば良いですか? また、to_json.py→def to_json, writetolog→output関数への置き換えという認識で間違いないでしょうか?
teamikl

2022/10/28 02:46

> with構文をdef関数にまとめた際に、importしたファイル(with log)が変数となり、local variable 'log' r> eferenced before assignmentと出るのですが、どうすれば良いですか? log の定義が質問のコードに提示されてないので、 第三者からは解らない箇所です。 (実行しているコードと掲載のコードが異なる可能性があります) エラー自体は、ローカル変数を定義前に使おうとしてる際に起こります。 >to_json.py→def to_json, writetolog→output関数への置き換えという認識で間違いないでしょうか? 概ねそのとおりです。ファイルを分ける必要があれば、to_json 関数を別の to_json ファイルで定義するようにしてください。
Kazuhiro-ch

2022/10/28 02:53

すいません。 loggerの方のlogに関してはネット上からの転記です。to_jsonの方のlogについては書き換えたものですので、違うものを指しています。わかりにくくしてしまい申し訳ございません。
guest

回答1

0

ベストアンサー

問題点は、変数 msg を上書きしているのが原因のようですね。
但し、変数を calc_ に渡すところが実装されていないので、
サンプルコードとして回答します

python

1# to_json.py 2 3def output(line): 4 # 実態がわからないため、値に対して何も変更しない 関数として実装。 5 return line 6 7 8# GUIから再利用するために、「ジェネレーター」として実装 9def read_file(filepath): 10 with open(filepath, encoding="utf-8") as stream: 11 for line in stream: 12 yield output(line) 13 14# to_json.py を直接呼び出した場合は、ファイル内容をprintで出力 15def main(filepath): 16 for line in read_file(filepath): 17 print(line) 18 19if __name__ == "__main__": 20 import sys 21 main(sys.argv[1]) 22

python

1# main.py 2 3import tkinter as tk 4from tkinter import ttk 5from tkinter.scrolledtext import ScrolledText 6from functools import partial 7import to_json 8 9 10def calc(button, text, freq=20): 11 # 処理中はボタンを押せないようにする 12 button.state(["disabled"]) 13 14 stream = to_json.read_file("test.txt") # ※ "test.txt" ファイルを用意する 15 16 for lineno, line in enumerate(stream, start=1): 17 text.insert(tk.END, f"{lineno:04} ", "lineno") 18 text.insert(tk.END, f"{line}\n") 19 20 if lineno % freq == 0: 21 text.see(tk.END) 22 text.update() 23 24 text.see(tk.END) 25 26 button.state(["!disabled"]) 27 28 29def main(): 30 root = tk.Tk() 31 text = ScrolledText(root, width=80, height=20) 32 text.tag_config("lineno", foreground="#AAAAAA") 33 text.pack(fill=tk.BOTH, expand=tk.YES) 34 button = ttk.Button(root, text="Output") 35 button.config(command=partial(calc, button, text)) 36 button.pack() 37 root.mainloop() 38 39if __name__ == '__main__': 40 main()

ちなみに、今回はファイルを経由してデータを渡していますが、
コマンドラインに出力される文字を直接 GUI に渡すには、
標準出力をリダイレクトする手法があります。

投稿2022/10/27 09:09

編集2022/10/28 03:17
teamikl

総合スコア8664

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

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

Kazuhiro-ch

2022/11/03 22:41

無事、反映される形になりました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問