TK-GUI设计问题和对象没有属性'TK'?

2024-04-29 04:08:35 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是我目前拥有的代码。我是初学者程序员,正在写一个小程序,将自动化一些初级设计的工作流程(生物学家/生物信息学家代表)。在

我现在的问题是我对OOP如何与TKinter一起工作缺乏理解。但我还是在youtube上看了很多相关的文章,我还是看了很多视频。我目前的理解是,每个窗口都应该是自己的对象,上面的窗口是其父对象。我试着用我的程序来做这个。 目前我有两个类,AUTOPRIMER和BlastAPI。自动驾驶仪是主窗口。在我创建的窗口中有一个按钮,当单击时会打开一个新窗口。据我所知,我为这个窗口创建了一个新的对象,名为BlastAPI,它处理我程序的特定需求。我看到很多指南建议将父对象放在新对象的init中,但是我看到了从父对象到主对象再到args*,kwargs**的初始化变化。什么时候合适?另外,目前堆栈跟踪提供了这种反馈,因为它甚至不能正确编译。在

Traceback (most recent call last):
  File "/Users/Thunderpurtz/Desktop/CGIStuff/AUTOPRIMER/autoprimercode/test1.py", line 201, in <module>
    autoprimer = AUTOPRIMER(root)
  File "/Users/Thunderpurtz/Desktop/CGIStuff/AUTOPRIMER/autoprimercode/test1.py", line 105, in __init__
    self.blast = BlastAPI(self)
  File "/Users/Thunderpurtz/Desktop/CGIStuff/AUTOPRIMER/autoprimercode/test1.py", line 150, in __init__
    eValueSetting = Entry(parent)
  File "/anaconda3/lib/python3.6/tkinter/__init__.py", line 2673, in __init__
    Widget.__init__(self, master, 'entry', cnf, kw)
  File "/anaconda3/lib/python3.6/tkinter/__init__.py", line 2289, in __init__
    BaseWidget._setup(self, master, cnf)
  File "/anaconda3/lib/python3.6/tkinter/__init__.py", line 2259, in _setup
    self.tk = master.tk
AttributeError: 'AUTOPRIMER' object has no attribute 'tk'
[Finished in 0.289s]

从根本上说,我认为我对gui编程的理解并不扎实,所以如果有人能提供一些见解,那就太好了。如果这个问题有点宽泛,我很乐意在评论中澄清。在

^{pr2}$

谢谢各位。在


Tags: 对象inpyself程序initlineusers
1条回答
网友
1楼 · 发布于 2024-04-29 04:08:35

好吧,这里有很多工作要做。我想丢失的部分是主代码的一部分,但是没有它们测试代码是不可能的。我尽我所能,设置你的类从它们需要的tkinter对象继承。根据您在BlastAPI类中的按钮命令,我假设这个类应该是一个Toplevel()窗口。在

我已经对您的代码做了一些更改,而且没有Bio.Blast我已经将一些事情更改为我认为您可能需要做的事情。在

import subprocess
import tkinter as tk # import tkinter as tk is good for compatibility and maintainability. Don't use *
from tkinter.filedialog import *
import tkinter.messagebox
from Bio.Blast import NCBIWWW
from Bio.Blast import NCBIXML

