【发布时间】:2015-05-15 15:08:27
【问题描述】:
我为实验室写了一个管道,所以我知道在 GUI 中插入“控制台”是不可能的,所以我用 Frame 做了它并在上面贴上了标签。
但问题是,我是线程的初学者,在循环执行函数后,我不知道如何使用它将标签放入我的框架中。
这是我的代码(python 3.x):
########
# IMPORTS #
########
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import *
from tkinter.messagebox import *
import os
import glob
from datetime import date, time, datetime
#########
# FUNCTION #
#########
def OneFile(path1,DB,path2,seq,seq2,typ,path3):
"""
This function is very long, take all the sequences of the input file and BLAST it to the Library DATABASE
path : path to the library databse
DB : library database name
path2 : path of the file with the query sequences
seq : name of the file with the query sequences append with a job ID
seq2 : name of the file with the query sequence
Typ : Nucleotide or Proteine
"""
from datetime import date, time, datetime
import subprocess
import platform
import time
OS = platform.system()
if OS == 'Linux' or OS == 'Darwin':
pathLibrary = path1+'/'
pathSequence = path2+'/'
pathFolder = path3+'/'
if OS == 'Windows':
pathLibrary = path1+'\\'
pathSequence = path2+'\\'
if typ not in [(1,1),(2,2),(1,2),(2,1)]:
showerror('Error : Missing Type !', "You do not choose your type\n(nucleotides or proteins)")
else:
library = DB
if os.path.isfile(pathLibrary+library) != True:
showerror('Error : Missing File !', "You must choose a Library Database file")
else:
if os.path.isfile(pathSequence+seq2) != True:
showerror('Error : Missing File !', "You must choose your sequence file")
else:
if typ == (1,1):
typ = "blastn"
if typ == (2,2):
typ = "blastp"
if typ == (1,2):
typ = "blastx"
if typ == (2,1):
typ = "tblastn"
if OS == 'Linux' or OS == 'Darwin':
t0 = time.time()
query = str(seq2)
blast = str(seq)+'_Blast.txt'
seqs = str(seq)+'_seqs.txt'
subprocess.call(typ+" -query "+pathSequence+query+" -db "+pathLibrary+library+" -evalue 1e-10 -out "+pathFolder+blast, shell=True)
subprocess.call("grep '\(Sbjct\|>\)' "+pathFolder+blast+" > "+pathFolder+seqs, shell=True)
t1 = time.time()
print('Job finish in '+str(round(t1-t0,2))+' seconds')
if OS == 'Windows':
t0 = time.time()
query = str(seq2)
blast = str(seq)+'_Blast.txt'
seqs = str(seq)+'_seqs.txt'
subprocess.call(typ+' -query '+pathSequence+query+' -db '+pathLibrary+library+' -evalue 1e-10 -out '+pathSequence+blast, shell=True)
print('Fichier n° '+str(1)+' '+str(seq2))
subprocess.Popen('findstr "Sbjct >" '+pathSequence+blast+' > '+pathSequence+seqs, shell=True)
t1 = time.time()
print('Job finish in '+str(round(t1-t0,2))+' seconds')
#######
# CLASS #
#######
class GraphicalUserInterface():
#principal application
def __init__(self):
#constructor
self.fen = Tk()
self.fen.title("Starch Enzyme Pipeline")
#first label
self.label1 = Label(self.fen, text="Folder with your set(s) : ")
self.label1.grid(row=0, columnspan=2, sticky="W")
#first button
self.browse1 = Button(self.fen)
self.browse1.config(text="Browse",command=self.folderPath)
self.browse1.grid(row=1,column=0, sticky="W")
#label to show the path
self.varLabel1 = StringVar()
self.pathLabel1 = Label(self.fen, textvariable=self.varLabel1, relief=SUNKEN)
self.pathLabel1.grid(row=1,column=1, sticky="EW")
#second title
self.label2 = Label(self.fen, text="Folder with your library database(s) ")
self.label2.grid(row=2,column = 0, columnspan=2 , sticky="W")
#second button
self.browse2 = Button(self.fen)
self.browse2.config(text="Browse",command=self.folderPath2)
self.browse2.grid(row=3,column=0, sticky="W")
#label to show the path for database
self.varLabel2 = StringVar()
self.pathLabel2 = Label(self.fen, textvariable=self.varLabel2, relief=SUNKEN)
self.pathLabel2.grid(row=3,column=1, sticky = "EW")
#Frame wrappe listBox and other
self.frameListBoxAll = Frame(self.fen)
self.frameListBoxAll.grid(row=6,columnspan=2)
#list box label
self.labListBox1 = Label(self.frameListBoxAll, text="Your sets :",padx=10)
self.labListBox1.grid(row=0,column=0)
self.labListBox2 = Label(self.frameListBoxAll, text="Your library database :",padx=10)
self.labListBox2.grid(row=0,column=1)
#frame with listbox1
self.frame1 = Frame(self.frameListBoxAll, bd=2, relief=SUNKEN)
self.frame1.grid(row=1,column=0)
#frame with listbox1
self.frame2 = Frame(self.frameListBoxAll, bd=2, relief=SUNKEN)
self.frame2.grid(row=1,column=1)
#scrollbar listbox1
self.scrollbar1 = Scrollbar(self.frame1)
self.scrollbar1.grid(row=0,column=1, sticky="NS")
self.scrollbar2 = Scrollbar(self.frame2)
self.scrollbar2.grid(row=0,column=3, sticky="NS")
self.scrollbar3 = Scrollbar(self.frame1, orient=HORIZONTAL)
self.scrollbar3.grid(row=1,column=0, sticky="WE")
self.scrollbar4 = Scrollbar(self.frame2, orient=HORIZONTAL)
self.scrollbar4.grid(row=1,column=2, sticky="WE")
#liste box
self.listeBox1 = Listbox(self.frame1, selectmode=EXTENDED, exportselection=0, yscrollcommand=self.scrollbar1.set, xscrollcommand=self.scrollbar3.set)
self.listeBox1.grid(row=0,column = 0)
self.scrollbar1.config(command=self.listeBox1.yview)
self.scrollbar3.config(command=self.listeBox1.xview)
#liste box2
self.listeBox2 = Listbox(self.frame2, selectmode=EXTENDED, exportselection=0, yscrollcommand=self.scrollbar2.set, xscrollcommand=self.scrollbar4.set)
self.listeBox2.grid(row=0,column = 2)
self.scrollbar2.config(command=self.listeBox2.yview)
self.scrollbar4.config(command=self.listeBox2.xview)
#radioboutton list box 1
self.var = IntVar()
for item in [1,2]:
if item == 1:
self.rb = Radiobutton(self.frameListBoxAll, text='Nucleotides',value=item,variable=self.var)
self.rb.grid(row=2, column=0)
if item == 2:
self.rb = Radiobutton(self.frameListBoxAll, text='Proteins',value=item,variable=self.var)
self.rb.grid(row=3, column=0)
#radioboutton list box 2
self.var2 = IntVar()
for item in [1,2]:
if item == 1:
self.rb2 = Radiobutton(self.frameListBoxAll, text='Nucleotides',value=item,variable=self.var2)
self.rb2.grid(row=2, column=1)
if item == 2:
self.rb2 = Radiobutton(self.frameListBoxAll, text='Proteins',value=item,variable=self.var2)
self.rb2.grid(row=3, column=1)
#variables
self.path1 = str()
self.path2 = str()
self.path3 = str()
#RUN Buttun
self.runbutton = Button(self.fen, text="RUN",command=self.start_foo_thread).grid(row=7,column=0,columnspan=2)
#FRAME CONSOLE
self.console = Frame(self.fen)
self.console.config(relief=SUNKEN, bg="black", height=200, width=400)
self.console.grid(row=8, columnspan=10)
self.console.grid_propagate(False) #to block the size of the frame
#QUIT BUTTON
self.quitButton = Button(self.fen)
self.quitButton.config(text="QUIT", command=self.fen.destroy)
self.quitButton.grid(row=100,column=0)
def folderPath(self):
path = askdirectory(title='Choose your set folder')
self.varLabel1.set(path)
self.listeBox1.delete(0, END)
for filename in sorted(glob.glob(path+'/*')):
if os.path.isfile(filename):
#stockage of path
self.path1 = os.path.split(filename)[0]
name = os.path.split(filename)[1]
self.listeBox1.insert(END, name)
def folderPath2(self):
path = askdirectory(title="Choose your library database folder")
self.varLabel2.set(path)
self.listeBox2.delete(0, END)
for filename in sorted(glob.glob(path+'/*')):
if os.path.isfile(filename):
#stockage of path
self.path2 = os.path.split(filename)[0]
name = os.path.split(filename)[1]
self.listeBox2.insert(END, name)
def run(self):
self.fen.mainloop()
def createJobName():
job = str(datetime.now())
job = job.replace(" ","-")
return job
def typeNP(self):
liste = []
#selection of query files
valListBox1 = [self.listeBox1.get(idx) for idx in self.listeBox1.curselection()]
#selection of database file
valListBox2 = [self.listeBox2.get(idx) for idx in self.listeBox2.curselection()]
#selection of sequence type
typ = (self.var.get(),self.var2.get())
# loop
for i in range(len(valListBox2)):
job = GraphicalUserInterface.createJobName()
path1 = self.path2
path2 = self.path1
DB = valListBox2[i]
path3 = os.getcwd()+"/"+DB+job
if os.path.isdir(DB+job) == True:
showwarning('Warning', "The folder already exist \n or they are no folder name !\nChange or get the folder name")
else:
os.mkdir(DB+job)
for filename in valListBox1:
seq = filename+job
seq2 = filename
#stock data for OneFile function
liste.append([path1,DB,path2,seq,seq2,typ,path3])
return liste
def start_foo_thread(self):
liste = self.typeNP()
for i in range(len(liste)):
global foo_thread
import threading
print('Fichier n°'+str(i+1)+' '+str(liste[i][4]))
stringLabel = Label(self.console,text='Fichier n°'+str(i+1)+' '+str(liste[i][4]),bg='black', fg='white')
stringLabel.grid(row=i,sticky="W")
foo_thread = threading.Thread(target=OneFile(liste[i][0],liste[i][1],liste[i][2],liste[i][3],liste[i][4],liste[i][5],liste[i][6]))
foo_thread.daemon = True
foo_thread.start()
#########
# AUTORUN #
#########
if __name__ == '__main__':
app = GraphicalUserInterface()
app.run()
问题是循环开始的时间:
def start_foo_thread(self):
liste = self.typeNP()
for i in range(len(liste)):
使用打印功能,我看到该功能运行,但迭代完成时标签没有进入框架。循环完成后,我会在框架中看到我的标签。 在我的函数在我的循环中运行的同时,将我的标签放在我的框架中的正确代码是什么?
【问题讨论】:
-
阅读量很大。请创建一个MCVE。
-
您不能从创建它们的线程以外的任何线程访问 tkinter 小部件。通过在此站点上搜索
[tkinter] threading进行更多研究。这是一个复杂的主题,可能会使您的问题过于宽泛。 -
非常感谢您的建议,问候 yoan
标签: python multithreading tkinter