はじめに
ボタンやラベルのサイズやフォントの設定をメインファイルに記述するとスクリプトが冗長になります。別ファイル(YAMLファイル)に記述できるようにしました。今回やること
以前に英単語暗記のためのアプリを作りました。こちらを新たに書き直しました。touch-sp.hatenablog.com
まずは「constructGUI.py」というファイルを作成する必要があります。
これは指定されたYAMLファイルを読み込んで各QWidgetに設定を追加するためのスクリプトです。
とりあえずQLabelとQPushButtonの基本的な設定を追加できるようにしています。
from PyQt6.QtCore import Qt, QSize from PyQt6.QtGui import QFont import yaml def construct(x, yaml_file, settings): with open(yaml_file, 'r') as f: yaml_data = yaml.load(f, Loader=yaml.SafeLoader) if settings in yaml_data.keys(): settings_dict = yaml_data[settings] if settings_dict['type'] == 'QLabel': ##サイズの設定 if ('height' in settings_dict.keys() and 'width' in settings_dict.keys()): h = settings_dict['height'] w = settings_dict['width'] x.setFixedSize(QSize(w, h)) ##サイズの設定 ##fontの設定 font = QFont() if 'fontFamily' in settings_dict.keys(): font.setFamily(settings_dict['fontFamily']) if 'fontPoint' in settings_dict.keys(): font.setPointSize(settings_dict['fontPoint']) if 'fontBold' in settings_dict.keys(): font.setBold(settings_dict['fontBold']) x.setFont(font) ##fontの設定 ##テキストの設定 if 'text' in settings_dict.keys(): x.setText(settings_dict['text']) ##テキストの設定 ##アライメントの設定 if 'alignment' in settings_dict.keys(): alignment_str = settings_dict['alignment'] if alignment_str == 'center': x.setAlignment(Qt.AlignmentFlag.AlignCenter) elif alignment_str == 'right': x.setAlignment(Qt.AlignmentFlag.AlignRight) elif alignment_str == 'right': x.setAlignment(Qt.AlignmentFlag.AlignLeft) ##アライメントの設定 elif settings_dict['type'] == 'QPushButton': ##サイズの設定 if ('height' in settings_dict.keys() and 'width' in settings_dict.keys()): h = settings_dict['height'] w = settings_dict['width'] x.setFixedSize(QSize(w, h)) ##サイズの設定 ##fontの設定 font = QFont() if 'fontFamily' in settings_dict.keys(): font.setFamily(settings_dict['fontFamily']) if 'fontPoint' in settings_dict.keys(): font.setPointSize(settings_dict['fontPoint']) if 'fontBold' in settings_dict.keys(): font.setBold(settings_dict['fontBold']) x.setFont(font) ##fontの設定 ##テキストの設定 if 'text' in settings_dict.keys(): x.setText(settings_dict['text']) ##テキストの設定 return x
実際のPythonスクリプトとYAMLファイル
YAMLファイル
「settings.yaml」という名前で保存して下さい。label_1: type: QLabel alignment: center fontFamily: times fontPoint: 40 fontBold: True
Pythonファイル
冒頭のコメントアウトされた部分は「constructGUI.py」をGitHubページからダウンロードするためのスクリプトになります。最新のものがダウンロードされます。
''' import os from urllib.request import urlretrieve url = 'https://raw.githubusercontent.com/dai-ichiro/pyqt6_yaml/main/constructGUI.py' fname = os.path.basename(url) if not os.path.isfile(fname): urlretrieve(url, fname) ''' from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QVBoxLayout from PyQt6.QtCore import Qt, QSize import pickle import random from constructGUI import construct with open('words_dict.pkl', 'rb') as f: words_dict = pickle.load(f) dict_keys = words_dict.keys() class Window(QWidget): def __init__(self): super().__init__() self.initUI() self.question = '' self.new_question = True def initUI(self): self.setWindowTitle("単語帳") self.setFixedSize(QSize(400, 200)) self.label_q = construct(QLabel(), 'settings.yaml', 'label_1') self.label_a = construct(QLabel(), 'settings.yaml', 'label_1') layout = QVBoxLayout() layout.addWidget(self.label_q) layout.addWidget(self.label_a) self.setLayout(layout) def keyPressEvent(self, e): if e.key() == Qt.Key.Key_Return: if self.new_question == True: self.label_a.clear() self.question = random.choice(list(dict_keys)) self.label_q.setText(self.question) self.new_question = False else: self.label_a.setText(', '.join(words_dict[self.question])) self.new_question = True if __name__ == "__main__": app = QApplication([]) ex =Window() ex.show() app.exec()
英単語アプリを使用する前に英単語データのダウンロードが必要です。
こちらのスクリプトでダウンロード可能です。
ダウンロードしてpickle保存してくれます。
import pandas as pd url = 'https://touch-sp.hatenablog.com/entry/2021/03/07/234555' dfs = pd.read_html(url, encoding='utf-8') df = dfs[0] df = df.drop_duplicates() words_list = list(df['英単語'].unique()) words_dict = {} for word in words_list: words_dict[word] = list(df[df['英単語']==word]['意味']) import pickle with open('words_dict.pkl', 'wb') as f: pickle.dump(words_dict, f)
動作画面
2022年4月19日追記(For Python 3.10)
Python 3.10を使ってスクリプトを書き換えました。touch-sp.hatenablog.com