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

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

新規登録して質問してみよう
ただいま回答率
85.35%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Tkinter

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

Python

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

Q&A

解決済

1回答

1933閲覧

python tkinter ファイルの選択について

riyoriyo

総合スコア3

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/09/08 06:11

前提・実現したいこと

ファイルの選択画面の初期ディレクトリの指定に関してなのですが、initialdirでtextファイルに書いてあるディレクトリを初期ディレクトリにしたい。
3つの初期ディレクトリが違うように設定したい。

発生している問題・エラーメッセージ

それぞれの初期ディレクトリを指定しているのですが、うまく表示されません。
前に指定したフォルダが初期フォルダに指定されてしまいます。

該当のソースコード

python

1import tkinter as tk 2import tkinter.filedialog 3import tkinter.messagebox 4from tkinter import ttk 5from tkinter import * 6import pandas as pd 7import os 8import datetime 9import logging 10import codecs 11 12def button01_click(): 13 path = "情報.txt" 14 with open(path) as f_01: 15 f_02 = f_01.read() 16 file_name01 = tk.filedialog.askopenfilename(initialdir=f_02) 17 if file_name01: 18 attribute_01.set(file_name01) 19def button02_click(): 20 path = "情報01.txt" 21 with open(path) as f_03: 22 f_04 = f_03.read() 23 file_name02 = tk.filedialog.askopenfilename(initialdir=f_04) 24 if file_name02: 25 file01.set(file_name02) 26 27def button03_click(): 28 path = "情報02.txt" 29 with open(path) as f_03: 30 f_04 = f_03.read() 31 file_name03 = tk.filedialog.askopenfilename(initialdir=f_03) 32 if file_name03: 33 file02.set(file_name03) 34 35 36if __name__ == "__main__": 37 root = tk.Tk() 38 root.geometry("1300x500") 39 root.title("データの選択") 40 frame01 = ttk.Frame(root,padding=(32)) 41 frame01.grid() 42 43 button01 = ttk.Button(frame01,text="ファイルの選択",width=30,command=button01_click) 44 button01.grid(row=0,column=5) 45 attribute_01 = StringVar() 46 label01 = ttk.Label(frame01,textvariable=attribute_01) 47 label01.grid(row=0,column=6) 48 49 button02 = ttk.Button(frame01,text="ファイルの選択",width=25,command=button02_click) 50 button02.grid(row=1,column=5) 51 file01 = StringVar() 52 label02 = ttk.Label(frame01,textvariable=file01) 53 label02.grid(row=1,column=6) 54 55 button03 = ttk.Button(frame01,text="出力先の選択",width=25,command=button03_click) 56 button03.grid(row=2,column=5) 57 file02 = StringVar() 58 label04 = ttk.Label(frame01,textvariable=file02) 59 label04.grid(row=2,column=6) 60 61 button04 = ttk.Button(frame01,text='作成',command=lambda: root.quit()) 62 button04.grid(row=3,column=5) 63 64 root.mainloop() 65 66 attriable_02 = attribute_01.get() 67 attriable_03 = attriable_02.split("/") 68 attriable_04 = attriable_03.pop() 69 map_01 = map(str,attriable_03) 70 attriable_05 = "/".join(map_01) 71 with open("情報.txt","w") as g: 72 print(attriable_05,file=g) 73 74 attriable_06 = file01.get() 75 attriable_07 = attriable_06.split("/") 76 attriable_08 = attriable_07.pop() 77 map_02 = map(str,attriable_07) 78 attriable_09 = "/".join(map_02) 79 with open("情報01.txt","w") as g: 80 print(attriable_09,file=g) 81 82 attriable_10 = file02.get() 83 attriable_11 = attriable_10.split("/") 84 attriable_12 = attriable_11.pop() 85 map_03 = map(str,attriable_11) 86 attriable_13 = "/".join(map_03) 87 with open("情報02.txt","w") as g: 88 print(attriable_13,file=g) 89

試したこと

いろいろと調べて行ったのですができませんでした。

補足情報(FW/ツールのバージョンなど)

pythonのバージョンはPython 3.7.6です。

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

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

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

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

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

q_sane_q

2020/09/08 07:11

本来どのような動作を想定しているのか、それに対しどのようになっしまっているのかがわかりづらいので、もう少し具体的なところを追記お願いできますか?
riyoriyo

2020/09/08 07:25

わかりずらくて申し訳ございません。 本来は読み込んだファイルがあるディレクトリを記憶して、次に実行する際に前に選択したファイルがあるディレクトリを初期ディレクトリとして設定したいと思っています。 なのでテキストファイルにファイルを選んだ後にディレクトリを書き込んで次に実行する際にそのテキストファイルから初期ディレクトリを読み込むことを想定しています。 問題としては、実行すると3つのファイル選択の画面ができるのですが、テキストファイルの文字列を読み込むことなく、意図していない場所が初期ディレクトリとして表示されてしまいます。
q_sane_q

2020/09/08 07:36

次に実行する際、 というのは(プログラムは起動したまま)もう一回ボタンを押したとき、でしょうか それともプログラムを起動し直したとき でしょうか?
riyoriyo

2020/09/08 07:38

プログラムを一度終了させて、またプログラムを起動させた時です。
q_sane_q

2020/09/08 08:12

処理をざっと見たところ情報ファイルへの書き込みが行われるのはrootのフレームが閉じたあとで、その時ファイルダイアログでファイルが選択されていないと情報ファイルが空白になりそうですが、そこに起因した挙動ではないでしょうか
riyoriyo

2020/09/08 08:21

ありがとうございます。 ファイルが選択されていないと空白になるのですが、ファイルを選択した際には情報ファイルに書き込みが行われるのでそこが原因では無いと思います。
nto

2020/09/08 12:03

