質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3723閲覧

Python(TkInter)  GUIアプリの開発を終えて 自分の端末以外で 実行したら 同じ画面イメージで表示されなかった

saya24

総合スコア221

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/02 15:16

編集2020/07/03 06:10

標題の件、大変初歩的なことと思いますが 教えてください。

解像度が異なる端末であっても
自分が 従来まで開発してきた端末と同じように各フォームを表示させたいのですが、悉く無駄な余白が現れ
同じように表示されていませんでした。

自分の開発端末で表示されてたイメージ同様、縦横の縮尺率だけが違うだけの 表示を達成するには どういった設定を行う・気を付ければよいでしょうか

ご見解を頂けたら幸いです、よろしくお願いします。

20200703 14:45 現況コードと画像追加

Python

1from tkinter import * 2import tkinter.ttk as ttk 3import tkinter.scrolledtext as tksc 4import math 5 6 7 8class Apprication(ttk.Frame): 9 10 def __init__(self, app): 11 12 13 super().__init__(app) 14 self.pack(fill = BOTH, expand=True) 15 16 btn1 = ttk.Button(self, text="Script", command=self.openDialog1) 17 btn1.bind('<Return>', self.openDialog1) 18 btn1.pack(fill = BOTH, expand=True) 19 btn1.focus_set() 20 21 btn2 = ttk.Button(self, text="Mail") 22 btn2.pack(fill = BOTH, expand=True) 23 24 btn3 = ttk.Button(self, text="Job") 25 btn3.pack(fill = BOTH, expand=True) 26 27 btn4 = ttk.Button(self, text="Quit", command=app.quit) 28 btn4.bind('<Return>', lambda _: app.quit()) 29 btn4.pack(fill = BOTH, expand=True) 30 31 self.menu() 32 33 34 35 def menu(self): 36 menu_top = Menu(app) 37 menu_file = Menu(menu_top, tearoff=False) 38 menu_open = Menu(menu_top, tearoff=False) 39 40 menu_help = Menu(menu_top, tearoff=False) #★ 41 42 43 app.configure(menu=menu_top, bg="#F0FFFF") 44 45 menu_top.add_cascade (label='File(F)', menu=menu_file, underline=0) 46 #★menu_top.add_command(label='Help(H)', underline=0) 47 menu_top.add_cascade(label='Help(H)', menu=menu_help, underline=0) #★ 48 49 menu_file.add_cascade(label='Open(O)', underline=0, menu=menu_open) 50 menu_open.add_command(label='Script(S)', underline=0, command=self.openDialog1) 51 menu_open.add_command(label='Job(J)', underline=0) 52 menu_open.add_command(label='Mail(M)', underline=0) 53 menu_file.add_command(label='Quit(Q)',underline=0, command=app.quit) 54 55 #★ 56 menu_help.add_command(label='Display(D)', underline=0) 57 menu_help.add_command(label='Version(V)', underline=0) 58 #★ 59 60 61 62 63 # 子画面①開く Script Menu 64 def openDialog1(self, event=None): 65 66 global pngfile 67 68 # メモリにDB一覧を作る 69 70 71 72 73 self.dialog = Toplevel(self) 74 self.dialog.title("Script Menu") 75 76 #フォームサイズを実行端末から導き、ド真中に配置表示 77 lw = math.ceil(ww * 0.408) 78 lh = math.ceil(wh * 0.477) 79 self.dialog.geometry(str(lw)+"x"+str(lh)+"+"+str(int(ww/2-lw/2))+"+"+str(int(wh/2-lh/2))) 80 81 self.dialog.configure(bg="#F0FFFF") 82 self.dialog.resizable(0,0) 83 self.dialog.protocol('WM_DELETE_WINDOW', (lambda: 'pass')()) 84 85 # 当該ダイアログのカーソルを変更し、関数側でもカーソルを変更できるように 86 self.dialog['cursor'] = 'hand2' 87 self.this = self.dialog 88 89 # modalに 90 self.dialog.grab_set() 91 92 93 94 # DataBaseを選択するためのコンボボックス 95 self.cmbox1 = ttk.Combobox(self.dialog, width=5, justify=CENTER, state='readonly', takefocus=1) 96 self.cmbox1.grid(row=0, column=0, padx=(10, 0), pady=(10,0), sticky=W+E) 97 self.cmbox1.focus_set() 98 99 # DataBaseという文字 100 self.txt1 = Entry(self.dialog, state="readonly", takefocus=1) 101 self.txt1.grid(row=0, column=1, columnspan=7, sticky=W+E, pady=(10,0)) 102 103 104 105 106 # 登録SQL文のコンボボックス 107 self.v2 = StringVar() 108 self.cmbox2 = ttk.Combobox(self.dialog, width=5, justify=CENTER, state='disable', textvariable=self.v2, takefocus=1) 109 self.cmbox2.grid(row=1, column=0, padx=(10, 0), sticky=W+E) 110 111 self.txt2 = Entry(self.dialog, state="readonly", takefocus=1) 112 self.txt2.grid(row=1, column=1, columnspan=7, sticky=W+E) 113 114 # 登録SQL文のコンボボックスの有効無効切替え 115 self.chbox1_var = BooleanVar(self.dialog) 116 self.chbox1 = Checkbutton(self.dialog, variable=self.chbox1_var, bg="#F0FFFF", takefocus=1, activebackground="#F0FFFF") 117 self.chbox1.grid(row=1, column=8) 118 119 self.btn4 = Button(self.dialog, text='Delete', state=DISABLED, takefocus=1) 120 self.btn4.grid(row=1, column=10, padx=(0,10), sticky=W+E) 121 122 123 124 125 # 発行するSQL文の入力エリア 126 self.scrtxt1 = tksc.ScrolledText(self.dialog, bg="black", fg="orange", font=("Helvetica",11), insertbackground="orange", blockcursor=False, height=6, state="disable", takefocus=1) 127 self.scrtxt1.grid(row=2, column=0, columnspan=11, sticky=W+E, padx=10) 128 129 self.update() 130 scrtxt1_width = self.scrtxt1.winfo_width() 131 scrtxt1_height = self.scrtxt1.winfo_height() 132 middle_x = scrtxt1_width / 2 133 middle_y = scrtxt1_height / 2 134 135 self.cvs = Canvas(self.dialog, height=scrtxt1_height) 136 self.cvs.create_image(middle_x, middle_y, anchor=CENTER) 137 self.cvs.grid(row=2, column=0, columnspan=11, sticky=W+E, padx=10) 138 139 140 141 142 self.lb1 = Label(self.dialog, bg="#F0FFFF", fg="red") 143 self.lb1.grid(row=3, column=0, padx=(10, 0), pady=(0, 20), sticky=N+W) 144 145 self.lb2 = Label(self.dialog, bg="#F0FFFF", fg="red") 146 self.lb2.grid(row=3, column=2, pady=(0, 20), sticky=N+W) 147 148 # SQL文の表示を許すか許さないかの切替え 149 self.chbox2_var = BooleanVar(self.dialog) 150 self.chbox2 = Checkbutton(self.dialog, variable=self.chbox2_var, bg="#F0FFFF", takefocus=1, activebackground="#F0FFFF") 151 self.chbox2.grid(row=3, column=8, pady=(0, 40), ) 152 153 # ★SQL発行ボタン★ 154 self.btn1 = Button(self.dialog, text='Execute', width=10, state=DISABLED, takefocus=1) 155 self.btn1.grid(row=3, column=10, pady=(0, 20), padx=(0,10), sticky=N) 156 157 158 159 160 # SQL発行結果(表示専用) 161 self.scrtxt2 = tksc.ScrolledText(self.dialog, bg="SystemButtonFace", font=("Helvetica",11), height=6, takefocus=1) 162 self.scrtxt2.grid(row=4, column=0, columnspan=11, sticky=W+E, padx=10) 163 164 165 166 167 # SQL登録ボタン 168 self.btn2 = Button(self.dialog, text='Save', state=DISABLED, takefocus=1) 169 self.btn2.grid(row=5, column=0, padx=(10,0), sticky=W+E) 170 171 # SQL登録ID 172 self.lb3 = Label(self.dialog, bg="black", fg="orange", width=7, takefocus=1) 173 self.lb3.grid(row=5, column=1, sticky=W+E) 174 175 self.txt3 = Entry(self.dialog, state='readonly', takefocus=1) 176 self.txt3.grid(row=5, column=2, columnspan=10, sticky=W+E, padx=(0,10)) 177 178 179 180 181 # EXCEL出力ボタン 182 self.btn3 = Button(self.dialog, text='Excel', state=DISABLED, takefocus=1) 183 self.btn3.grid(row=6, column=0, padx=(10,0), sticky=W+E) 184 185 self.prbar1 = ttk.Progressbar(self.dialog, orient=HORIZONTAL, length=100, mode='determinate') 186 self.prbar1.grid(row=6, column=1, columnspan=3, pady=(5,0), sticky=N+W) 187 188 # SQL文の提供を受けることを想定し インポートメニューを追加 189 btn5 = Button(self.dialog, text='Import', width=10, takefocus=1) 190 btn5.grid(row=6, column=8, pady=10) 191 192 193 # 閉じるボタン 194 btn4 = Button(self.dialog, text='Quit', command=self.closeDialog, width=10, takefocus=1) 195 btn4.grid(row=6, column=10, pady=10, padx=(0,10)) 196 btn4.bind('<Return>', self.closeDialog) 197 198 199 200 self.dialog.grid_rowconfigure(1, weight=1) 201 self.dialog.grid_rowconfigure(3, weight=1) 202 203 self.dialog.grid_columnconfigure(2, weight=1) 204 205 206 207 208 209 # 子画面閉じる 210 def closeDialog(self, event=None): 211 self.dialog.destroy() 212 213 214 215if __name__ == '__main__': 216 217 #世間でいうrootをappとしています 218 app = Tk() 219 220 #実行端末の画面サイズを取得 221 ww = app.winfo_screenwidth() 222 wh = app.winfo_screenheight() 223 224 app.update_idletasks() 225 226 #フォームサイズを実行端末から導き、ド真中に配置表示 227 lw = math.ceil(ww * 0.208) 228 lh = math.ceil(wh * 0.277) 229 app.geometry(str(lw)+"x"+str(lh)+"+"+str(int(ww/2-lw/2))+"+"+str(int(wh/2-lh/2)) ) 230 231 #タイトルを指定 232 app.title("Main Menu") 233 234 235 #フォームの最大化、×ボタン操作を無効化 236 app.resizable(0,0) 237 app.protocol('WM_DELETE_WINDOW', (lambda: 'pass')()) 238 239 # カーソル変更 240 app["cursor"] = "hand2" 241 242 243 244 # フレームを作成する 245 frame = Apprication(app) 246 # 格納したTkインスタンスのmainloopで画面を起こす 247 app.mainloop() 248 249

