GUIのイメージ図と開発途中の画面を掲載する
イメージ図はこのようにちょっと複雑な感じ

現段階ではここまで再現できた

難しいのは素材の画像を表示させる所
リストボックスで素材名を選択して
それに紐づく形で画像を特定フォルダから持ってきて・・・
の部分が難しい
取りあえず画像の表示で出来ない事には何も進まない
「記入」ボタンを押して文字を描画出来るようにするには
Buttonにkeyイベントをつけて
イベントを発生するように設定する必要がある
そこで以下のように設定をした
一部を抜粋してコードを載せる
if main_event == '-BOARDinput-form-': #基板名入力フォームボタンが押されたら #サブ画面を開く時に毎回layoutを宣言する #エラーが発生せず、何度でも展開できる sg.theme('LightGray3') #テーマの設定 sub_layout = [ [sg.Text('基板名 入力欄', font=14), sg.T(' ' *10), sg.Input('')], [sg.T('')], [sg.Text('リスト作成日 入力欄', font=14), sg.Input('')], [sg.T('')], [sg.T(' '*20), sg.Button('記入', font=16, key='-Data_ENTER-')] ] sub_window = sg.Window('基板名入力フォーム (1/2)', layout= sub_layout)
見ての通り「記入」ボタンに-Data_ENTER-というkeyイベントを設定した
そして前回のその29の記事では
elif sub2_event == '-Data_ENTER-': #「記入」ボタンが押されたら #フォームで入力した項目がPDFのヘッダーとフッター上に記載される pdf_Draw_characters()
としてイベントが発生した場合の処理をつけ
ボタンが押された場合にPDF上のヘッダーとフッターに入力項目を書き込むという
処理が実行される
次回は、テストコードで上記のコードが動作するかを確認する
前回は、pickleを使ってオブジェクトを保存したり、
読み込んだりでpickleの使い方について学んだ
その3では、回路草案入力フォームの入力項目を
オブジェクトに保存したい
もにょもにょしながらコードを書いたが
インデントが正しくないとエラーが発生する
解決方法としては、インデックスを揃えればいいのだが
どこを試してもインデントが正しくない!と警告されるので
一度メインウインドウからウィンドウ2を開く
ウィンドウ2からウィンドウ3を開く
この一連の動作をフローチャートに書きだしてみて
インデント位置を揃えられるようにする
またif~elifの使い方も再度勉強し直す
次回は、一連の動作をフローチャート化し、問題に対処したい
「記入」ボタンを押して文字を描画出来るようにするには
自作関数を作るのが簡単
def 関数名(引数1、引数2): #ここに関数の処理を記述 rerutn 戻り値
という形で書ける
文字を描画するので、特定ライブラリをインポートする事を忘れずに
def pdf_Draw_characters(): #PDF上に文字を描画する関数 pass file_name = 'guiから基板名入力フォームを開くその3.pdf' #ファイル名を設定 pdf = canvas.Canvas(file_name, pagesize=poatrait(A4)) #pdfを生成、A4サイズ縦に設定 pdf.saveSate() #セーブ #pdfのファイル情報を作成する pdf.setTitle('guiから基板名入力フォームを開くその3結果') #タイトル情報 #フォントやサイズを設定 pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5')) pdf.setFont('HeiseiKakuGo-W5', 14) #文字を描画(左からの位置、下からの位置、入れたい文字列) #ヘッダー部分の文字を描画する pdf.drawString(2.2*cm, 26*cm, '基板名:____________ リスト作成年月日: 年 月 日') #ヘッダー部分文字 #フッター部分の文字を描画する pdf.drawString(2*cm, 5.5*cm, '分類名:___________基板 担当者確認年月日: 年 月 日') #フッター部分文字 pdf.drawString(2*cm, 4.5*cm, 'ガーバーデータを外注時には作成日より日を空けて確認する事!!!') #フッター部分文字 #保存 pdf.restoreState() pdf.save()
「記入」ボタンを押したイベントを作る
elif sub2_event == '-Data_ENTER-': #「記入」ボタンが押されたら #フォームで入力した項目がPDFのヘッダーとフッター上に記載される pdf_Draw_characters()
これで「記入」ボタンを押して文字が描画されれば次の段階へ進める
ヘッダーとフッター混合描画テストを試す
テスト1ではヘッダーとフッターに長方形を描画し、
テスト2ではヘッダーとフッターに文字を描画する
#混合描画テスト2 from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4, portrait from reportlab.lib.units import cm #特定のフォントを指定する為に from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.cidfonts import UnicodeCIDFont file_name = '基板作りチェックヘッダーフッター混合描画テスト2.pdf' #ファイル名を設定 pdf = canvas.Canvas(file_name, pagesize=portrait(A4)) #pdfを生成、A4サイズ縦に設定 pdf.saveState() #セーブ #PDFのファイル情報を作成する pdf.setAuthor('python_checktest') #作成者情報 pdf.setTitle('ヘッダーフッター混合描画テスト2') #タイトル情報 pdf.setSubject('Footer_and_Header_TEST2') #件名情報 ### フォント、サイズを設定 ### pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5')) pdf.setFont('HeiseiKakuGo-W5', 14) ### 文字を描画 (左からの位置、下からの位置、入れたい文字列) pdf.drawString(2.2*cm, 26*cm, '基板名:____________ リスト作成年月日: 年 月 日') #ヘッダー部分文字 pdf.drawString(2*cm, 5.5*cm, '分類名:___________基板 担当者確認年月日: 年 月 日') #フッター部分文字 pdf.drawString(2*cm, 4.5*cm, 'ガーバーデータを外注時には作成日より日を空けて確認する事!!!') #フッター部分文字 #図形の描画 pdf.rect(2*cm, 25*cm, 17*cm, 2*cm) #ヘッダー部分の長方形を描画する pdf.rect(1*cm, 4*cm, 19*cm, 2*cm) #フッター部分の長方形を描画する #保存 pdf.restoreState() pdf.save()
混合描画テスト1はこんな感じに
混合描画テスト2はこのような感じになった
文字を描画出来たのでチェックリストの本体をPDF化に挑戦する
基板作りチェックguiから基板名入力フォームを開くその2
その2は、基板名入力フォーム(2/2)の基板分類分け選択欄が開くもの
その3は、フォーム2/2の「記入」ボタンを押すと
選択した分類分けや基板の名前、リスト作成年月日が
PDF上に記載される
その4では、「DBへ登録」ボタンを押すと専用DBに入力した項目が登録される
また、その4では、ER図(実体関連図とも呼ばれる)というデータベースの
設計も同時に行っていく
""" guiから基板名入力フォームを開くその2 基板名入力フォームボタンの「次へ」を押すと フォーム(2/2)が開き、基板分類分け選択欄が開く その3は記入ボタンを押すと入力フォームで選択した分類分けや 基板の名前やリスト作成年月日がPDFに記載される その4はDBへ登録ボタンを押すと専用DBへ記録される 作成日:2022-5-21 動作確認日:2022-5-21 AM4:00 """ import PySimpleGUI as sg sg.theme('LightBlue4') #基板分類分けフレーム L1 = [ [sg.Radio('モジュール基板', group_id='g1', font=('小塚ゴシック', 14))], [sg.Radio('試作基板', group_id='g1', font=('小塚ゴシック', 14))], [sg.Radio('ホビー用基板', group_id='g1', font=('小塚ゴシック', 14))], [sg.Radio('書き込みアダプター', group_id='g1', font=('小塚ゴシック', 14))], [sg.Radio('実験基板', group_id='g1', font=('小塚ゴシック', 14))] ] def Form2_window(): #基板名入力フォーム(2/2)ページ目 pass sub2_layout = [ [sg.Text('基板名入力フォーム(2/2)', font=('小塚ゴシック', 14))], [sg.T('')], [sg.Frame('基板分類分け 選択欄', L1, font=('小塚ゴシック', 20))], [sg.T('')], [sg.Button('記入', key='-ENTER-'), sg.T(' '*33), sg.Button('DBへ登録', key='-DB-')] ] sub2_window = sg.Window('入力フォーム(2/2)', sub2_layout) while True: sub2_event, sub2_values = sub2_window.read() if sub2_event is None: break sub2_window.close() # ------ Menu Definition ------ # menu_def = [ ['&ファイル', ['&開く Ctrl-O', '&保存 Ctrl-S', '&Properties', '&閉じる']], ['編集', ['&印刷プレビュー', '&印刷', ], ], ['&Toolbar', ['---', 'Command &1', 'Command &2', '---', 'Command &3', 'Command &4']], ['&ヘルプ', ['&オフライン対応ヘルプ', '&ReadMe','---', '&About...']],] #L6:実装済み基板の外観検査 L6 = [ [sg.Checkbox('半田がついてなかったりボール状の半田になっていないか', font='メイリオ 14', default=False, enable_events=True,)], [sg.Checkbox('半田は富士山の形状をしているか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('DIPの挿入ミスで端子が曲がっていないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('ICが逆に実装されていないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('カットされたリード部品の足クズが転がっていないか', font='メイリオ 15', default=False)], [sg.Checkbox('立っているチップ部品は無いか', font='メイリオ 15', default=False, visible=True)], [sg.Checkbox('コネクタの樹脂が溶けていないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('すべての電源ICの入出力とGND間はショート(短絡)していないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('電源投入後、熱くなったり臭いを放ったりする部品は無いか', font='メイリオ 15', default=False, enable_events=True)] ] #L7:電源投入と基本動作判定 L7 = [ [sg.Checkbox('安定化電源に電流リミッタをかけてあるか', font='メイリオ 15', default=False, enable_events=True),], [sg.Checkbox('5Vや3Vの電源バスの電圧が狙い通りか', font='メイリオ 15',default=False, enable_events=True)], [sg.Checkbox('電源を何回抜き差ししても正常に動作するか', font='メイリオ 15',default=False, enable_events=True)], [sg.Checkbox('リプルはマイコンの電源電圧仕様やADコンバータの分解能より十分小さいか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('Clockの振幅が10ms以下でVDDの80%以上に立ち上がっているか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('Clockの発振周波数の精度は1ppm以下であるか(時計機能を付けている場合のみ)', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('AD/DAコンバータの入力信号と変換データの関係は正しいか', font='メイリオ 15', default=False, enable_events=True,)] ] #チェックボックスを表示するエレメント checkbox_element = [sg.Checkbox("")] # ------ GUI Defintion ------ # L = [ [sg.Column([ [sg.T(''*10)], [sg.Menu(menu_def, tearoff=False, pad=(200, 1))], [sg.Frame('6.実装済み基板の外観検査', L6, font='メイリオ 20')], [sg.T(' '*60)], [sg.Frame('7.電源投入と基本動作', L7, font='メイリオ 18')], [sg.Output(size=(70, 12),font='小塚ゴシック 16')]], #Menuボタンの確認用でOutputを配置している scrollable=True, vertical_scroll_only=True)], [sg.T(' '*20), sg.Button('一時保存',key='-TempSAVE-', font='小塚ゴシック 16', bind_return_key= True, size=(10,2)), sg.T(' '*25), sg.Button('すべて解除', key='-CLEAR-', bind_return_key= True, font='小塚ゴシック 16', size=(10,2)), sg.T(' '*40), sg.Button('基板名\n入力フォーム',key='-BOARDinput-form-', font='小塚ゴシック 16',size=(10,2) , button_color='Green')], [sg.T(' '*10), sg.Button('PDF出力', key='OUTPUT', font='小塚ゴシック 16', size=(10,2), button_color='red')] ] window = sg.Window('基板作りチェックguiから基板名入力フォームを開くその2', L, ) #イベントループ while True: main_event, value= window.read() #イベントの読み取り(イベント待ち) if main_event in (sg.WIN_CLOSED, '閉じる'): break print(main_event, value) #Menuボタンの確認用で配置している if main_event == '印刷': #「印刷」が押されたら dn = sg.PopupYesNo('印刷前にプレビューは見ましたか?', title='プレビュー確認', font=18, text_color='#FF0', background_color='#777', button_color=('#F00', '#ccc')) #yesならそのまま印刷作業に移行 #Noなら強制的にプレビューに移行 #チェック項目が入っている箇所のみを取得する if main_event == '-TempSAVE-': #ボタンが押された時に ceg = checkbox_element.get() #選択された要素を取得する if main_event == '-BOARDinput-form-': #基板名入力フォームボタンが押されたら #サブ画面を開く時に毎回layoutを宣言する #エラーが発生せず、何度でも展開できる sg.theme('LightGreen5') #テーマの設定 sub_layout = [ [sg.Text('基板名 入力欄'), sg.T(' ' *10), sg.Input(key='-Board name-')], [sg.T('')], [sg.Text('リスト作成日 入力欄'), sg.Input(key='-List creation date-')], [sg.T('')], [sg.Button('クリア', key='-Clear-'), sg.T(' '*33), sg.Button('次へ', key='-NEXT-')] #4行目 ] sub_window = sg.Window('基板名入力フォーム (1/2)', layout= sub_layout) while True: sub_event, sub_value = sub_window.read() #フォームの入力待ち(イベント待ち) if sub_event is None: break elif sub_event == '-NEXT-': #次へが押されたら Form2_window() #フォーム2/2を開く elif sub_event == '-Clear-': #クリアボタンが押されたら sub_window['-Board name-'].update("") #基板名をカラにする sub_window['-List creation date-'].update("") #リスト作成年月日をカラにする sub_window.close() #入力フォームを閉じる #終了処理 window.close()
実際の動作は以下の通り
次回はその3 「記入」ボタンを押すと
選択した分類分けや基板の名前、リスト作成年月日が
PDF上に記載される動作に挑戦する
「基板名入力フォーム」ボタンを押すと
別のform画面が表示される
""" チェックリストGUIから基板名入力フォームを開くその1 「基板名入力フォーム」ボタンを押すと 別のform画面が表示される 動作確認日:2022-5-20 """ import PySimpleGUI as sg from PySimpleGUI.PySimpleGUI import button_color_to_tuple sg.theme('LightBlue4') def allClear_click(): #すべて解除クリック関数 pass#実現したい処理をこの下に書く global list_check #グローバル宣言 list_check = [] for i in range(len(list_check)): list_check[i].update(value=False) # ------ Menu Definition ------ # menu_def = [ ['&ファイル', ['&開く Ctrl-O', '&保存 Ctrl-S', '&Properties', '&閉じる']], ['編集', ['&印刷プレビュー', '&印刷', ], ], ['&Toolbar', ['---', 'Command &1', 'Command &2', '---', 'Command &3', 'Command &4']], ['&ヘルプ', ['&オフライン対応ヘルプ', '&ReadMe','---', '&About...']],] #L6:実装済み基板の外観検査 L6 = [ [sg.Checkbox('半田がついてなかったりボール状の半田になっていないか', font='メイリオ 14', default=False, enable_events=True,)], [sg.Checkbox('半田は富士山の形状をしているか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('DIPの挿入ミスで端子が曲がっていないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('ICが逆に実装されていないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('カットされたリード部品の足クズが転がっていないか', font='メイリオ 15', default=False)], [sg.Checkbox('立っているチップ部品は無いか', font='メイリオ 15', default=False, visible=True)], [sg.Checkbox('コネクタの樹脂が溶けていないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('すべての電源ICの入出力とGND間はショート(短絡)していないか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('電源投入後、熱くなったり臭いを放ったりする部品は無いか', font='メイリオ 15', default=False, enable_events=True)] ] #L7:電源投入と基本動作判定 L7 = [ [sg.Checkbox('安定化電源に電流リミッタをかけてあるか', font='メイリオ 15', default=False, enable_events=True),], [sg.Checkbox('5Vや3Vの電源バスの電圧が狙い通りか', font='メイリオ 15',default=False, enable_events=True)], [sg.Checkbox('電源を何回抜き差ししても正常に動作するか', font='メイリオ 15',default=False, enable_events=True)], [sg.Checkbox('リプルはマイコンの電源電圧仕様やADコンバータの分解能より十分小さいか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('Clockの振幅が10ms以下でVDDの80%以上に立ち上がっているか', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('Clockの発振周波数の精度は1ppm以下であるか(時計機能を付けている場合のみ)', font='メイリオ 15', default=False, enable_events=True)], [sg.Checkbox('AD/DAコンバータの入力信号と変換データの関係は正しいか', font='メイリオ 15', default=False, enable_events=True,)] ] #チェックボックスを表示するエレメント checkbox_element = [sg.Checkbox("")] # ------ GUI Defintion ------ # L = [ [sg.Column([ [sg.T(''*10)], [sg.Menu(menu_def, tearoff=False, pad=(200, 1))], [sg.Frame('6.実装済み基板の外観検査', L6, font='メイリオ 20')], [sg.T(' '*60)], [sg.Frame('7.電源投入と基本動作', L7, font='メイリオ 18')], [sg.Output(size=(70, 12),font='小塚ゴシック 16')]], #Menuボタンの確認用でOutputを配置している scrollable=True, vertical_scroll_only=True)], [sg.T(' '*20), sg.Button('一時保存',key='-TempSAVE-', font='小塚ゴシック 16', bind_return_key= True, size=(10,2)), sg.T(' '*25), sg.Button('すべて解除', key='-CLEAR-', bind_return_key= True, font='小塚ゴシック 16', size=(10,2)), sg.T(' '*40), sg.Button('基板名\n入力フォーム',key='-BOARDinput-form-', font='小塚ゴシック 16',size=(10,2) , button_color='Green')], [sg.T(' '*10), sg.Button('PDF出力', key='OUTPUT', font='小塚ゴシック 16', size=(10,2), button_color='red')] ] window = sg.Window('基板作りチェック確認リストレイアウト変更', L, ) """ チェックON・OFF変数 #bin = BooleanVar() #bin.set(True) #チェックがされているか否か #if bin.get(): #チェック状態を取得するにはgetを使う # print('チェックされている') #else: # print('チェックされていない') """ #エレメントを操作する為(チェックリストを参照したい) #Checkbox_element = window['-PCB_making_check_List-'] #イベントループ while True: main_event, value= window.read() #イベントの読み取り(イベント待ち) if main_event in (sg.WIN_CLOSED, '閉じる'): break print(main_event, value) #Menuボタンの確認用で配置している if main_event == '印刷': #「印刷」が押されたら dn = sg.PopupYesNo('印刷前にプレビューは見ましたか?', title='プレビュー確認', font=18, text_color='#FF0', background_color='#777', button_color=('#F00', '#ccc')) #yesならそのまま印刷作業に移行 #Noなら強制的にプレビューに移行 #チェック項目が入っている箇所のみを取得する if main_event == '-TempSAVE-': #ボタンが押された時に ceg = checkbox_element.get() #選択された要素を取得する if main_event == '-CLEAR-': allClear_click() if main_event == '-BOARDinput-form-': #基板名入力フォームボタンが押されたら #サブ画面を開く時に毎回layoutを宣言する #エラーが発生せず、何度でも展開できる sg.theme('LightGray3') #テーマの設定 sub_layout = [ [sg.Text('基板名 入力欄'), sg.T(' ' *10), sg.Input('')], [sg.T('')], [sg.Text('リスト作成日 入力欄'), sg.Input('')] ] sub_window = sg.Window('基板名入力フォーム (1/2)', layout= sub_layout) while True: sub_event, sub_value = sub_window.read() if sub_event is None: break sub_window.close() #入力フォームを閉じる #終了処理 window.close()
上記のコードを実行すると
以下のような動きになる
次回は、基板名入力フォームボタンの「次へ」を押すと
フォーム(2/2)の基板分類分け選択欄が開く その2を作成する