みなさん、こんにちは。
先日、Xubuntu 22.04用に改修した宛名印刷ソフト「Riosanatea」ですが、快適な印刷環境が整ったことで意気揚々と年賀状や挨拶状の準備を進めていました。
プログラムの改修顛末記事はこちら↓
しかし、いざ会社関係の方へ送ろうとしたその時、重大な事実に気づいてしまったのです。
「あれ……会社名と部署名を入れる欄がない……?」
そうなんです。個人宛の印刷には完璧に対応していたのですが、ビジネス用途で必須となる「会社名」や「部署名」のフィールドが存在しなかったのです。ビジネス用途ではあるはずのものがない、個人開発のフリーソフトでは「あるある」ですよね。
「なければ自分で足せばいいじゃない」の精神で、今回はこの機能の追加に取り組んでみました。
今回のミッション
今回追加・修正する機能は以下の通りです。
- 会社名・部署名フィールドの実装(住所と宛名の間にいい感じで配置したい)
- レイアウト調整用UIの追加(位置や文字間隔をGUIでいじれるようにする)
- 用紙サイズ変更時の自動調整(ハガキから封筒に変えてもレイアウトが崩れないように)
- 【おまけ】連名(二人目)の配置選択(上寄せか下寄せか選べるように)
技術的な実装 – 中身はどうなっている?
ここからは、実際にPythonコードをどういじったのか、技術的な詳細をご紹介します。
1. データ構造の拡張 – 座標を定義する
まず、印刷レイアウトを管理している parts_dict という辞書に、会社名と部署名の定義を追加しました。
はがき上のどこに配置するか(X, Y座標)や、どのくらいの範囲に収めるか(Area Size)を数値で指定します。
# Riosanatea.py (90行目付近)
parts_dict = {
# ... 既存の項目 ...
"company-position": [ 70, 24 ], # 会社名の位置 [x, y]
"company-areasize": [ 38, 10 ], # 会社名の収納範囲 [width, height]
"company-bind-space": 2, # 文字間隔
"department-position": [ 82, 24 ], # 部署名の位置
"department-areasize": [ 38, 10 ], # 部署名の収納範囲
"department-bind-space": 2, # 文字間隔
}
同様に、初期化用の standard_parts_dict にも同じ値を追加しておきます。これで「標準に戻す」機能も安心です。
2. CSV読み込みの拡張
CSVファイルからデータを読み込む際、どの列を会社名・部署名として扱うかを指定します。今回は7列目と8列目(0始まり)を使用することにしました。
# Riosanatea.py (135行目付近)
column_etc_dictionary = {
# ... 既存の項目 ...
"company": 7, # 会社名は8列目
"department": 8, # 部署名は9列目
}
これで、以下のようなCSVデータが扱えるようになります。 郵便番号,住所1,住所2,氏名1,氏名2,敬称,会社名,部署名
3. 描画ロジック – Pillowで貼り付け
ここが印刷の心臓部です。parts_setting 関数の中で、文字列を画像化して貼り付ける処理を追加します。
# 会社名の処理(部署名も同様)
company_name = row_list[column_etc_dictionary["company"]]
if company_name: # 空でなければ描画
company_image = self.making_name_image(
company_name,
parts_dict["company-areasize"],
parts_dict["company-bind-space"],
1 # 1列で表示
)
self.pillow_image.paste(
company_image,
parts_dict["company-position"],
company_image
)
4. GUIの拡張 – SpinCtrlの大量追加
設定ファイルを手書きで修正するのは大変なので、GUI(印刷レイアウトタブ)にも調整用のコントロールを追加しました。 wx.SpinCtrl を使い、位置(X, Y)とサイズ(W, H)を調整できるようにします。
# 会社名の位置調整用スピンコントロール
company_position_x_spinbutton = wx.SpinCtrl(panel, value=str(parts_dict["company-position"][0]), min=0, max=999)
# ... (これが部署名含めてXYWHと続くので計12個追加!)
イベントハンドラもしっかり実装し、数値を変えたらリアルタイムでプレビューが再描画されるようにしました。これで微調整もラクラクです。
ハマりポイントとデバッグの苦労
順調に進んでいるように見えましたが、やはりトラブルは起きました。
1. 恐怖の「インデント混在」
実装中、なぜか動かない……と思ったら、既存コードと自分のコードで「タブ」と「スペース」が混在していました。Python使いにとっての悪夢ですね。 見た目では揃っているのにエラーになる。最終的には expand コマンドで強制的にスペースに統一して解決しました。
# タブをスペース4つに置換して浄化
expand -t 4 Riosanatea.py > temp.py && mv temp.py Riosanatea.py
2. ロジックの迷宮(if/elseの罠)
用紙サイズを変更した際の「自動調整ロジック」でバグが発生しました。 ユーザーが「自動調整しますか?」に「はい」と答えたとき、ハガキ以外なら計算して配置を直す……はずが、動かない。
修正前(バグあり)
if auto_relocation_question_dialog.ShowModal() == wx.ID_YES:
if paper_size_category == "はがき" ...:
# はがき用の処理
else: # ← ここ!!このelseが外側のifではなく内側のifに対応していた
# 自動調整処理(ここが実行されない)
修正後
if auto_relocation_question_dialog.ShowModal() == wx.ID_YES:
if paper_size_category == "はがき" ...:
# はがき用の処理
else: # ← インデントを修正して、正しい「if YESの中のelse」に
# 自動調整処理(これで動く!)
インデント一つで挙動が変わる、Pythonの怖さと面白さを再確認しました。
おまけ機能 – 連名の配置
ついでに、「宛名の二人目」の配置も改良しました。これまでは下寄せ固定でしたが、「上寄せ」も選べるようにしました。これは、宛名1に役職名、宛名2に担当者名を指定して印刷するような場合に、上揃えの方が見栄えが良いためです。
# GUIのComboBoxで "top" か "bottom" を選択可能に
if parts_dict["twoname-alignment-mode"] == "top":
second_name_y = first_name_y
else:
second_name_y = first_name_y + areasize_height - second_name_height
まとめ
こうして、私のRiosanateaは「ビジネス対応版」へと進化しました。
- 会社名・部署名バッチリ印刷可能
- CSVの8列目・9列目に対応
- 用紙サイズを変えても自動で追従
- GUIで微調整も可能
これで今年の年賀状、そして今後のビジネス挨拶状もLinuxだけで完結できそうです。コードは前回同様 GitHubリポジトリに反映していますので、会社宛に送る必要がある方はぜひ試してみてください。
今回もコードの実装には GitHub Copilot Agent に手伝ってもらいました。欲しい機能を伝えて、サクッと実装できる。本当に良い時代になったものです。
本日も最後までお読みいただきありがとうございました。
それでは、よいLinuxライフを!
関連リンク




ピンバック: 【Linuxで年賀状】宛名印刷ソフト「Riosanatea」を改造して、最強の印刷環境を作ってみた話 - ビューローみかみ