LoginSignup
1
2

More than 1 year has passed since last update.

PySide2を使ったPyshonのツール作成

Last updated at Posted at 2021-06-20

Pythonの初学者ですが、初めてツールを作成しました。
PySide2でcsvファイルを読み込んで、JSON,YAMLファイルに変換するだけのツールです。

Json_yanlfikemaker.jpg

これを使った目的は学習で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に変更。

もう少し、分かりやすくしたいので修正予定。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2