ryotankの備考録日記

趣味の電子工作についての備考録などなど

素材集めGUIその2

GUIのイメージ図と開発途中の画面を掲載する


イメージ図はこのようにちょっと複雑な感じ

アークナイツ素材集め表示GUI-ver3.0イメージ図

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

アークナイツ素材集めGUI_ver1.0素子結晶選択時キャプチャ


難しいのは素材の画像を表示させる所

リストボックスで素材名を選択して
それに紐づく形で画像を特定フォルダから持ってきて・・・

の部分が難しい

取りあえず画像の表示で出来ない事には何も進まない

基板作りチェックリストその30

「記入」ボタンを押して文字を描画出来るようにするには

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上のヘッダーとフッターに入力項目を書き込むという
処理が実行される

次回は、テストコードで上記のコードが動作するかを確認する

回路草案入力フォームその15

前回は、pickleを使ってオブジェクトを保存したり、
読み込んだりでpickleの使い方について学んだ

その3では、回路草案入力フォームの入力項目を
オブジェクトに保存したい

もにょもにょしながらコードを書いたが
インデントが正しくないとエラーが発生する

pickleを使いオブジェクトを保存する動作確認その3でエラーが発生

解決方法としては、インデックスを揃えればいいのだが

どこを試してもインデントが正しくない!と警告されるので

一度メインウインドウからウィンドウ2を開く
ウィンドウ2からウィンドウ3を開く
この一連の動作をフローチャートに書きだしてみて
インデント位置を揃えられるようにする

またif~elifの使い方も再度勉強し直す

次回は、一連の動作をフローチャート化し、問題に対処したい

基板作りチェックリストその29

「記入」ボタンを押して文字を描画出来るようにするには

自作関数を作るのが簡単

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()

これで「記入」ボタンを押して文字が描画されれば次の段階へ進める

基板作りチェックリストその28

ヘッダーとフッター混合描画テストを試す

テスト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はこんな感じに

ヘッダーとフッター混合テスト1

混合描画テスト2はこのような感じになった

ヘッダーフッター混合描画テスト2


文字を描画出来たのでチェックリストの本体をPDF化に挑戦する

基板作りチェックリストその27

基板作りチェック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()

実際の動作は以下の通り

基板作りチェックguiから基板名入力フォームを開くその2実際の動作


次回はその3 「記入」ボタンを押すと
選択した分類分けや基板の名前、リスト作成年月日が
PDF上に記載される動作に挑戦する

基板作りチェックリストその26

「基板名入力フォーム」ボタンを押すと
別の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()

上記のコードを実行すると
以下のような動きになる

基板作りチェックguiから基板名入力フォームを開くその1

次回は、基板名入力フォームボタンの「次へ」を押すと
フォーム(2/2)の基板分類分け選択欄が開く その2を作成する