Я пытаюсь создать простой пользовательский интерфейс в Tkinter, и у меня возникла проблема. Я создаю настраиваемый объект Frame как вкладку в блокноте в общем приложении, а настраиваемый объект Frame определяет сетку, содержащую набор элементов управления слева и другой блокнот справа. Элемент управления Frame правильно устанавливается равным трети ширины родительского кадра, но Notebook начинается только с половиной ширины. Если я нажму кнопку, которая создает больше вкладок и добавляет их в Блокнот, ширина Блокнота увеличивается до тех пор, пока фрейм управления не станет непригодным для использования. Как мне определить такие вещи, чтобы контрольный фрейм всегда составлял точно, скажем, 30% ширины родительского фрейма, а блокнот - 70% ширины, даже если размер родительского фрейма изменяется?
Root .py
from tkinter import *
from tkinter.ttk import *
from tkinter import filedialog
import os
from IndexFrame import IndexFrame
root = Tk()
root.option_add('*tearOff', FALSE)
root.title('Test')
width, height = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (width, height))
root.grid_propagate(0)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
menubar = Menu(root)
root['menu'] = menubar
menu_app = Menu(menubar)
menubar.add_cascade(menu=menu_app, label='App')
tabs = Notebook(root)
tabs.grid(row=0, column=0, sticky='nesw')
def openIndex():
dir = filedialog.askdirectory()
tab = IndexFrame(root, dir)
tabs.add(tab, text=os.path.split(dir)[1])
menu_app.add_command(label='Open Index', command=openIndex)
def closeApp():
root.destroy()
menu_app.add_command(label='Close', command=closeApp)
menu_index = Menu(menubar)
menubar.add_cascade(menu=menu_index, label='Index')
def closeIndex():
tabs.forget(tabs.index('current'))
menu_index.add_command(label='Close Index', command=closeIndex)
menu_results = Menu(menubar)
menubar.add_cascade(menu=menu_results, label='Results')
def closeResults():
tabs.nametowidget(tabs.select()).closeResults()
menu_results.add_command(label='Close Results', command=closeResults)
root.mainloop()
IndexFrame.py (вам может потребоваться удалить код Lucene, если вы хотите запустить его, если у вас не установлен PyLucene)
from tkinter import *
from tkinter import filedialog
from tkinter.ttk import *
from tkinterhtml import HtmlFrame
import lucene
from lucene import *
from java.io import File
from java.lang import Integer
from org.apache.lucene.analysis.standard import StandardAnalyzer
from org.apache.lucene.index import IndexReader, DirectoryReader
from org.apache.lucene.search import IndexSearcher, BooleanClause
from org.apache.lucene.queryparser.classic import MultiFieldQueryParser
from org.apache.lucene.store import FSDirectory
from ScrollText import ScrollText
class IndexFrame(Frame):#(PanedWindow):
def __init__(self, parent, dirPath):
Frame.__init__(self, parent)
lucene.initVM()
analyzer = StandardAnalyzer()
indexPath = File(dirPath).toPath()
indexDir = FSDirectory.open(indexPath)
reader = DirectoryReader.open(indexDir)
searcher = IndexSearcher(reader)
self.grid_propagate(0)
queryFrame = Frame(self)
queryFrame.grid(row=0, column=0, sticky='nsw')
self.resultsTabs = Notebook(self)
self.resultsTabs.grid(row=0, column=1, sticky='nesw')
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=3)
label = Label(queryFrame, text="Contains " + str(reader.numDocs()) + " indexed documents")
label.grid(row=0, column=0, columnspan=3, sticky='nesw')
text = ScrollText(queryFrame)
text.grid(row=2, column=0, columnspan=3, sticky='nesw')
def save_btn():
fname = filedialog.asksaveasfilename(title="Save query", filetypes=(("text files", "*.txt"),))
if fname:
file = open(fname, 'w')
file.write(text.text.get('1.0', 'end'))
file.close()
save = Button(queryFrame, text='Save', command=save_btn)
save.grid(row=1, column=0, sticky='ew')
def load_btn():
fname = filedialog.askopenfilename(title="Load query", filetypes=(("text files", "*.txt"),))
if fname:
text.text.delete('1.0', 'end')
file = open(fname, 'r')
text.text.insert('1.0', file.read())
file.close()
load = Button(queryFrame, text='Load', command=load_btn)
load.grid(row=1, column=1, sticky='ew')
def clear_btn():
text.text.delete('1.0', 'end')
clear = Button(queryFrame, text='Clear', command=clear_btn)
clear.grid(row=1, column=2, sticky='ew')
def search_btn():
queryText = text.text.get('1.0', 'end')
fields =["title", "abstract", "keywords"]
flags = [BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD]
query = MultiFieldQueryParser.parse(queryText, fields, flags, analyzer)
docs = searcher.search(query, Integer.MAX_VALUE)
tab = Frame(self.resultsTabs)
resultsLabel = Label(tab, text="{} => {} results".format(queryText, len(docs.scoreDocs)))
resultsLabel.grid(row=0, column=0, sticky='ew')
htmlText = HtmlFrame(tab, vertical_scrollbar="auto")
htmlText.grid(row=1, column=0, sticky='nesw')
html = "<html>"
doc = searcher.doc(docs.scoreDocs[0].doc)
html += "<h2>Title: {}</h2></br>".format(doc.getField("title").stringValue())
#html += "<h4>Abstract: {}</h4></br>".format(doc.getField("abstract").stringValue())
html += "</html>"
htmlText.set_content(html)
self.resultsTabs.add(tab, text=str(len(docs.scoreDocs)))
search = Button(queryFrame, text='Search', command=search_btn)
search.grid(row=3, column=0, columnspan=3, sticky='ew')
queryFrame.grid_rowconfigure(0, weight=0)
queryFrame.grid_rowconfigure(1, weight=0)
queryFrame.grid_rowconfigure(2, weight=1)
queryFrame.grid_rowconfigure(3, weight=0)
queryFrame.grid_columnconfigure(0, weight=1)
queryFrame.grid_columnconfigure(1, weight=1)
queryFrame.grid_columnconfigure(2, weight=1)
def closeResults(self):
self.resultsTabs.forget(self.resultsTabs.index('current'))
ScrollText.py
from tkinter import *
from tkinter.ttk import *
class ScrollText(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.text = Text(self)
self.text.grid(row=0, column=0, sticky='nesw')
yscroll = Scrollbar(self, orient=VERTICAL, command=self.text.yview)
yscroll.grid(row=0, column=1, sticky='nesw')
self.text.configure(yscrollcommand=yscroll.set)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=0)
Я тоже рад получить общий совет Python. У меня нет большого опыта создания приложений Python, которые включают более одного файла / класса, поэтому я уверен, что делаю много чего неправильно (особенно уверен, что я неправильно делю подклассы ).
Спасибо.