ryotankの備考録日記

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

SVGからPNG変換GUIその2


作り込む為に画面レイアウトを見やすくした

svgpng変換GUIイメージ図-ver1.0の変換前_画面レイアウト用

これに沿ってツールを作成していく



出来たのがこれ

svgpngツールver1.0キャプチャ

あとフレーム要素は画面の中央に寄せたい

#画面レイアウトに従いレイアウトを作り込む
#2022-7-19作成

#ver2.0ではFrameの位置を中央に寄せる

from contextlib import closing
import PySimpleGUI as sg

sg.theme('LightGreen3')


frame1_layout =[
    [sg.Text('回路図.svg')]
]

frame2_layout =[
    [sg.Text('pngになった回路図.png')]
]


layout = [
    [sg.T()],
    [sg.Text('変換したいSVGファイルを選択して下さい')],

    [sg.Button('ファイルを選択', font=16, key="-FILE-CHO-")],
    [sg.Frame(title='変換したいsvgのサムネ', layout=frame1_layout)],
    [sg.Text('変換処理のステータス表示', font=18)],
    [sg.ProgressBar(key="-PROCESSING-", size=(30, 30), max_value=100)],
    [sg.Text('実行後にファイルがpngに変換されます', font=20)],
    [sg.Frame(title='pngファイル',layout=frame2_layout)],
    [sg.T('')],
    [sg.Button('別名で保存', key="-BET-", button_color='red')],
    [sg.T('')]
]


def gen_bytes_count(filepath):
    
    import os

    # Total Bytes

    filesize = os.stat(filepath).st_size

    count = 0



    # NOTE: バイト数カウントのためバイナリで開いてます

    # テキストで開いた場合、文字数 != バイト数(ファイルサイズ) と一致しません

    with open(filepath, "rb") as infile:

        for line in infile:

            count += len(line)

            yield (int(100*count/filesize), count)



task = None

options = {}

timeout_options = {"timeout":100, "timeout_key":"-timeout-"}



def task_cancel():

    global task

    task = None

    options.clear()



def task_start(filepath):

    global task

    task = gen_bytes_count(filepath)

    options.update(timeout_options)




with closing(sg.Window('svgをpngに変換ツールver1.0', layout)) as window:

    while True:
    
        event, values = window.read(**options)

        # print(event)

        if not event:

            break

        elif event == "-STOP-":

            task_cancel()

        elif event == "-START-":

            task_start(values["-INPUT-FILE-"])

        elif event == "-timeout-":

            if not task: # 処理するファイルが無い時

                continue

            info = next(task, None)

            if not info: # ファイル処理が終わった時

                task_cancel()

                continue

            status, count = info

            window["-PROCESSING-"].update_bar(status)

            sg.Print(status, count)

            ret = sg.OneLineProgressMeter(

                'Byte カウンター', status, 100, "", '{}'.format(count))

            if not ret: # 進捗ダイアログの Cancel が押された時

                task_cancel()

                continue


まずは、フレーム要素を中央に配置したver2.0を作っていく

SVGからPNG変換GUIその1

経緯としては、自前のWEBアプリで
基板設計記録をしていく上で
回路図やパターン図、3D完成イメージをpngで投稿出来る
ものを鋭意作成中であるが、

KICADという基板設計CADだと画像出力がPDF、SVG、DXF形式でしか
出力されないという問題があったので、

SVGで画像を出力して、そのSVGPNGに変換するツールを作る事にした


PythonGUIを作成していきたい

まずは、変換前のイメージ図

svgをpdf、png変換GUIイメージ図-ver1.0の変換前

次に変換中のイメージ図

svgをpdf、png変換GUIイメージ図-ver1.0の変換中


最後に変換終了後のイメージ図

svgをpdf、png変換GUIイメージ図-ver1.0の変換実行終了画面

これらに沿ってGUIを作成する

外見を作り込んだ後にそれぞれの機能を作り込んでいく

基板設計記録WEBアプリその35

views.pyの続き
削除画面を作成する

削除画面はDeleteViewを使って作成する

ポイントはtemplate_nameフィールドに対応するテンプレートを
設定し、削除するデータに対応するモデルを
modelフィールドに与える事

削除確定ボタンを押した後は、一覧画面(PDR_list)に
遷移する(移動する)ように設定する。

削除した後のリダイレクト先(新しいURLに転送する仕組み)を
リスト画面(一覧画面)へ遷移する為、
success_ful = "リスト画面へ遷移するような関数"となり

クラスベースビューのクラス変数として書くので
reverse_lazyを使う為
コードはこのような形になる
またテンプレートファイルを"PDR_data_delete.html"にする

#削除画面
class PDRDelete(DeleteView):
	#pdr_dataテーブルと連携
	model= models.pdr_data
	#テンプレートファイル連携
 	template_name = "PDR_data_delete.html"
	#削除した後のリダイレクト先
	success_full = reverse_lazy("app:list")

ちなみにDjangoでは、"モデルを実装する事"で自動でテーブルを作成する

なので、変更があった場合には
models.pyにコードを記述する

次回は、詳細画面を作る

基板設計記録WEBアプリその34

