如何在 tkinter 中动态创建选项卡

时间:2021-05-15 06:13:01

标签: python-3.x tkinter

我创建了一个菜单栏,其中包含打开、编辑等选项。打开的下拉菜单说打开文件,保存文件和另存为。 我想以这样的方式设计 GUI,当单击打开并选择文件时,我希望文件内容显示在新选项卡中,当我单击另一个选项时,我希望它显示在另一个选项卡中。 有人可以帮我解决这个问题吗? enter image description here

    from tkinter import *
from tkinter import filedialog
from tkinter import font
from xml.dom.minidom import parseString
from tkinter import ttk
import subprocess
import os

root = Tk()
root.title('Text-Editor')
root.resizable(width=True, height=True)
root.geometry("1400x660")



def new_file():
    my_text.delete("1.0",END)
    root.title('New File - TextEditor')
    status_bar.config(text="New File        ")

def open_file():
    my_text.delete("1.0",END)
    text_file = filedialog.askopenfilename(initialdir = "/",title="Open file" , filetypes = (("APK Files","*.apk"),("all files","*.*")))
    name=text_file
    status_bar.config(text=f'{name}       ')
    name = name.replace("/", "")
    root.title(f'{name}-TextEditor')
    text_file = open(text_file,'r')
    stuff = text_file.read()
    my_text.insert(END , stuff)
    text_file.close()


def save_as_file():
    text_file = filedialog.asksaveasfilename(defaultextension=".*",initialdir="/",title="Save file",filetypes=(("Text files",".txt"),("All files",".*.*")))
    if text_file:
        name = text_file
        name = name.replace("/","")
        root.title(f'{name} Saved1-TextEditor')

        text_file = open(text_file,'w')
        text_file.write(my_text.get(1.0, END))

        text_file.close()


def get_path(p):
    p = p.split(".")
    p.pop()
    return ''.join(p)


apk_path = filedialog.askopenfilename(initialdir="/",title = "Disassembling", filetypes=(("APK files","*.apk"),("All files","*.apk")))
gpath = get_path(apk_path) + "/AndroidManifest.xml"


def dis_file():
    
    subprocess.run(["apktool","d",apk_path])
    b = str(apkname(apk_path))
    command = "ls " + b + " >" + " a.txt"
    os.system(command)
    os.system("pwd > path.txt")
    file()
    

    
