Pythonの初学者ですが、初めてツールを作成しました。
PySide2でcsvファイルを読み込んで、JSON,YAMLファイルに変換するだけのツールです。
これを使った目的は学習でDockerCompose.Ymlファイルを作成するが、慣れていないので見えないバグにいつも悩まされる。
一括で変換してなるべく入力ミスをなくしたい。
PySide2を勉強していたので、その復習も兼ねて作りました。
・QfileDialogでcsvファイルを選択して、ListWidgetに内容を表示させる。
・ListWidgetの情報をJSONボタンをクリックした時に情報を取得してJSONファイルに変換して、ファイルを書き込む。
・ListWidgetの情報をYAMLボタンをクリックした時に情報を取得してYAMLファイルに変換して、ファイルを書き込む。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv
import json
import yaml
import codecs
import sys
from PySide2 import QtWidgets, QtCore
#init関数を定義
class Jymaker(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Json Yaml fileMaker")
self.build_ui()
#SignalとSlotを設定
self.connect_signal_slot()
def callback_line_edit_editingFinished(self):
file = self.line_edit.text()
if not file.endswith(".csv"):
return
url = QtCore.QUrl(file)
if url.isLocalFile():
file = url.toLocalFile()
if os.path.exists(file):
self.line_edit.setText(file)
json_list = self.load_csv(file)
self.listwgt.clear()
self.listwgt.addItems(json_list)
#Openボタンを押したときの挙動を設定
def callback_file_dialog_button_clicked(self):
file, filter_ = QtWidgets.QFileDialog.getOpenFileName(
self, "Open CSV", "C:/Users/User/Documents/Jymaker/csv", "CSV (*.csv)"
)
#csvファイルの中の情報を取り出す
#listWedgetに情報を入れていく
if file:
self.line_edit.setText(file)
json_list = self.load_csv(file)
self.listwgt.clear()
self.listwgt.addItems(json_list)
#returnで返された、変数を受け取り表示させる。
#JSONボタンを押したときにの処理
def callback_create_file_button_clicked(self):
jsdata = []
for row in range(self.listwgt.count()):
item = self.listwgt.item(row)
jsdata.append(item.text())
filename = "C:/Users/User/Documents/Jymaker/json/sample.json"
with open(filename, "w", encoding="utf_8") as f:
json.dump(jsdata, f ,indent=4)
#メッセージボックス
QtWidgets.QMessageBox.about(
self,
"json file was created.",
"json file was created."
)
#YAMLボタンを押したときにの処理
def callback_create_yaml_button_clicked(self):
yamldata = []
for row in range(self.listwgt.count()):
item = self.listwgt.item(row)
yamldata.append(item.text())
filename = "C:/Users/User/Documents/Jymaker/yml/sample.yml"
with codecs.open(filename, 'w', 'utf-8') as f:
yaml.dump(yamldata, f, encoding='utf-8', allow_unicode=True)
#メッセージボックス
QtWidgets.QMessageBox.about(
self,
"Yaml file was created.",
"Yaml file was created."
)
#パーツを作る関数の定義
def build_ui(self):
self.line_edit = QtWidgets.QLineEdit()
self.file_dialog_button = QtWidgets.QPushButton("Open")
self.line = QtWidgets.QFrame()
self.line.setFrameStyle(QtWidgets.QFrame.HLine | QtWidgets.QFrame.Sunken)
self.listwgt = QtWidgets.QListWidget()
self.create_file_button = QtWidgets.QPushButton("JSON")
self.create_yaml_button = QtWidgets.QPushButton("YAML")
#GUIを表示させるためのレイアウト設置
form_layout = QtWidgets.QFormLayout()
form_layout.addRow("CSV File", self.line_edit)
form_layout.addRow("", self.file_dialog_button )
form_layout.addRow(self.line)
form_layout.addRow("File", self.listwgt)
form_layout.addRow(self.create_file_button)
form_layout.addRow(self.create_yaml_button)
self.setLayout(form_layout)
#SignalとSlotを繋げる処理を行う関数
def connect_signal_slot(self):
self.line_edit.editingFinished.connect(self.callback_line_edit_editingFinished)
self.file_dialog_button.clicked.connect(self.callback_file_dialog_button_clicked)
self.create_file_button.clicked.connect(self.callback_create_file_button_clicked)
self.create_yaml_button.clicked.connect(self.callback_create_yaml_button_clicked)
#csvファイルの内容をを読み込む。
# 読み込んだ内容をQListWidgetItemに返して表示させる。
def load_csv(self, file):
json_list =[]
with open(file, "r", encoding="utf_8") as f:
reader = csv.reader(f)
for row in reader:
json_list.append(",".join(row))
return(json_list)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = Jymaker()
win.show()
sys.exit(app.exec_())
````
苦労したこと
1.listWedgetに情報を表示せせるのに苦労しました。
思うように情報が表示できない。
エラーが発生しないから、どこが間違っているのか分からない。
listWedgetが間違っているとの指摘もあり、 QTableWidget や QTableView への表示が適切との御意見を頂きましたが、
teratail.comに質問を投稿して、
引数に,を入れることを教えて頂き、無事、情報を表示せることができました。
````
json_list.append(",".join(row))
```
2.listWedgetからの情報を取得してJsonファイルに変換できない。
csvファイルから単にJsonファイルに変換するのなら、Qiitaに情報があります。
listWedgetの情報を取得してJSONファイルに変換できない。
ファイルが出力されない。
ググっても分からなくて心が折れそうになりました。
QListWidgetのitermを取り出して、文字情報を取り出すには、text()メソッドを使いました。
そこからJSONファイルを作成するコードを書いたのですが、上書きされてしまい最後の行しか内容がない。
これが問題の行
````
def callback_create_file_button_clicked(self):
for row in range(self.listwgt.count()):
item = self.listwgt.item(row)
jsonlist = item.text()
filename = "C:/Users/User/Documents/Jymaker/json/sample.json"
with open(filename, "w", encoding="utf_8") as f:
json.dump(jsonlist, f)
````
上のコードは、jsonlistという変数にitem.text()の内容が上書きされて保持される。
Udemyの先生に教えて頂き、これを以下のように修正
````
def callback_create_file_button_clicked(self):
jsdata = []
for row in range(self.listwgt.count()):
item = self.listwgt.item(row)
jsdata.append(item.text())
filename = "C:/Users/User/Documents/Jymaker/json/sample.json"
with open(filename, "w", encoding="utf_8") as f:
json.dump(jsdata, f ,indent=4)
````
変数を変更しましたが、jsdata変数を初期化して、list.appendで、リストに要素を追加するようにしました。
これによりcsvフィルの内容が全部、JSONファイルに変換され保存できました。
YAMLファイルも同様ですが、PyYAML というパッケージをインストールする必要があります。
書き込むとき(日本語が入っているとき)は.codecsをインポートする必要があります。
今後について
JSONファイルもYAMLファイルも文法的に問題ないか専用のチェッカーWebサービスで確認したら問題はありませんでした。
DockerCompose.ymlを生成し問題なく出力されたのですが、csvファイルのフォーマットに注意が必要。
これが正常に使えるか検証。
今度はJSONファイルやYAMLファイルをcsvファイルに変換する機能を実装したい。
コード上でファイル名を指定しているので、GUIでファイル名を指定できるようにしたい。
PyInstallerを使いexeファイルに変換する。
listWedgetからQTableWidgetに変更。
もう少し、分かりやすくしたいので修正予定。