関数を定義する際にコピペしてしまっていませんか?
riyoriyo

2020/09/08 12:08

基本的にコードが変わらないのでコピペしてして、ファイル名だけを変えてます。 コピペだとダメなんでしょうか?
nto

2020/09/08 12:21

button03_click関数でのinitialdirの指定がファイル名(ただの文字列)になってしまっていると思いまして。 一点お伺いしたいのですが、txtファイルへの書き込みはどのタイミングで行いたいという事でしょうか? 目的のタイミングを教えて下さい。
riyoriyo

2020/09/08 12:30

すみません。そこはこちらのミスです。f_03ですね。 書き込みのタイミングはどのタイミングでもいいです。 txtファイルに書き込む目的としてはプログラムを実行する際に前回に実行した際に選んだファイルのディレクトリを記憶しておきたいためなので。
guest

回答1

0

ベストアンサー

ディレクトリの取得は標準モジュールであるpathlibのPathを使用する事で
親ディレクトリ名の取得が可能です。
また、ファイル操作を行う為の関数もそれぞれに定義するのではなく
引数を与えてあげる事で関数定義は1回で済む様になります。

以下で目的通りの挙動を得られるかと思います。こちらで勝手にクラス化及び不要箇所、見づらい点などを成形してしまっております。
その点についてはご了承ください。

python

1import tkinter as tk 2from tkinter import ttk 3import tkinter.filedialog 4from pathlib import Path 5 6 7class MainWindow(ttk.Frame): 8 def __init__(self, master): 9 super().__init__(master) 10 self.master.geometry("1300x500") 11 self.master.title("データの選択") 12 self.CreateWidget() 13 14 def CreateWidget(self): 15 self.frame = ttk.Frame(self.master, padding=(32)) 16 self.frame.grid() 17 18 19 self.attribute_01 = tk.StringVar() 20 self.file01 = tk.StringVar() 21 self.file02 = tk.StringVar() 22 23 self.button01 = ttk.Button(self.frame,text="ファイルの選択",width=30,command=lambda: self.ButtonClick('情報.txt', self.attribute_01)).grid(row=0,column=5) 24 self.button02 = ttk.Button(self.frame,text="ファイルの選択",width=25,command=lambda: self.ButtonClick('情報01.txt', self.file01)).grid(row=1,column=5) 25 self.button03 = ttk.Button(self.frame,text="出力先の選択",width=25,command=lambda: self.ButtonClick('情報02.txt', self.file02)).grid(row=2,column=5) 26 27 28 ttk.Label(self.frame,textvariable=self.attribute_01).grid(row=0,column=6) 29 ttk.Label(self.frame,textvariable=self.file01).grid(row=1,column=6) 30 ttk.Label(self.frame,textvariable=self.file02).grid(row=2,column=6) 31 32 self.button04 = ttk.Button(self.frame,text='作成',command=lambda: self.master.quit()).grid(row=3,column=5) 33 34 def ButtonClick(self, file, var): 35 with open(file, 'r') as f: 36 filedata = f.read() 37 filename = tk.filedialog.askopenfilename(initialdir=filedata) 38 if filename: 39 var.set(filename) 40 self.LastDirSave(file, var) 41 42 def LastDirSave(self, file, var): 43 vardata = var.get() 44 parent_dir = Path(vardata).parent 45 with open(file, 'w') as f: 46 print(parent_dir, end='', file=f) 47 48 49if __name__ == '__main__': 50 root = tk.Tk() 51 app = MainWindow(master = root) 52 app.mainloop()

追記

モジュールのインポートですがimport tkinter as tkimport tkinter as *が混在するのはあまり好ましくありません。どちらかで統一しましょう。

投稿2020/09/08 12:52

編集2020/09/09 02:31
nto

総合スコア1438

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

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

riyoriyo

2020/09/08 13:09

ntoさん!ありがとうございます! もっとPythonの勉強をする必要があると思うのでこれから頑張っていきます。 本当にありがとうございました!
nto

2020/09/08 13:30

またもう一点挙げるとしたら、わざわざテキストを3つ用意する必要もありません。 例えばjsonファイルやiniファイルを使ってそれぞれのパスを1つのファイルで管理することも可能です。 configparserモジュールやjsonモジュールなど、ご自身のお好きな形を取ってお試しください。 またそれらを実装していく上で分からない所があったらteratailで質問をしてみてください。
riyoriyo

2020/09/08 15:53

すみません。一度このコードを実行させていただいたのですが、私の作成したコードと同じような動作をしてしまいます。 1つ目のファイル選択を押してファイルを選んだあと、次に2つ目のファイルを選択する際に、1つ目で選択したファイルがあるディレクトリが初期ディレクトリとして表示されてしまいます。 環境による問題でしょうか? 何度も申し訳ございません。
nto

2020/09/09 00:33

そもそも予め情報ファイル内でパスの指定は出来てありますか?
riyoriyo

2020/09/09 01:13

はい。予めテキストファイル内でパスの指定は行っています。
nto

2020/09/09 02:34

失礼致しました。大事な部分を忘れてしまっていました、ただいま解答のコードを編集致しましたので今一度お確かめください。 原因はテキストファイル保存時、テキストの最後に入ってしまう改行が原因です。 修正方法は2パターンあります。 - テキストを読み込む際に.replace('\n','')として、改行コードを置換してしまう - テキスト保存時に末尾に改行が入らない様に保存する 今回は後者の末尾に改行が入らない様にという方法をとって、テキスト保存時のオプションをprint(parent_dir, end='', file=f)とする事で修正が確認いただけるかと思います。
riyoriyo

2020/09/09 03:30

こちらこそこんなに何度も対応していただいて申し訳ございません。 教えていただいた部分の編集を行ったことで無事に解決いたしました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問