![](/img/trans.png)
[英]Python Tkinter Text Widget not displaying contents from .txt file
[英]Tkinter: print (.txt) filepath to text widget AND (.txt) file content to scrolledtext widget in the same gui with one filedialogue access
作为对此的后续问题: Python tkinter - 如何使用 grid() 和使用程序代码将 StringVar() 内容发送到滚动文本框
我可以在同一个程序中浏览两次,以实现目标; 但这并没有真正实现目标。
def browsefunc(): #browse button to search for files
filename = filedialog.askopenfilename()
infile = open(filename, 'r')
content = infile.read()
pathadd = os.path.dirname(filename)+filename
pathlabel.delete(0, END)
pathlabel.insert(0, pathadd)
return content
Tkinter 中的按钮错误 - 选择文件,添加它们的路径我也是这样做的,这有点不同:
def fd_getfile():
filetypes = (
('sys list file', '*.txt'),
('any', '*.*')
)
filename_file1 = fd.askopenfilename(
title='add file1',
initialdir='src',
filetypes=filetypes)
file1_entry.insert(tk.END, filename_file1)
showinfo(
title='file1 selected',
message=filename_file1,
)
def process(*args):
try:
# COMMENT: Reset output
file1.set('')
# COMMENT: Load files
with open(file1path.get()) as file1:
def forkscroll():
mylabelframe = tk.LabelFrame(myframe, text='My Long Text:').pack()
scroll_w = 30
scroll_h = 10
myscrolledtext = scrolledtext.ScrolledText(mylabelframe, width=scroll_w, height=scroll_h, wrap=tk.WORD)
myscrolledtext.vbar.config(width=20)
myscrolledtext.grid(sticky='news', row=6, column=0, rowspan=1, columnspan=1, padx=5, pady=5)
# Open a dialogue; select and load a text file; read the text file directly into the scrolledtext widget (box)
fork = open(filedialog.askopenfilename(), 'r') # it's the same as "infile" above; but it's not a string
myscrolledtext.insert(tk.END, fork.read()) ### This reads the content of "fork" into the scrolledtext widget
forkit = StringVar()
forkit.set(fork.get())
mynormaltext = Text(mylabelframe, width = 10, height = 1, wrap=tk.WORD)
mynormaltext.grid(sticky='news', row=5, column=0, rowspan=1, columnspan=1, padx=5, pady=5)
mynormaltext.insert(tk.END, forkit.get())
# Even though it does the same thing in one line as it does in three, the outcome is not the same for scrolledtext
# forkname = filedialog.askopenfilename()
# forkfile = open(forkname, 'r')
# fork = forkfile.read()
# above... "fork" is a textIO, but Text can read it...
我查看了 forkname、forkfile 和 fork 这三行,发现它看起来像是 fork=open(filedialog.askopenfilename(), 'r').read() 的简写,这就是我最终获得滚动文本的方式工作......但是这个“fork”在每种情况下都是不同的文件类型......一个是字符串,另一个是“TextIO”或“FilePath”object。 后者适用于滚动文本,但前者不适用。 前者适用于插入文本,但后者不适用。 它们不能在同一个 function 中共存,而且代码似乎不喜欢它们在 same.py 文件中,所以我猜它们应该在不同的类中......但我不知道如何转换这段代码上课。
关于如何实现预期功能的任何想法?
预期的功能是:
对于你问题的第二部分
由于wrap
设置,出现了路径不完整的问题。 要解决这个问题,只需更改此字符串:
mypathtext = Text(mylabelframe, width=10, height=1)
您可以使用.replace()
方法修复带有反斜杠和正斜杠的功能。
这个怎么样:
from tkinter import *
from tkinter import filedialog
from tkinter import scrolledtext
import os
def browsefunc():
global content
filename = filedialog.askopenfilename()
infile = open(filename, 'r')
content = infile.read()
pathadd = filename
pathtext.delete(0.0, END)
pathtext.insert(0.0, pathadd)
contenttext.delete(0.0, END)
contenttext.insert(0.0, content)
w = Tk()
w.geometry('600x370')
lb1 = Label(text="Select text file")
lb1.place(x=0, y=0)
bt1 = Button(text="Process", command=browsefunc)
bt1.place(x=0, y=40)
pathtext = Text()
pathtext.place(x=0, y=85, width=450, height=20)
contenttext = scrolledtext.ScrolledText()
contenttext.place(x=0, y=120, width=450)
读取文件后,您的数据将位于content
变量中。
查看调试器后,发现 TextIO 变量“fork”包含两部分:“<_io.Textwrapper”和“name = C:\blah\blah\blah”
我得到了 99% 的工作是这样的:
#import os
#import io
from tkinter import *
#from tkinter import ttk
from tkinter import filedialog
from tkinter import scrolledtext
import tkinter as tk
from pathlib import Path
from typing import TextIO
def forkscroll():
mylabelframe = tk.LabelFrame(myframe, text='My Long Text:').pack()
scroll_w = 30
scroll_h = 10
myscrolledtext = scrolledtext.ScrolledText(mylabelframe, width=scroll_w, height=scroll_h, wrap=tk.WORD)
myscrolledtext.vbar.config(width=20)
myscrolledtext.grid(sticky='news', row=6, column=0, rowspan=1, columnspan=1, padx=5, pady=5)
# Open a dialogue; select and load a text file; read the text file directly into the scrolledtext widget (box)
fork: TextIO = open(filedialog.askopenfilename(), 'r')
myscrolledtext.insert(tk.END, fork.read()) ### This reads the content of "fork" into the scrolledtext widget
forkname = fork.name # works
mypathtext = Text(mylabelframe, width=10, height=1, wrap=tk.WORD)
mypathtext.grid(sticky='news', row=5, column=0, rowspan=1, columnspan=1, padx=5, pady=5)
mypathtext.insert(tk.END, forkname) # works
#GUI
root = Tk()
root.title('Root Title')
root.geometry('600x300')
myframe = tk.Frame(root, width=300, height=300)
myframe.winfo_toplevel().title('MyFrame Title')
myframe.grid(column=0, row=0, sticky='news')
myforkpath = StringVar()
f1 = Frame(myframe, width=900, height=150) #file1
f1.pack(fill=X, side =TOP)
f2 = Frame(myframe, width=900, height=150) #file2
f2.pack(fill=X, side=BOTTOM)
Label(f1, text="Select text file").grid(row=0, column=0, sticky='e') # select file button label
run_button = Button(myframe, text="Process", command=forkscroll).pack()
Label(f2, text="put the content of the file in the text scroll box below").grid(row=1, column=0, sticky='s')
myframe.mainloop()
...有一个问题...那 1%
我的笔记本电脑被命名为“Crappy Laptop”(不是真的,但它在路径的那部分名称中有一个空格),因此打印到文本小部件字段的名称路径是:
“C://用户/糟糕”
...我没有完整的路径...应该是“C://Users/Crappy Laptop/Desktop/My/Python/Code/mylongtextfile.txt”
in fact I get forward slashes, and not backslashes... in the Pycharm console window it displays the paths with slashes in each direction: Like this: C.\......\python:exe C.//.. ./.../myfile.py
如何处理空间?
好吧,到目前为止我已经做到了...
forkname = fork.name # works
# fix the "path with spaces problem"
newforkname1 = forkname.replace(' ', '_')
print(newforkname1)
newforkname2 = newforkname1.replace('/', '\\')
print(newforkname2)
mypathtext = Text(mylabelframe, width=10, height=1, wrap=tk.WORD)
mypathtext.grid(sticky='news', row=5, column=0, rowspan=1, columnspan=1, padx=5, pady=5)
#mypathtext.insert(tk.END, forkname) # works
mypathtext.insert(tk.END, newforkname2) # works
还没有弄清楚如何显示空格而不是下划线。
这完全不行……
newforkname1 = forkname.replace(' ', ' '.join(forkname))
这是一个单独的答案,因为我从上一个问题和这个问题中解决了一个问题,但产生了一个新问题:D
我能够使用 StringVar 将文本文件中的字符串内容从一个 function 传递到另一个 function ...
所以我在代码顶部添加了新的 StringVars
reflines_sv = StringVar()
cfglines_sv = StringVar()
然后在 function 中,我打开文本文件,获取内容,并将其传递给字符串,然后传递给字符串变量:
def getref():
# COMMENT: Get reference file
Label(frame_input, anchor='w', width=80, text='Reference filepath:', background='#abdbe3').pack(side=TOP, fill=Y)
ref: TextIO = open(filedialog.askopenfilename(title='add Reference file', initialdir='src', ), 'r')
reflines = ref.readlines()
reflines_sv.set(reflines)
# COMMENT: Get reference file path
refname = ref.name
refname_new = refname.replace('/', '\\')
pathtext_ref = Text(frame_input, width=80, height=1, bg='#f0f0f0')
pathtext_ref.pack(anchor='n', side=TOP, fill=Y, ipadx=5, ipady=5)
pathtext_ref.configure(font=("Arial", 9, "italic",))
pathtext_ref.insert(tk.END, refname_new)
return reflines_sv
然后在下一个 function 中,我可以检索内容并使用它。
def process():
try:
# COMMENT: Reset output
rdiff.set('')
tdiff.set('')
rtmiss.set('')
reflines = reflines_sv.get()
cfglines = cfglines_sv.get()
# COMMENT: Comparing lines
refhash = dict()
cfghash = dict()
different = False
etc...
这样做的好处是我现在可以拥有一个带有单独按钮的向导,用于处理文本文件的不同阶段。
可能有更好的方法可以做到这一点,但我还没有找到。
新的问题是,现在文本文件的内容没有正确输出。
等等... =下面的代码
for i, value in enumerate(reflines):
refhash[i] = value
for i, value in enumerate(cfglines):
cfghash[i] = value
contains = value in refhash.values()
different = different or not contains
if not contains:
tdiff.set(tdiff.get() + 'problem line ' + str(i) + ': ' + value) ### <- new problem!
for i, value in enumerate(reflines):
contains = value in cfghash.values()
different = different or not contains
if not contains:
rdiff.set(rdiff.get() + 'line ' + str(i) + ': ' + value)
if not different:
errmsg.set('no differences')
if len(reflines) == len(cfglines) and different:
for i, _ in enumerate(reflines):
if cfglines[i] != reflines[i]:
rtmiss.set(rtmiss.get() + 'line ' + str(i) + '\n')
else:
rtmiss.set('files have different number of lines')
scroll_w = 15
scroll_h = 5
myscrolledtext1 = scrolledtext.ScrolledText(frame_input, width=scroll_w, height=scroll_h, wrap=tk.WORD,background='#bbffe6')
myscrolledtext1.vbar.config(width=20)
myscrolledtext1.pack(anchor='s', fill=X, side=LEFT, ipadx=5,ipady=5, expand=True)
myscrolledtext1.insert(tk.END, rdiff.get())
myscrolledtext2 = scrolledtext.ScrolledText(frame_input, width=scroll_w, height=scroll_h, wrap=tk.WORD, background='#bbffe6')
myscrolledtext2.vbar.config(width=20)
myscrolledtext2.pack(anchor='s', fill=X, side=LEFT, ipadx=5,ipady=5, expand=True)
myscrolledtext2.insert(tk.END, tdiff.get())
myscrolledtext3 = scrolledtext.ScrolledText(frame_input, width=scroll_w, height=scroll_h, wrap=tk.WORD,background='#bbffe6')
myscrolledtext3.vbar.config(width=20)
myscrolledtext3.pack(anchor='s', fill=X, side=LEFT, ipadx=5,ipady=5, expand=True)
myscrolledtext3.insert(tk.END, rtmiss.get())
except OSError:
errmsg.set('failed to load both files')
# COMMENT: Buttons
button_ref = Button(frame_button, text="Browse for ref file", font='50', command=getref).pack(anchor='s', side=BOTTOM, pady=10, ipadx=5, ipady=20)
button_cfg = Button(frame_button, text="Browse for test file", font='50', command=getcfg).pack(anchor='s', side=BOTTOM, pady=10, ipadx=5, ipady=20)
button_process = Button(frame_button, text="Process", font='50', command=process).pack(anchor='s', side=BOTTOM, pady=10, ipadx=5, ipady=20)
它以前没有这样做,当我把它全部放在一个 function 中时,只需一个按钮。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.