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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2532閲覧

別画面の表示、値のインサートについて

MATLIB

総合スコア27

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/10/11 12:57

編集2020/10/11 13:36

ファイルAの一覧で選択した行の値を取得して画面2ボタンを押下すると、
選択した行のIDと名前を取得してその値をファイルBのテキストボックスにインサートして
画面を表示したいです。

現在、ファイルAではボタンを押下して、ファイルBにIDと名前を引数として
渡すことはできています。

問題点としては、ファイルBのテキストボックスにインサートして画面を表示できないのと、
ファイルAの画面がボタンを押下してファイルB画面が開くとファイルBの画面の大きさや画面名になって
表示され、きちんと表示されていない状態です。

どなたかご教授ください。

<ファイルA>
#ここでIDと名前を取得して、その値をファイルBに引数で渡す処理と
画面を開く処理を書いています。

def selected(self):
for item in self.master.tree.selection():
print(item, self.master.tree.item(item))
d = self.master.tree.item(item)
self.txt_id = d['values'][0]
self.txt_name = d['values'][1]
print(self.txt_id)
print(self.txt_name)
gamen2(self.master,self.txt_id,self.txt_name)
test10.main()

<ファイルB>
#ここでIDと名前を引数で受け取り、テキストボックスにインサートする処理を書いています。
書く場所が違う?
class gamen2(tkinter.Frame):
def init(self, master,txt_id,txt_name,**kwargs):
super().init(master)
self.pack()

self.master.geometry("400x300") self.master.title("画面2") self.txt_id = txt_id self.txt_name = txt_name self.create_widgets() self.master.txt.insert(tk.END,self.txt_id) self.master.txt_pw.insert(tk.END, self.txt_name)

#ここのapp = で引数渡せとエラーがでたのでとりあえずそれぞれNoneを入れています。
これもだめな気がしています。

def main():
root = tk.Tk()
app = gamen2(master=root,txt_id=None,txt_name=None)
app.mainloop()

#ファイルA import tkinter import tkinter as tk from tkinter import ttk from tkinter import font import psycopg2 from test10 import gamen2 import test10 # connect postgreSQL conn = psycopg2.connect(必要な情報) # カーソルを取得 cursor = conn.cursor() class itiran(tkinter.Frame): def __init__(self, master=None, **kwargs): super().__init__(master) self.pack() self.master.geometry("400x480") self.master.title("一覧") self.create_widgets() # 略 def selected(self): for item in self.master.tree.selection(): print(item, self.master.tree.item(item)) d = self.master.tree.item(item) self.txt_id = d['values'][0] self.txt_name = d['values'][1] print(self.txt_id) print(self.txt_name) gamen2(self.master,self.txt_id,self.txt_name) test10.main() # 最初の画面に戻るのだ def return_view(self): self.master.destroy() # Create Widgets function def create_widgets(self): # ラベル作成: font1 = font.Font(self.master,size=10) LBL_1= tkinter.Label(self.master,text='ID:', font=font1) LBL_1.place(x=40, y=30) # ラベルを配置する位置の設定 LBL_2 = tkinter.Label(self.master,text='名:', font=font1) LBL_2.place(x=40, y=70) # ラベルを配置する位置の設定 # テキストボックス txt_id= tkinter.Entry(self.master,width=30) # ID txt_id.place(x=100, y=30) txt_name = tkinter.Entry(self.master,width=30) # 名 txt_name.place(x=100, y=70) # ボタン作成 btn_4 = tkinter.Button(self.master,text='画面2', width=8,command = self.selected) # ボタン設定(text=ボタンに表示するテキスト) btn_4.place(x=100, y=400) # ボタンを配置する位置の設定 btn_end = tkinter.Button(self.master, text='閉じる', width=8, command=self.return_view) # ボタン設定(text=ボタンに表示するテキスト) btn_end.place(x=200, y=400) # ボタンを配置する位置の設定 # ツリービューの作成 frame = tk.Frame(self.master) frame.place(x=40, y=200) # ツリービューの作成 self.master.tree = ttk.Treeview(frame, height=8) # ツリービューの配置 self.master.tree.grid(row=0, column=0) self.master.tree["columns"] = (1, 2) self.master.tree["show"] = "headings" self.master.tree.column(1, width=120) self.master.tree.column(2, width=120) self.master.tree.heading(1, text="ID") self.master.tree.heading(2, text="名") # ツリービューのスタイル変更 style = ttk.Style() # TreeViewの全部に対して、フォントサイズの変更 style.configure("Treeview", font=("", 10)) # TreeViewのHeading部分に対して、フォントサイズの変更と太字の設定 style.configure("Treeview.Heading", font=("", 10, "bold")) ysb = tk.Scrollbar(frame, orient=tk.VERTICAL, width=16, command=self.master.tree.yview) self.master.tree.configure(yscrollcommand=ysb.set) ysb.grid(row=0, column=1, sticky='news') # SELECT文の作成 sql = """ SELECT id,name FROM gs """ cursor.execute(sql) # SQLの実行結果を取得 for r in cursor.fetchall(): self.master.tree.insert("", "end", values=r) print(r) print("終了") # ツリービューの配置 self.master.tree.grid(row=0, column=0) # tree.bind("<<TreeviewSelect>>",selected) def main(): root = tk.Tk() app = itiran(master=root) app.mainloop() if __name__ == "__main__": main()
#ファイルB import tkinter from tkinter import font import tkinter as tk class gamen2(tkinter.Frame): def __init__(self, master,txt_id,txt_name,**kwargs): super().__init__(master) self.pack() self.master.geometry("400x300") self.master.title("画面2") self.txt_id = txt_id self.txt_name = txt_name self.create_widgets() self.master.txt.insert(tk.END,self.txt_id) self.master.txt_pw.insert(tk.END, self.txt_name) def return_view(self): self.master.destroy() # Create Widgets function def create_widgets(self): # ラベル作成 font1 = font.Font(self.master, size=10) LBL = tkinter.Label(self.master, text='ID:', font=font1) LBL.place(x=10, y=30) # ラベルを配置する位置の設定 LBL_1 = tkinter.Label(self.master, text='名:', font=font1) LBL_1.place(x=10, y=70) # ラベルを配置する位置の設定 # テキストボックス self.master.txt = tkinter.Entry(self.master, width=20) # ID self.master.txt.place(x=70, y=30) self.master.txt_pw = tkinter.Entry(self.master, width=20) # 名 self.master.txt_pw.place(x=70, y=70) self.master.txt.insert(tk.END,self.txt_id) self.master.txt_pw.insert(tk.END, self.txt_name) btn_end = tkinter.Button(self.master, text='閉じる', width=8, command=self.return_view) # ボタン設定(text=ボタンに表示するテキスト) btn_end.place(x=70, y=150) # ボタンを配置する位置の設定 def main(): root = tk.Tk() app = gamen2(master=root,txt_id=None,txt_name=None) app.mainloop()

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

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

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

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

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