端末Aでの実行(立ち上げ時メニューでSCRIPTを押してください)
大きな解像度での実行
端末Bでの実行(立ち上げ時メニューでSCRIPTを押してください)
SCRIPT

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiracamus

2020/07/02 17:54

解像度に合わせてフォントサイズを変更することが考えられますが、まったく同じイメージにはならないと思います。 簡単なサンプルコードを示してくれれば、アドバイスもしやすくなります。 OSが違うとフォントの種類やサイズも違うので、OSの種類・バージョン、Pythonのバージョン、tkinterのバージョンも示してください。
saya24

2020/07/03 06:07

shiracamusさん ご見解ありがとうございます。簡易コードを作り本文に反映させて頂きました。 アプリの利用予定端末は すべてWindows10、コードはPython3.6で構築、TkIinterのVerは...ごめんなさい ちょっと不明です。 希望としてはどのWindows10端末であっても 常に端末B(アプリの開発端末)で実行されている際同様に SCRIPTのフォームを 形成して表示されて欲しいです!!
hope_mucci

2020/07/03 07:21

端末の画像解像度に合わせてウィンドウサイズを変更していますが、それは必要な要件なのでしょうか?
saya24

2020/07/03 07:27

いえ、必要ない要件です。 ただ、ウィンドウサイズを 可変にさせないと 大きな画像のモニタに フォームが極小で表示されてしまったりしないかを 懸念致しました。 ひょっとして、開発端末と同一の 画像サイズ(縦×横 比率)でないと、同じデザインを保てない、ということでしょうか?? ほんと初心者で 分からないんです。
hope_mucci