class AutoPrimer(tk.Tk): # Class names should normally use the CapWords convention.
    def __init__(self):
        #initialization
        tk.Tk.__init__(self)
        self.title("Complete Genomics Inc.")
        self.input = ""
        self.output = ""
        self.param = ""
        self.inputbool = False
        self.outputbool = False
        self.parambool = False
        self.p3filestring = '-p3_settings_file='


        self.entry_input = tk.Entry(self)
        self.entry_output = tk.Entry(self)
        self.entry_parameters = tk.Entry(self)
        self.entry_input.grid(row=1, column=1, padx=1, pady=1, sticky="w")
        self.entry_output.grid(row=2, column=1, padx=1, pady=1, sticky="w")
        self.entry_parameters.grid(row=3, column=1, padx=1, pady=1, sticky="w")

        self.label1 = tk.Label(self, text="AUTOPRIMER").grid(row=0, columnspan=4)
        tk.Button(self, text="Input Filepath: ", command=lambda: self.button1).grid(row=1, padx=1, pady=1, sticky="e")
        tk.Button(self, text="Output Filepath: ", command=lambda: self.button2).grid(row=2, padx=1, pady=1, sticky="e")
        tk.Button(self, text="Parameters Filepath: ", command=lambda: self.button3).grid(row=3, padx=1, pady=1, sticky="e")
        tk.Button(self, text="Get Primers",).grid(row=4)
        tk.Button(self, text="Parse Primers",).grid(row=4, column=1, sticky="w")
        tk.Button(self, text="Pool Primers",).grid(row=4, column=2, sticky="w")
        tk.Button(self, text="Blast Primers", command=lambda: BlastAPI(self)).grid(row=4, column=3, sticky="w")
        tk.Button(self, text="Quit", command=self.destroy).grid(row=4, column=4, sticky="w")

        #CLASS METHODS
        #Series of buttons methods that take in the filepath and displays it in the text widget to the user

    def button1(self):
        self.entry_input.delete(0,END)
        ifp = askopenfilename()
        self.setInput(ifp)
        self.entry_input.insert(0, ifp)
        self.setInputBool(True)
    def button2(self):
        self.entry_output.delete(0,END)
        ofp = asksavefilename()
        self.setOutput(ofp)
        self.entry_output.insert(0, ofp)
        self.setOutputBool(True)
    def button3(self):
        self.entry_parameters.delete(0,END)
        pfp = askopenfilename()
        self.entry_parameters.insert(0, pfp)
        self.setParameterBool(True)

    #Methods that rely on class attributes after using above buttons to set
    def get_primers(self):
        pass
    def primer_parser(self):
        pass
    def pool_primers(self):
        pass

    #Setters and Getters
    def setInput(self, value):
        self.input = value
    def setOutput(self, value):
        self.output = value
    def setParam(self, value):
        self.param = value
    def setInputBool(self, value):
        self.inputbool = value
    def setOutputBool(self, value):
        self.outputbool = value
    def setParameterBool(self, value):
        self.parambool = value




class BlastAPI(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.title('Complete Genomics Inc.')
        self.e_value_thresh = ""

        self.e_value_setting = tk.Entry(self)
        self.e_value_setting.pack() # Used pack here for quick testing. You will need to work on geometry yourself.
        tk.Button(self, text="Close", command=self.destroy).pack()
        tk.Button(self, text="Input file").pack()
        self.entry_field = tk.Entry(self)
        self.entry_field.pack()


    def blast_primers(self): # Nothing is calling this function in your example.
        filename = askopenfilename()
        with open(filename) as file:
            string = file.read() # string is not being used here.

        fasta = string # No such var name in code.
        result_handle = NCBIWWW.qblast("blastn", "nt", fasta) # This had a typo NCBIWW instead of NCBIWWW.

        with open("my_blast.xml", "w") as out_handle:
            out_handle.write(result_handle.read())
        result_handle.close()

        result_handle = open('my_blast.xml')
        self.blast_record = NCBIXML.parse(result_handle)
        evalue = 1 # Is not being used here.
        self.item = next(self.blast_record)
        self.e_value_thresh = self.e_value_setting.get()
        self.blast_write_loop()


    def blast_write_loop(self):
        # I don't really like while loops and they have problems in event based GUI's.
        # I don't think a while loop is needed here anyway.
        with open('BlastResults.txt', 'w') as blast:
            try:
                for alignment in self.item.alignments:
                    for hsp in alignment.hsps:
                        if hsp.expect < self.e_value_thresh:
                            blast.write("****Alignment****")
                            blast.write("sequence:", alignment.title)
                            blast.write("length:", alignment.length)
                            blast.write("e value:", hsp.expect)
                            blast.write(hsp.query[0:75] + "...")
                            blast.write(hsp.match[0:75] + "...")
                            blast.write(hsp.sbjct[0:75] + "...")
                self.item = next(self.blast_record)
            except StopIteration:
                print("Done!")


autoprimer = AutoPrimer()
autoprimer.mainloop()

相关问题 更多 >