guest

回答1

0

ベストアンサー

問題点としては、ファイルBのテキストボックスにインサートして画面を表示できないのと、

値の受け渡しは出来ている様なので、後者の問題が解決すれば直ると思います。


ファイルAの画面がボタンを押下してファイルB画面が開くと
ファイルBの画面の大きさや画面名になって表示され、きちんと表示されていない状態です。

複数のウィンドウを扱う場合、tkinter.Toplevel でのダイアログ作成方法を調べて下さい。

tkinter.Frame ではなく tkinter.Toplevel を継承し、
モーダルダイアログ(表示中、親ウィンドウは操作できない)にするかどうかで変わってきますが、
mainloop の代わりに wait_window でウィンドウが閉じられるのを待ちます。

  • 問題点1: tk.Tk() が複数回呼ばれている。selected関数内 → test10.main()

tkinter.Tk は、Toplevel (ウィンドウ) と tkinter ライブラリとのやり取りをする部分を受け持ちます。
tkinter.Tk() のインスタンス作成 root = tk.Tk() は、プログラム内で一度のみにして下さい。
2つ目のウィンドウを作りたい場合は、tkinter.Toplevel を利用します。

  • 問題点2: gamen2 が selected関数内と test10.main内で2度呼ばれています。

問題点3: self.master.XXX となっている箇所全般。

  • self.master.tree 現状での実行には支障ありませんが、self.tree にしましょう。

 tkでのウィジェットの階層とPythonでのオブジェクトの階層の一致しない為
Tk root (master) -> Frame itiran (self) -> tree となっていて、間のFrameが破棄された時に
上位の master が破棄済みの tree を保持する事が問題になる可能性があります。

  • 画面2でのtitle,geometry は親ウィンドウのタイトルとサイズを変更します。
  • 画面2でのself.master.destroy() は親ウィンドウを閉じるので、意図通りでない可能性があります。

現状のコードから一度に修正というのは大変だと思うので、
まずは、ダイアログの作成方法 (tkinter.Toplevel の使い方) を調べて、
問題個所の動作を確認する新規のコードを作成してみてください。

投稿2020/10/11 23:06

teamikl

総合スコア8664

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

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

MATLIB

2020/10/12 04:48

とりあえず問題3を修正したら、画面の表示はおかしいですがテキストボックスに同じ値が2回インサートされていることは確認できたので、あとは複数回の画面が表示が治るようにダイアログの作成方法を調べて修正してみます。
MATLIB

2020/10/12 06:33

teamiklさんすみません。 ネットて調べてみたのですが、ほとんど1つのファイル内で完結しているものばかりで、 よく分かりません。 できれば後者の解決方法をコードで教えてもらえると助かります。
teamikl

2020/10/12 07:51

値の受け渡し(txt_id, txt_name) と ファイルB(test10.py モジュール)のクラス・関数の呼び出し自体は出来てるので、 新規ウィンドウを開く部分のみ記述します。(解説は回答でした通りです) https://repl.it/@MiKLTea/TkDialogSample ファイルAの方は必要最低限のコードです。selected 関数内での利用を想定 ファイルBの方は、元のコードを極力残しましたが、 細かな変更点が何カ所もあるので注意深く見て下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問