2020/07/03 07:34

医療用モニタや8Kモニタにdot by dotで表示させない限りは読めないほど小さくならないのでは・・・
guest

回答1

0

ベストアンサー

レイアウトが崩れるのはモニタ解像度によりgeometryでウィンドウサイズを変更しているのが原因です。

python

1app.geometry(str(lw)+"x"+str(lh)+"+"+str(int(ww/2-lw/2))+"+"+str(int(wh/2-lh/2)) )

コメントを見る限りウィンドウサイズは固定でよさそうなので初期表示位置を設定する用途だけに使ってください。

投稿2020/07/03 07:40

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/07/03 13:44

仰るとおりでした! 私にとっては貴重なアドバイスでした。ありがとうございます。
saya24

2020/07/06 08:20

引用頂きましたコードで ww と wh というのが 端末からの画面サイズなのですが この比率、つまりは 縦と横の関係さえ維持すれば 開発端末で表示されていフォームイメージが どの端末でも 同じように表示されると思っていたら....違うのですねぇ!!!! 今日改めて気が付きました。 モニター違いで、縮尺率だけ変わって同じ範囲の内容表示をするのなら 上記ロジックが成り立つのでしょうが 決して そうじゃないんですね????? 表示できる範囲さえも 変わってくるのですね!(行数とか) だから みなさん わざわざ 大きな外付けモニタを購入するのですねぇ.... 今更ですが
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問