views.pyのフォーム2から3までを作成する

まずフォーム2から
部品候補名の情報が詰まった「spec1(最大25まで連番)_data」テーブルを使いたい
基板を設計する時に使うであろう
部品候補名をまとめた「parts_data」テーブルを使いたい
フォーム2の入力項目は、
部品候補名1から5までの仕様、メーカー名、通販コード、
価格、購入先を入力する 

これらをコード化すると

#入力フォーム2画面
class PDRCreateView2(CreateView):

   #parts_dataとspec1_dataとspec2_data、spec3_data、spec4_data
 #spec5_dataテーブルと連携
    model = models.parts_data, 
    model = models.spec1_data, 
    model = models.spec2_data,
    model = models.spec3_data, 
    model = models.spec4_data, 
    model = models.spec5_data

   #入力項目を定義する
	#部品候補名1
       fields = ("candidate_part_name_1", "part_candidate_name_1_specification",
	"manufacturers_name_of_candidate_part_name_1", 
	"mail_order_code_of_candidate_part_name_1", 
	"price_of_candidate_part_name_1", "where_to_by_candidate_part_name_1", 

	#部品候補名2
	"candidate_part_name_2", "part_candidate_name_2_specification",
	"manufacturers_name_of_candidate_part_name_2", 
	"mail_order_code_of_candidate_part_name_2", 
	"price_of_candidate_part_name_2", "where_to_by_candidate_part_name_2",

	#部品候補名3
	"candidate_part_name_3", "part_candidate_name_3_specification",
	"manufacturers_name_of_candidate_part_name_3", 
	"mail_order_code_of_candidate_part_name_3", 
	"price_of_candidate_part_name_3", "where_to_by_candidate_part_name_3",

	#部品候補名4
	"candidate_part_name_4", "part_candidate_name_4_specification",
	"manufacturers_name_of_candidate_part_name_4", 
	"mail_order_code_of_candidate_part_name_4", 
	"price_of_candidate_part_name_4", "where_to_by_candidate_part_name_4",

	#部品候補名5
	"candidate_part_name_5", "part_candidate_name_5_specification",
	"manufacturers_name_of_candidate_part_name_5", 
	"mail_order_code_of_candidate_part_name_5", 
	"price_of_candidate_part_name_5", "where_to_by_candidate_part_name_5")

	#テンプレートファイル"PDR_data_form2.html"と連携する
	template_name = "PDR_data_form2.html"

という感じ

同じようにフォーム3にもチャレンジする

pdr_dataテーブルと連携する
フォーム3の入力項目は、基板修正点、回路図画像データ、
パターン図画像データ、3D完成イメージ画像データの4つにする

	#入力フォーム3画面
class PDRCreateView3(CreateView):

	#pdr_dataテーブルと連携する
	model = models.pdr_data

	#入力項目を定義する
	fields = ("board_modification_points", "schematic_thumb", 
			"pattern_thumb", "graphic_thumb")
	
	#テンプレートファイル"PDR_data_form3.html"と連携する
	template_name = "PDR_data_form3.html"

部品候補名を入力する所はシンドイな・・・

次回は、削除画面と詳細画面を作る

基板設計記録WEBアプリその33

views.pyで入力フォーム1から3までを作成する前に

色々変更点がある

それは、入力フォーム画面のイメージ図を改良した事

なぜなら基板を設計している段階で、
最低でも5種類の部品で構成しているものが多い
最大25種類分の部品情報がある場合も考えられる

大学でのサークル活動時に使用していた基板が
そうだったから

なので、改良したイメージ図を載せる

基板設計記録WEBアプリ画面イメージ図-入力1画面
基板設計記録WEBアプリ画面イメージ図-入力画面2の追加ボタンを押した後
基板設計記録WEBアプリ画面イメージ図-入力画面3

またそれに伴い
入力フォーム1から3までのviews.pyの内容も変わってくる

例として入力フォーム1を出す
・クラスベースビューを使い、新規登録フォーム1を作る
・pdr_dataテーブルを使う
・フォーム1の入力項目は、
"設計作成日", "基板名", "基板英名", "基板概要", "縦の外形", "横の外形",
"電源供給方法"の計7つを入れる
・"PDR_data_form.html"と連携する

以上を踏まえてコード化すると

 #入力フォーム1画面
class PDRCreateView(CreateView):
 #pdr_dataテーブルと連携する
 model = models.pdr_data

 #入力項目を"設計作成日", "基板名", "基板英名", "基板概要", "縦の外形", "横の外形",
#"電源供給方法"に設定する
 fields = ("design_day", "board_name", "substrate_english_name", 
		"board_overview", "verical_outline", "horizonal_outline",
		"power_supply_method")

 #テンプレートファイルと連携する
 template_name = "PDR_data_form.html"

という風に書けた

次回は、入力フォーム2と3を作り
余裕があれば削除画面と詳細画面を作る予定

基板設計記録WEBアプリその32

今の問題点として

views.pyに書かれている内容と自分で設定したhtmlの名前が
一致していないのが判明したので、これを修正していく

あと"リダイレクト"や"redirect"とかの用語を理解してないので、
これも併せて学んでいく