def perm_file():
    tab1 = ttk.Frame(tabcontrol)
    tabcontrol.add(tab1 , text = "Permissions")
    tabcontrol.pack(fill = "both" , expand = 1)
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('uses-permission')
    l = Listbox(tab1,height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    co = 0
    for c,node in enumerate(nodes):
        co+=1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of Permissions : {co}')

    l.pack()


def apkname(a):
    a = a.split("/")
    a = a[-1].split(".")
    return a[0]

def act_file():
    tab2 = ttk.Frame(tabcontrol)
    tabcontrol.add(tab2 , text = "Activity Names")
    tabcontrol.pack(fill = "both" , expand = 1)
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('activity')
    l = Listbox(tab2, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    co = 0
    for c,node in enumerate(nodes):
        co += 1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of Activities : {co}')
    l.pack()

def inte_file():
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('action')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    co = 0
    for c,node in enumerate(nodes):
        co += 1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of Intent Actions : {co}')
    l.pack()

def intent_cat():
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('category')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    co = 0
    for c,node in enumerate(nodes):
        co += 1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of Intents Categories : {co}')
    l.pack()

def serv_file():
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('service')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    co = 0
    for c,node in enumerate(nodes):
        co += 1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of Services : {co}')
    l.pack()

def prov_file():
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('provider')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    co = 0
    for c,node in enumerate(nodes):
        co += 1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of providers : {co}')
    l.pack()

def recv_file():
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('receiver')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    co = 0
    for c,node in enumerate(nodes):
        co += 1
        l.insert(c,node.getAttribute('android:name'))
    l.insert(0,f'Number of Receivers : {co}')
    l.pack()

def app_file():
    with open(gpath,'r') as f:
        data = f.read()
    dom = parseString(data)
    nodes = dom.getElementsByTagName('manifest')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    co = 0
    for node in nodes:
        co += 1
        l.insert(1,f'Package Name:{node.getAttribute("package")}')
        l.insert(2,f'compileSdkVersion:{node.getAttribute("android:compileSdkVersion")}')
        l.insert(3,f'compileSdkVersionCodename:{node.getAttribute("android:compileSdkVersionCodename")}')
        l.insert(4,f'XMLNS:{node.getAttribute("xmlns:android")}')
        l.insert(5,f'platformBuildVersionCode:{node.getAttribute("platformBuildVersionCode")}')
        l.insert(6,f'platformBuildVersionName:{node.getAttribute("platformBuildVersionName")}')

    l.insert(0,f'Count = {co}')
    l.pack()

def file():
    with open('/home/prajwal/Downloads/a.txt','r') as f:
        data = f.read()
    a = data.split('\n')
    top = Toplevel()
    l = Listbox(top, height=600,
        width=650,
        bg = "grey",
        activestyle="dotbox",
        font="Arial",
        fg="black")
    top.geometry("700x250")
    l.insert(0,"Extracted Files:")
    for c,i in enumerate(a):
        l.insert(c+1,i) 
    l.pack()

my_frame = Frame(root)
my_frame.pack(pady=3)

tabcontrol = ttk.Notebook(my_frame)

text_scroll = Scrollbar(root)
text_scroll.pack(side=RIGHT , fill=Y)

my_text = Text(root , font=("Arial", 16), selectbackground="yellow", selectforeground="black", undo=True, yscrollcommand=text_scroll.set)
my_text.pack(fill=BOTH , expand=1)

text_scroll.config(command=my_text.yview)

my_menu = Menu(root)
root.config(menu=my_menu)

file_menu = Menu(my_menu , tearoff = False)
my_menu.add_cascade(label="File" , menu = file_menu)
file_menu.add_command(label="New",command=new_file) 
file_menu.add_command(label="Open",command=open_file)
file_menu.add_command(label="Save")
file_menu.add_command(label="Save As",command=save_as_file)
file_menu.add_separator()
file_menu.add_command(label="Exit", command = root.quit)

edit_menu = Menu(my_menu , tearoff=False)
my_menu.add_cascade(label="Edit" , menu = edit_menu)
edit_menu.add_command(label="Cut")
edit_menu.add_command(label="Copy")
edit_menu.add_command(label="Paste")
edit_menu.add_command(label="Undo")
edit_menu.add_command(label="Redo")

dis_menu = Menu(my_menu , tearoff = False)
my_menu.add_cascade(label = "APK",menu=dis_menu)
dis_menu.add_command(label = "Disassemble", command = dis_file)
dis_menu.add_command(label = "Show Permissions", command = perm_file)
dis_menu.add_command(label = "Show Activity Names", command = act_file)
dis_menu.add_command(label = "Show Intents", command = inte_file)
dis_menu.add_command(label = "Show Intent Category", command = intent_cat)
dis_menu.add_command(label = "Show Services", command = serv_file)
dis_menu.add_command(label = "Show Providers", command = prov_file)
dis_menu.add_command(label = "Show Recievers", command = recv_file)
dis_menu.add_command(label = "Show App Info", command = app_file)

status_bar = Label(root, text='Ready        ', anchor = E)
status_bar.pack(fill=X ,side=BOTTOM , ipady =5)
root.mainloop() 

2 个答案:

答案 0 :(得分:1)

看看这段代码:

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog


class Tab:
    def __init__(self, notebook:ttk.Notebook):
        self.filename = None
        self.notebook = notebook

        self.text_widget = tk.Text(self.notebook)
        self.text_widget.bind("<Control-o>", self.open)
        self.text_widget.bind("<Control-s>", self.save)
        self.text_widget.bind("<Control-Shift-S>", self.saveas)
        self.notebook.add(self.text_widget, text="The tab name")

    def open(self, _=None):
        filename = filedialog.askopenfilename()
        if filename != "":
            with open(filename, "r") as file:
                data = file.read()
            self.text_widget.delete("0.0", "end")
            self.text_widget.insert("end", data)
            self.filename = filename
        return "break"

    def save(self, _=None):
        if self.filename is None:
            self.saveas()
        else:
            self._save()
        return "break"

    def saveas(self, _=None):
        filename = filedialog.asksaveasfilename()
        if filename == "":
            return "break"
        self.filename = filename
        self._save()

    def _save(self):
        assert self.filename is not None, "self.filename shouldn't be None"
        data = self.text_widget.get("0.0", "end")
        with open(self.filename, "w") as file:
            file.write(data)


class App:
    def __init__(self):
        self.root = tk.Tk()
        self.new_tab_button = tk.Button(self.root, text="New tab", command=self.add_new_tab)
        self.new_tab_button.pack()
        self.open_button = tk.Button(self.root, text="Open file", command=self.open_file)
        self.open_button.pack()
        self.save_button = tk.Button(self.root, text="Save file", command=self.save_file)
        self.save_button.pack()
        self.notebook = ttk.Notebook(self.root)
        self.notebook.pack()
        self.tabs = []

    def add_new_tab(self):
        tab = Tab(self.notebook)
        self.tabs.append(tab)

    def get_current_tab(self):
        # This code gets the currently selected tab
        idx = self.notebook.index(self.notebook.select())
        tab = self.tabs[idx]
        return tab

    def open_file(self):
        tab = self.get_current_tab()
        tab.open() # Call `open` on the tab

    def save_file(self):
        tab = self.get_current_tab()
        tab.save() # Call `save` on the tab

    def mainloop(self):
        self.root.mainloop()


if __name__ == "__main__":
    app = App()
    app.mainloop()

它会创建一个 App 对象,每次按下 Tab 按钮时都会创建新的 "New tab" 对象。它还支持打开文件。添加其余功能应该很容易。

答案 1 :(得分:1)

这是您想要的代码吗(简单示例):

from tkinter import Tk, Menu, Text
from tkinter.ttk import Notebook
from tkinter.filedialog import askopenfile


text_list = []


def add_tab(parent, contents, name):
    text = Text()
    text_list.append(text)
    text = text_list[len(text_list) - 1]
    
    parent.add(text, text=name)
    text.insert('end', contents)


def open_file():
    file = askopenfile(filetypes=[('Text file', '*.txt')])

    if file:
        add_tab(notebook, file.read(), file.name.split('/')[-1])


root = Tk()

menu_bar = Menu(root)

file_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='File', menu=file_menu)
file_menu.add_command(label='Open', command=open_file)

root.config(menu=menu_bar)

notebook = Notebook(width=700, height=500)
notebook.pack()

root.mainloop()

对此没什么好说的,唯一要补充的是,在使用选项卡和文本时,您需要以某种方式存储文本小部件的索引,以便您始终可以访问它(以对该特定文本小部件执行操作)(我可以说这并不容易)但到目前为止,这有效并且符合您的要求。

来源:

相关问题