まず一覧画面から作り込んでいく
PDR_dataテーブルと連携させる
テンプレートファイルの"PDR_data_list.html"と連携する
またレコード情報をテンプレートに渡すオブジェクト名を
"PDR_data_list"とする
以上の3つを踏まえたコードが以下のようになる

#修正版のviews.py

 #一覧画面
 class PDRList(ListView):
	#PDR_dataテーブルと連携
	model = models.PDR_data
	#レコード情報をテンプレートに渡すオブジェクト
	context_ojbect_name ="PDR_data_list"
	#テンプレートファイル連携
	template_name = "PDR_data_list.html"

このように組んでいく

次回は、入力フォーム1から3までを作成する

基板設計記録WEBアプリその31

ちゃんとバリデーションを出来ているか確認する前に

webページ表示設定を行うviews.pyの変更をする

views.pyの役割は、
ユーザーからhttpリクエストを受けてから
それに応じたHTML形式のレスポンスを返す事


改めてPDRに関する画面をまとめると

  • PDR_data_list.htmlが、PDR一覧画面のデザインで、ListViewと連携する
  • PDR_data_detail.htmlが、PDR詳細画面のデザインで、DetailViewと連携する
  • PDR_data_update.htmlが、PDR更新画面のデザインで、UpdateViewと連携する
  • PDR_data_delete.htmlが、PDR削除画面のデザインで、DeleteViewと連携する
  • PDR_data_form.htmlが、PDR登録画面のデザインで、CreateViewと連携する
  • PDR_data_form2.htmlが、PDR登録画面のデザインで、CreateViewと連携する
  • PDR_data_form3.htmlが、PDR登録画面のデザインで、CreateViewと連携する
  • PDR_data_done.htmlが、PDR登録完了のデザイン連携しない
  • PDR_data_contest_check.htmlが、PDR登録内容確認のデザイン 連携しない

になっているが、

7-13日時点のviews.pyの中身(一部抜粋して載せる)

#一覧画面
class Pdr_dataList(ListView):
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #レコード情報をテンプレートに渡すオブジェクト
    context_object_name = "Pdr_data_list"
    #テンプレートファイル連携
    template_name = "PDR_data_form_list.html"

#詳細画面
class Pdr_dataDetail(DetailView):
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #レコード情報をテンプレートに渡すオブジェクト
    context_object_name = "Pdr_data_detail"
    #テンプレートファイル連携
    template_name = "PDR_data_detail.html"

#Create画面
class Pdr_dataCreateView(CreateView):
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #入力項目定義
    fields = ("board_name","industory","location")
    #テンプレートファイル連携
    template_name = "PDR_data_form.html"
    #更新後のリダイレクト先
    def get_success_url(self):
        return reverse('pdr_app:detail', kwargs={'pk': self.object.pk})

#Create画面2
class Pdr_dataCreateView2(CreateView):
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #入力項目定義
    fields = ("name","age","company")
    #テンプレートファイル連携
    template_name = "PDR_data2_form.html"
    #作成後のリダイレクト先
    success_url = reverse_lazy("pdr_app:list")

#Create画面3
class Pdr_dataCreateView3(CreateView):
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #入力項目定義
    fields = ("name","age","company")
    #テンプレートファイル連携
    template_name = "PDR_data3_form.html"
    #作成後のリダイレクト先
    success_url = reverse_lazy("pdr_app:list")

#Update画面
class Pdr_dataUpdateView(UpdateView):
    #入力項目定義
    fields = ("board_name","industory","location")
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #テンプレートファイル連携
    template_name = "PDR_data_form.html"
    #更新後のリダイレクト先
    def get_success_url(self):
        return reverse('pdr_app:detail', kwargs={'pk': self.object.pk})

#更新画面
class Pdr_dataUpdateView(UpdateView):
    #入力項目定義
    fields = ("boara_name","age")
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #テンプレートファイル連携
    template_name = "PDR_data_form.html"
    #更新後のリダイレクト先
    success_url = reverse_lazy("pdr_app:list")

#削除画面
class Pdr_dataDeleteView(DeleteView):
    #Pdr_dataテーブル連携
    model = models.Pdr_data
    #テンプレートファイル連携
    template_name = "PDR_data_delete.html"
    #削除後のリダイレクト先
    success_url = reverse_lazy("pdr_app:list")

#create_done関数
#データ登録が完了した際に呼び出される関数で、最終的に
#データ登録完了画面(PDR_data_done.html)が呼び出される
def create_done(request, **kwargs):
    contents = {}
    for key, val in kwargs.items():
        contents[key] = val

    return render(request, 'PDR_data_done.html',{
        'contents': contents,
    })

def image_index(request):
    params = {
        'title':'画像のアップロード',
        'upload_form':UploadForm(),
        'id': None,
    }

    if (request.method == 'POST'):
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            upload_image = form.save()

            params["id"] = upload_image.id

    return render(request, 'pdr_app/PDR_data_form3.html', params)

紙のノートにまとめている時に気づいた・・・

目標とviewの中身がチグハグでHTML名もバラバラになっている

次回は、ちゃんと合うように
views.pyを修正する所から始める