コード例 #1
0
class GuiConsole(Frame):
    def __init__(self, master=None, cnf={}, **kw):
        super(GuiConsole, self).__init__(master, cnf, **kw)
        self.pack(fill=BOTH, expand=YES)
        self.console = ScrolledText(self, font=('Source Code Pro', 12, 'normal'))
        self.console.pack(side=TOP, fill=BOTH, expand=YES, padx=5, pady=5)
        self.console.focus()
        self.console.mark_set(INSERT, '1.0')

    def clear(self):
        self.console.delete('1.0', END)

    def write(self, text):
        text = '{}'.format(text)
        self.console.insert(INSERT, text)
        self.console.mark_set(INSERT, INSERT+'+{}c'.format(len(text)))

    def writeline(self, text):
        self.write('{}\n'.format(text))

    def writelines(self, lines):
        for line in lines:
            self.writeline(line)

    def read(self):
        pass
コード例 #2
0
class TextEditor():                     # see PyEdit for more
    def __init__(self, parent=None):
        # TODO: 1226 why This can generate independent window ?
        #frm=Toplevel(Frame.__init__(self, parent))
        frm=Toplevel()
        # TODO : assign title based on cmdline tag 
        frm.title('New Text')
        # TODO , how to make button and Text in a better Layout format ?
        #        grid() param to learn 
        Button(frm, text='Save',  command=self.onSave).grid(row=0,column=0)
        Button(frm, text='Cut',   command=self.onCut).grid(row=0,column=1)
        Button(frm, text='Paste', command=self.onPaste).grid(row=0,column=2)
        Button(frm, text='Find',  command=self.onFind).grid(row=0,column=3)
        self.text = ScrolledText(frm)
        self.text.grid(row=1,columnspan=4)

        #Button(self, text='Save',  command=self.onSave).grid()
        #Button(self, text='Cut',   command=self.onCut).grid()
        #Button(self, text='Paste', command=self.onPaste).grid()
        #Button(self, text='Find',  command=self.onFind).grid()
        #self.text = ScrolledText(self)

    def gettext(self):                                   # returns a string
        return self.text.get('1.0', END+'-1c')           # first through last

    def onSave(self):
        filename = asksaveasfilename()
        #print(filename)
        if filename:
            alltext = self.gettext()                      # first through last
            open(filename, 'w').write(alltext)            # store text in file

    def onCut(self):
        text = self.text.get(SEL_FIRST, SEL_LAST)         # error if no select
        self.text.delete(SEL_FIRST, SEL_LAST)             # should wrap in try
        self.text.clipboard_clear()
        self.text.clipboard_append(text)

    def onPaste(self):                                    # add clipboard text
        try:
            text = self.text.selection_get(selection='CLIPBOARD')
            self.text.insert(INSERT, text)
        except TclError:
            pass                                          # not to be pasted

    def onFind(self):
        target = askstring('SimpleEditor', 'Search String?')
        if target:
            where = self.text.search(target, INSERT, END)  # from insert cursor
            if where:                                      # returns an index
                print(where)
                pastit = where + ('+%dc' % len(target))    # index past target
               #self.text.tag_remove(SEL, '1.0', END)      # remove selection
                self.text.tag_add(SEL, where, pastit)      # select found target
                self.text.mark_set(INSERT, pastit)         # set insert mark
                self.text.see(INSERT)                      # scroll display
                self.text.focus()                          # select text widget
コード例 #3
0
ファイル: console_ui.py プロジェクト: TobyBoyne/py-toolkit
class ConsoleUi:
	"""Poll messages from a logging queue and display them in a scrolled text widget"""
	def __init__(self, frame):
		self.frame = frame
		self.input_start_idx = tk.END
		# Create a ScrolledText wdiget
		self.scrolled_text = ScrolledText(frame, state='disabled', height=12)
		self.scrolled_text.pack(expand=True, fill=tk.BOTH)
		self.scrolled_text.configure(font='TkFixedFont')
		self.scrolled_text.tag_config('INFO',     foreground='black')
		self.scrolled_text.tag_config('DEBUG',    foreground='gray')
		self.scrolled_text.tag_config('WARNING',  foreground='dark orange')
		self.scrolled_text.tag_config('ERROR',    foreground='red')
		self.scrolled_text.tag_config('CRITICAL', foreground='red', underline=1)

		self.scrolled_text.bind('<Key>', self.key_press)

		# Create a logging handler using a queue
		self.log_queue = queue.Queue()
		self.queue_handler = QueueHandler(self.log_queue)
		formatter = logging.Formatter('%(asctime)s:\t%(message)s', datefmt='%H:%M:%S')
		self.queue_handler.setFormatter(formatter)
		logger.addHandler(self.queue_handler)
		# Start polling messages from the queue
		self.frame.after(100, self.poll_log_queue)

	def display(self, record):
		msg = record.getMessage()
		self.scrolled_text.configure(state='normal')
		self.scrolled_text.insert(tk.END, msg + '\n', record.levelname)
		# self.scrolled_text.configure(state='disabled')
		# Autoscroll to the bottom
		self.scrolled_text.yview(tk.END)

		self.scrolled_text.mark_set('input_start', 'end-1c')
		self.scrolled_text.mark_gravity('input_start', tk.LEFT)

	def poll_log_queue(self):
		while True:
			try:
				record = self.log_queue.get(block=False)
			except queue.Empty:
				break
			else:
				self.display(record)

		# Check every 100ms if there is a new message in the queue to display
		self.frame.after(100, self.poll_log_queue)

	def key_press(self, event):
		"""Function used to send any inputs to the input_queue when the return key is pressed"""
		if event.char == '\r':
			user_input = self.scrolled_text.get('input_start', 'end-1c').strip()
			input_queue.put(user_input)
			self.scrolled_text.mark_set('input_start', 'end-1c')
コード例 #4
0
class SummaryFrame(Observer, FrameBase):
    def _init_frame(self):
        # ROW 0
        self.title = tk.Label(self,
                              text='Summary',
                              font=self.root_frame.font_title)
        self.title.grid(column=0,
                        row=0,
                        columnspan=2,
                        sticky='w',
                        padx=4,
                        pady=4)

        # ROW 1
        self.receipt = ScrolledText(self)
        self.receipt.grid(column=0,
                          row=1,
                          columnspan=6,
                          sticky='nsew',
                          padx=2,
                          pady=2)
        self.receipt.bind("<FocusIn>", self._select_all)
        self.receipt.bind("<Control-a>", self._select_all)

        self.assign_subject(OrderController().last_order)

        # ROW 2
        self.clipboard_button = tk.Button(self,
                                          text='Copy to clipboard',
                                          command=self._copy_to_clipboard)
        self.clipboard_button.grid(column=0, row=2, sticky='e', padx=2, pady=2)

        self.save_button = tk.Button(self,
                                     text='Save receipt',
                                     command=self._save_receipt)
        self.save_button.grid(column=1, row=2, sticky='e', padx=2, pady=2)

        self.next_button = tk.Button(self,
                                     text='Finish',
                                     command=self.goto_home)
        self.next_button.grid(column=5, row=2, sticky='e', padx=2, pady=2)

        self.columnconfigure(2, weight=1)
        # self.columnconfigure(4, minsize=30)
        self.rowconfigure(1, weight=1)

        self.configure(padx=2, pady=2)

    def _select_all(self, event):
        self.receipt.tag_add('sel', '1.0', 'end')
        self.receipt.mark_set('insert', '1.0')
        self.receipt.see('insert')
        return 'break'

    def _copy_to_clipboard(self):
        self.root_win.clipboard_clear()
        self.root_win.clipboard_append(self.subject.get_receipt())
        return 'break'

    def _save_receipt(self):
        filename = filedialog.asksaveasfilename(
            parent=self,
            title='Select where to save the receipt',
            filetypes=[('Plaintext file', '*.txt')],
        )
        if filename:
            self.subject.save_receipt(filename)

    def update_content(self):
        receipt = self.subject.get_receipt()
        # self.receipt.insert('1.0', 'LMAO\nhehehehheeheh\nbruuuuuuuuuuuuuu\nkek')
        self.receipt['state'] = 'normal'
        self.receipt.delete('1.0', 'end')
        self.receipt.insert('1.0', receipt)
        self.receipt['state'] = 'disabled'
        # self.receipt.insert('1.1', 'WUTBRUH')

    def goto_home(self):
        pass

    def _on_frame_destroy(self):
        pass
コード例 #5
0
ファイル: GUI.py プロジェクト: yogeshsinghgit/Tkinter-Notepad
class PyNote:
    def __init__(self,root):
        self.root = root
        self.root.title('Untitled - PyNote')
        self.root.configure( bg='lightgray')
        self.root.geometry('950x600')
        self.root.protocol("WM_DELETE_WINDOW", self.callback)
        self.root.minsize(width=700, height=400)

        # important stuffs ...
        self.font_style = ('arial',14)
        self.filename = None
        self.file_saved = True
        self.index=0

        # widgets ,........
        self.textarea = ScrolledText(self.root,font=self.font_style,undo=True, wrap = WORD)
        #self.textarea.bindtags(('Text','post-class-bindings', '.', 'all'))
        self.textarea.pack(fill=BOTH,expand=True)
        self.shortcut_binding()

        self.status = StringVar()
        self.pos = StringVar()

        self.status.set('PyNote - ({})'.format('Untitled File'))
        # important stuffs ...
        font_style = ('arial', 13)
        self.label = Label(self.root, textvariable=self.status, fg='black', bg='lightgray', anchor=SW, font=font_style)
        self.label.pack(side=LEFT,fill=BOTH)


        # cursor postion label...
        self.cursor_pos_lbl = Label(self.root, textvariable=self.pos, fg='black', bg='lightgray', anchor=NW, font=font_style)
        self.cursor_pos_lbl.pack(side=RIGHT)

        # code for popup menu bar ....
        # creating menu-bar ...
        self.m = Menu(root, tearoff=0)
        self.m.add_command(label="Refresh", command=self.refresh)
        self.m.add_command(label = "Select All",command=self.select_all)
        self.m.add_command(label="Cut", command=lambda: self.textarea.event_generate("<<Cut>>"))
        self.m.add_command(label="Copy", command=lambda: self.textarea.event_generate("<<Copy>>"))
        self.m.add_command(label = "Paste", command=lambda: self.textarea.event_generate("<<Paste>>"))
        self.m.add_command(label="Delete", command=lambda: self.textarea.delete(SEL_FIRST, SEL_LAST))
        self.m.add_command(label="Add Date/Time", command=self.add_time_date)

        # Calling functions and other class methods or creating objects ......
        self.menubar = Menubar(self)


    # function definations .................

    def set_title(self,name= None):
        if name:
            self.root.title(name + " - PyNote")
        else:
            self.root.title('Untitled - PyNote')



    def new_file(self, event = None):
        self.textarea.delete(1.0, END)
        # call the save command if any text is written on text area ..
        self.filename = None
        self.set_title()
        self.update_status('PyNote - ({})'.format('Untitled File'))


    def open_file(self, *args):
        self.filename = filedialog.askopenfilename( defaultextension = ".txt",
                                                    filetypes = [("All Files" , "*.*"),
                                                                 ("Text Files" , "*.txt"),
                                                                 ("Python Scripts" , "*.py"),
                                                                 ('HTML Docs.' , "*.html"),
                                                                 ("CSS Docs.","*.css")])
        if self.filename:
            self.textarea.delete(1.0,END)
            with open(self.filename , "r") as f :
                self.textarea.insert(1.0,f.read())
            self.update_status('File is Opened /  ' + self.filename)
        self.set_title(self.filename)





    def save_file(self, *args):
        if self.filename:
            try:
                textarea_data = self.textarea.get(1.0,END)
                with open(self.filename, 'w') as f:
                    f.write(textarea_data)
                self.update_status('File is Saved Again ')
                self.file_saved = True

            except Exception as e:
                messagebox.showerror('PyNote -Says ','Error Occurs '+ str(e))
        else:
            self.save_as_file()


    def save_as_file(self, *args):
        try:
            new_file = filedialog.asksaveasfilename(initialfile = 'Untitled.txt',
                                                    defaultextension=".txt",
                                                    filetypes=[("All Files", "*.*"),
                                                               ("Text Files", "*.txt"),
                                                               ("Python Scripts", "*.py"),
                                                               ('HTML Docs.', "*.html"),
                                                               ("CSS Docs.", "*.css")]
                                                    )
            textarea_data =  self.textarea.get(1.0,END)
            with open(new_file , 'w') as f:
                f.write(textarea_data)
            self.filename = new_file
            self.set_title(self.filename)
            self.file_saved = True
            self.update_status('File is Saved As '+ self.filename)
        except Exception as e:
            messagebox.showerror('PyNote -Says ','Error Occurs '+ str(e))


    def about_us(self):
        messagebox.showinfo('About - Us','''
        PyNote is a Text Editor which is looks like a Notepad \n
        PyNote is Build as a Demo Project for those Who are \n
        interested in building Awesome GUI Projects using Tkinter\n
        _________________________________________________________\n
        PyNote Developer : Yogesh Singh \n
        Build For : Dynamic Coding \n''')

    def about_pynote(self):
        messagebox.showinfo('About - PyNote','''
        Current Version : 0.0 \n
        ''')


    def shortcut_binding(self):
        self.textarea.bind('<Control-n>',self.new_file)
        self.textarea.bind('<Control-Key-o>',self.open_file)
        self.textarea.bind('<Control-s>',self.save_file)
        self.textarea.bind('<Control-S>',self.save_as_file)
        self.textarea.bind('<Control-q>',self.close_App)
        self.textarea.bind('<Key>', self.text_area_cursor)
        #self.textarea.bind('<KeyPress>', self.cursor_pos)

        self.root.bind("<Button-3>", self.do_popup)

    def do_popup(self, event):
        try:
            self.m.tk_popup(event.x_root, event.y_root)
        finally:
            self.m.grab_release()

    def find_word_window(self):
        top = Toplevel(self.root)
        top.geometry('400x130')
        top.title('PyNote - Find Text ')
        top.resizable(0,0)

        # important stuffs ...........
        find_var = StringVar()
        self.total_var =StringVar()

        # --------------------------find window widgets ----------------------
        self.find_entry = ttk.Entry(top,width=20,font=('times',12), textvariable = find_var)
        self.find_entry.focus_set()
        self.find_entry.bind('<Return>',self.find)
        self.find_entry.place(x=10,y=25)

        find_btn = Button(top,text='Find',width=10,bd=2,relief=RIDGE,command=self.find)
        find_btn.place(x=200,y=25)

        clear_btn = Button(top, text='Clear', width=10, bd=2, relief=RIDGE,command=lambda:find_var.set(''))
        clear_btn.place(x=300, y=25)

        self.total_world_count = Label(top,font=('arial',13,'bold'))
        self.total_world_count.place(x=20,y=80)

        top.mainloop()


    def find(self, *args):
        # remove tag 'found' from index 1 to END
        self.textarea.tag_remove('found', '1.0', END)

        # returns to widget currently in focus
        s = self.find_entry.get()

        if (s):
            idx = '1.0'
            self.count=0
            while 1:
                # searches for desried string from index 1
                idx = self.textarea.search(s, idx, nocase=1,
                                  stopindex=END)
                self.count +=1

                if not idx: break

                # last index sum of current index and
                # length of text
                lastidx = '% s+% dc' % (idx, len(s))

                # overwrite 'Found' at idx
                self.textarea.tag_add('found', idx, lastidx)
                idx = lastidx

            # mark located string as red
            self.textarea.tag_config('found', foreground='green', background='yellow')
            #self.textarea.focus_set()
            self.total_world_count['text'] = 'Total Word Count is : ' + str(self.count -1 )



    def refresh(self):

        self.textarea.tag_delete("found")


    def find_replace_window(self):
        top = Toplevel(self.root)
        top.geometry('400x130')
        top.title('PyNote - Find Text ')
        top.focus_force()
        top.resizable(0, 0)

        # important stuffs ...........
        find_var = StringVar()
        replace_var = StringVar()

        # --------------------------find replace window widgets ----------------------
        self.find_entry = ttk.Entry(top, width=20, font=('times', 12), textvariable=find_var)
        self.find_entry.focus_set()
        self.find_entry.bind('<Return>', self.find)
        self.find_entry.place(x=10, y=25)

        self.replace_entry = ttk.Entry(top, width=20, font=('times', 12), textvariable=replace_var)
        #self.replace_entry.focus_set()
        self.replace_entry.bind('<Return>', self.find_replace)
        self.replace_entry.place(x=10, y=60)

        find_btn = Button(top, text='Find', width=10, bd=2, relief=RIDGE, command=self.find)
        find_btn.place(x=200, y=25)

        replace_btn = Button(top, text='Replace', width=10, bd=2, relief=RIDGE,
                             command=self.find_replace)
        replace_btn.place(x=200, y=60)

        clear_btn = Button(top, text='Clear All', width=10,height=3, bd=2, relief=RIDGE, command=lambda: [find_var.set(''),replace_var.set('')])
        clear_btn.place(x=300, y=26)

        self.total_world_count = Label(top, text='',font=('arial', 13, 'bold'))
        self.total_world_count.place(x=20, y=100)

        top.mainloop()


    def find_replace(self, *args):
        find = self.find_entry.get()
        replace = self.replace_entry.get()

        if(find and replace):
            idx = '1.0'
            while 1:
                # searches for desired string from index 1
                idx = self.textarea.search(find, idx, nocase=1,
                                  stopindex=END)
                print(idx)
                if not idx: break

                # last index sum of current index and
                # length of text
                lastidx = '% s+% dc' % (idx, len(find))

                self.textarea.delete(idx, lastidx)
                self.textarea.insert(idx, replace)

                lastidx = '% s+% dc' % (idx, len(replace))

                # overwrite 'Found' at idx
                self.textarea.tag_add('found', idx, lastidx)
                idx = lastidx

            self.total_world_count['text'] = '" {} " is replaced with " {} "'.format(find,replace)
        self.replace_entry.focus_set()

    def close_App(self, *args):
        print(self.textarea.get(1.0,END))
        if self.textarea.get(1.0,END) != '' and self.file_saved == True:
            if messagebox.askyesno('PyNote Says','Do you really want to exit'):
                self.root.quit()
        else:
            val = messagebox.askyesnocancel('PyNote - Says', 'Save File Before Exit App. ')
            if val:
                self.save_file()
                self.root.destroy()
            elif val == False:
                self.root.destroy()

    def text_area_cursor(self, *args):
        #print('inside function ')
        self.file_saved = False
        if self.filename:
            self.update_status('PyNote - Currently Working on : ({})'.format(self.filename))
        else:
            self.update_status('Untitled File')

        pos = self.textarea.index(INSERT)
        line , column = pos.split('.')
        column = int(column) + 1
        #print('Current line is : ',line)
        #print('Current Column is : ', column)
        self.pos.set('Line : {} Column : {}'.format(line,column))

    def cursor_pos(self, *args):
        pos = self.textarea.index(INSERT)
        line, column = pos.split('.')
        column = int(column) + 1
        self.pos.set('Line : {} Column : {}'.format(line, column))



    def update_status(self,data=''):
        self.status.set('PyNote - ({})'.format(data))


    def select_font(self):
        font= askfont()
        # font is "" if the user has cancelled
        if font:
            # spaces in the family name need to be escaped
            font['family'] = font['family'].replace(' ', '\ ')
            font_str = "%(family)s %(size)i %(weight)s %(slant)s" % font
            if font['underline']:
                font_str += ' underline'
            if font['overstrike']:
                font_str += ' overstrike'

            self.font_style = font_str
            self.textarea.configure(font=self.font_style)


    def add_time(self):
        now = datetime.datetime.now()
        now = now.strftime(' Time: %I:%M:%S:%p ')
        self.textarea.insert(END, now)


    def add_date(self):
        now = datetime.datetime.now()
        now = now.strftime(' %Y-%m-%d ')
        self.textarea.insert(END, now)


    def add_time_date(self):
        now = datetime.datetime.now()
        now = now.strftime(' Date: %Y-%m-%d Time: %I:%M:%S:%p ')
        self.textarea.insert(END,now)

    # Select all the text in textbox
    def select_all(self, *args):
        self.textarea.tag_add(SEL, "1.0", END)
        self.textarea.mark_set(INSERT, "1.0")
        self.textarea.see(INSERT)

    def callback(self):
        if(self.file_saved) and (self.textarea.get(1.0,END)) != '':
            if messagebox.askokcancel("Quit", "Do you really wish to quit?"):
                self.root.destroy()
        else:
            val = messagebox.askyesnocancel('PyNote - Says','Save File Before Exit App. ')
            if val:
                self.save_file()
            elif val== False:
                self.root.destroy()
コード例 #6
0
ファイル: onmyoji_win.py プロジェクト: AlanRuijia/onmyoji
class Application(Frame):
    def __init__(self, master=None):
        self.warning = '【封号防止】\n' + \
                       '请尽量在自己的日常刷魂时间使用\n' + \
                       '请不要长时间连续使用,任何使你看起来明显违背人类正常作息规律的行为,很容易会被鬼使黑盯上\n' + \
                       '当你离开了常在城市,请不要使用,这会被认为是找了代练\n' + \
                       '点到为止,贪婪是万恶之源\n'
        self.label = r'阴阳师-网易游戏'
        self.hwnd = None
        self.shell = None
        if not self.info_get():
            self.scaling = 1
            self.clear_time = 35
        self.fight = None
        self.timing_value = None

        # 控件初始化
        Frame.__init__(self, master)
        self.pack()
        self.frame1 = Frame(self)
        self.frame1.pack()
        self.frame2 = Frame(self)
        self.frame2.pack()

        self.label_scaling = Label(self.frame1)
        self.var_scaling = StringVar(self.frame1)
        self.entry_scaling = Entry(self.frame1)

        self.button_scaling_explain = Button(self.frame1)

        self.label_mode = Label(self.frame1)
        self.var_mode = StringVar(self.frame1)
        self.listbox_mode = ttk.Combobox(self.frame1)

        self.button_mode_explain = Button(self.frame1)

        self.label_member = Label(self.frame1)
        self.var_member = IntVar()
        self.radio1 = Radiobutton(self.frame1)
        self.radio2 = Radiobutton(self.frame1)

        self.label_clear_time = Label(self.frame1)
        self.var_clear_time = StringVar(self.frame1)
        self.entry_clear_time = Entry(self.frame1)

        self.button_clear_time_explain = Button(self.frame1)

        self.label_offer = Label(self.frame1)
        self.var_offer_mode = StringVar(self.frame1)
        self.listbox_offer_mode = ttk.Combobox(self.frame1)

        self.label_timing_mode = Label(self.frame1)
        self.var_timing_mode = StringVar(self.frame1)
        self.listbox_timing_mode = ttk.Combobox(self.frame1)

        self.var_timing_value = StringVar(self.frame1)
        self.entry_timing_value = Entry(self.frame1)

        self.entry_test = Entry(self.frame1)
        self.test_btn = Button(self.frame1)

        self.start_ctn = Button(self.frame2)
        self.stop_ctn = Button(self.frame2)

        self.info_box = ScrolledText(self.frame2)

        self.queue = Queue(maxsize=1)
        self._running = 1
        self.create_main()

    @staticmethod
    def check_hwnd(label):
        # 获取游戏窗口句柄
        hwnd = win32gui.FindWindow(None, label)
        if hwnd:
            return hwnd
        else:
            print('游戏没有运行')
            return False

    @staticmethod
    def init_window_place(root, x, y):
        screenwidth = root.winfo_screenwidth()
        screenheight = root.winfo_screenheight()
        root.resizable(False, False)
        root.update_idletasks()
        root.deiconify()
        width = root.winfo_width()
        height = root.winfo_height()
        size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / x,
                                (screenheight - height) / y)
        root.geometry(size)

    def jump_window(self):
        # 跳转到游戏窗口
        win32gui.SetForegroundWindow(self.hwnd)
        win32gui.PostMessage(self.hwnd, win32con.WM_SYSCOMMAND,
                             win32con.SC_RESTORE, 0)

    def get_scaling(self):
        var = self.entry_scaling.get()
        try:
            var = float(var)
        except ValueError:
            messagebox.showinfo(title='提示', message='缩放倍率只能为数字')
            return False
        if var > 2:
            messagebox.showinfo(title='提示', message='缩放倍率过高')
            return False
        return var

    def get_clear_time(self):
        var = self.var_clear_time.get()
        try:
            var = float(var)
        except ValueError:
            messagebox.showinfo(title='提示', message='平均通关时间只能为数字')
            return False
        if var <= 5:
            messagebox.showinfo(title='提示', message='平均通关时间不能小于5')
            return False
        return var

    def get_timimg(self):
        if self.listbox_timing_mode.get() == '无':
            return True
        var = self.var_timing_value.get()
        try:
            var = float(var)
        except ValueError:
            messagebox.showinfo(title='提示', message='预定结束只能填入数字')
            return False
        if var < 1:
            messagebox.showinfo(title='提示', message='数字过小,无法执行')
            return False
        return var

    @staticmethod
    def time_format(second):
        try:
            second = int(second)
        except ValueError:
            return second
        if second > 60:
            m, s = divmod(second, 60)
            h, m = divmod(m, 60)
            return ':'.join(
                (str(h).zfill(2), str(m).zfill(2), str(s).zfill(2)))
        else:
            return second

    def info_get(self):
        try:
            with shelve.open('mysetting.db') as data:
                setting_data = data['setting']
                self.scaling = setting_data['scaling']
                self.clear_time = setting_data['clear_time']
        except KeyError:
            return False
        return True

    def info_save(self):
        with shelve.open('mysetting.db') as data:
            setting_data = dict()
            setting_data['scaling'] = self.var_scaling.get()
            setting_data['clear_time'] = self.var_clear_time.get()
            data['setting'] = setting_data

    def turn_radio_on(self, *args):
        type(args)
        var = self.listbox_mode.get()
        if var == '司机':
            self.radio1.configure(state='active')
            self.radio2.configure(state='active')
        else:
            self.radio1.configure(state='disabled')
            self.radio2.configure(state='disabled')

    def turn_entry_on(self, *args):
        type(args)
        var = self.listbox_timing_mode.get()
        if var == '定时[分钟]' or var == '场数':
            self.entry_timing_value.configure(state='normal')
        else:
            self.entry_timing_value.configure(state='disabled')

    def fight_start(self):
        self.scaling = self.get_scaling()
        if not self.scaling:
            return False
        self.clear_time = self.get_clear_time()
        if not self.clear_time:
            return False
        self.timing_value = self.get_timimg()
        if not self.timing_value:
            return False
        self.info_save()

        # 获取游戏窗口句柄
        self.hwnd = self.check_hwnd(self.label)
        if not self.hwnd:
            messagebox.showinfo(title='提示', message='游戏没有运行')
            return False
        self.shell = win32com.client.Dispatch("WScript.Shell")
        # self.shell.SendKeys('%')

        self.jump_window()
        time.sleep(0.5)
        self.fight = GameController(self.hwnd, self.scaling)
        thread1 = threading.Thread(target=self.fight_thread,
                                   name='fight_thread')
        thread2 = threading.Thread(target=self.offer_thread,
                                   name='offer_thread')
        # 将线程状态、队列内容置为1
        self._running = 1
        if self.queue.empty():
            self.queue.put(1)
        else:
            self.queue.get()
            self.queue.put(1)
        self.start_ctn.configure(state='disabled')
        self.stop_ctn.configure(state='active')
        thread1.start()
        thread2.start()

    def fight_thread(self):
        self.jump_window()
        if not self.queue.empty():
            self.queue.get()
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(self.warning) + '\n', 'RED')
        self.info_box.tag_config('RED', foreground='red')
        var = '[%s]挂机开始' % datetime.datetime.now().strftime("%H:%M:%S")
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)
        rounds = 0
        total_time = 0
        beginning_timg = time.clock()
        while True:
            if self._running == 1:
                fight_start_time = time.clock()
                self.fight.form_team_phase(self.listbox_mode.get(),
                                           self.var_member.get(), self.queue)
                self.fight.wait_fight_finish_phase(self.clear_time, self.queue)
                self.jump_window()
                self.fight.settle_phase(self.queue)
                if self._running == 1:
                    fight_end_time = time.clock()
                    fight_time = fight_end_time - fight_start_time
                    # time.sleep(0.5)
                    rounds = rounds + 1
                    total_time = total_time + fight_time
                    elapsed_time = fight_end_time - beginning_timg
                    var = '第 %s 场 耗时:%s 共计:%s' % \
                          (rounds, self.time_format(fight_time), self.time_format(elapsed_time))
                    self.info_box.mark_set('insert', END)
                    self.info_box.insert('insert', str(var) + '\n')
                    self.info_box.see(END)
                    # 检查是否到达预定结束场数或时间
                    if (self.listbox_timing_mode.get() == '场数' and rounds >= self.timing_value) or \
                       (self.listbox_timing_mode.get() == '定时[分钟]' and elapsed_time / 60 >= self.timing_value):
                        win32gui.PostMessage(self.hwnd, win32con.WM_CLOSE, 0,
                                             0)
                        self.fight_stop()
                        var = '已到达预定目标,游戏窗口已关闭。下线15分钟后buff自动关闭'
                        self.info_box.mark_set('insert', END)
                        self.info_box.insert('insert', str(var) + '\n')
                        self.info_box.see(END)
                    time.sleep(random.uniform(1, 2))
            elif self._running == 0:
                return

    def fight_stop(self):
        # 将线程状态、队列内容置为0
        self._running = 0
        self.queue.put(0)
        self.start_ctn.configure(state='active')
        self.stop_ctn.configure(state='disabled')
        var = '[%s]挂机结束。记得关御魂buff' % datetime.datetime.now().strftime(
            "%H:%M:%S")
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)

    def offer_thread(self):
        while True:
            if self._running == 1:
                self.fight.check_offer(self.listbox_offer_mode.get(),
                                       self.queue)
            elif self._running == 0:
                return

    @staticmethod
    def resource_path(relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        base_path = getattr(sys, '_MEIPASS',
                            os.path.dirname(os.path.abspath(__file__)))
        return os.path.join(base_path, relative_path)

    def what_is_scaling_window(self):
        what_is_scaling = Toplevel(self)
        what_is_scaling.title('缩放倍率 - 不能自动获取,技术就是这么菜,不服憋着_(:3」∠)_')

        frame1 = Frame(what_is_scaling)
        frame1.pack()
        frame2 = Frame(what_is_scaling)
        frame2.pack()

        title = Label(frame1)
        title['text'] = '\n【 缩放倍率 】'
        title.pack()
        desc1 = Message(frame1)
        desc1['width'] = 600
        desc1['text'] = '\n缩放倍率是指Windows系统在不改变分辨率的情况下,将窗口和图标放大以达到更加舒适的显示效果的功能\n' + \
                        '\n在某些分辨率下,Windows会自动设置一个超过100%的倍率。请确定自己系统当前的缩放倍率设置,并填入缩放倍率一栏中\n' + \
                        '\n不正确的缩放倍率设置,会导致坐标计算不准\n' + \
                        '\n若设置的缩放倍率是100%,则填入1,若是125%,则填1.25,依次类推\n'
        desc1.pack()

        label_win10 = Label(frame2)
        label_win10['text'] = 'Windows 10'
        label_win10.grid(row=0, column=0)

        label_win7 = Label(frame2)
        label_win7['text'] = 'Windows 7'
        label_win7.grid(row=0, column=1)

        ipath = self.resource_path('image/win10.png')
        load = PLI_Image.open(ipath)
        load = load.resize(tuple(map(lambda x: int(x * 0.5), load.size)))
        render = ImageTk.PhotoImage(load)
        img_win10 = Label(frame2, image=render)
        img_win10.image = render
        img_win10.grid(row=1, column=0)

        ipath = self.resource_path('image/win7.png')
        load = PLI_Image.open(ipath)
        load = load.resize(tuple(map(lambda x: int(x * 0.5), load.size)))
        render = ImageTk.PhotoImage(load)
        img_win7 = Label(frame2, image=render)
        img_win7.image = render
        img_win7.grid(row=1, column=1)

        self.init_window_place(what_is_scaling, 1.3, 3)

    def when_click_start_window(self):
        when_click_start = Toplevel(self)
        when_click_start.title('模式说明')

        var = self.listbox_mode.get()
        if var == '单刷':
            title = Label(when_click_start)
            title['text'] = '\n【 单刷模式 】'
            title.pack()
            desc = Message(when_click_start)
            desc['text'] = '\n请把游戏调整至如图所示界面,再点START\n'
            desc['width'] = 300
            desc.pack()

            ipath = self.resource_path('image/single.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.7), load.size)))
            render = ImageTk.PhotoImage(load)
            img = Label(when_click_start, image=render)
            img.image = render
            img.pack()
        elif var == '乘客':
            title = Label(when_click_start)
            title['text'] = '\n【 乘客模式 】'
            title.pack()
            desc = Message(when_click_start)
            desc['text'] = '\n建议接受了司机的默认邀请,再点START\n' + \
                           '因为我不会在战斗里帮你点开始...不服憋着\n_(:3」∠)_\n'
            desc['width'] = 300
            desc.pack()

            ipath = self.resource_path('image/passenger_accept.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.7), load.size)))
            render = ImageTk.PhotoImage(load)
            img = Label(when_click_start, image=render)
            img.image = render
            img.pack()
        elif var == '司机':
            title = Label(when_click_start)
            title['text'] = '\n【 司机模式 】'
            title.pack()
            desc = Message(when_click_start)
            desc['text'] = '\n建议对乘客发出默认邀请,回到组队界面再点START\n' + \
                           '因为自动发出邀请这个功能没写...不服憋着\n_(:3」∠)_\n'
            desc['width'] = 300
            desc.pack()

            ipath = self.resource_path('image/driver_invite.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.5), load.size)))
            render = ImageTk.PhotoImage(load)
            img1 = Label(when_click_start, image=render)
            img1.image = render
            img1.pack()

            ipath = self.resource_path('image/driver_form.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.5), load.size)))
            render = ImageTk.PhotoImage(load)
            img2 = Label(when_click_start, image=render)
            img2.image = render
            img2.pack()

        self.init_window_place(when_click_start, 1.3, 3)

    def what_is_clear_time(self):
        what_is_clear = Toplevel(self)
        what_is_clear.title('平均通关时间说明')

        title = Label(what_is_clear)
        title['text'] = '\n【 平均通关时间 】'
        title.pack()
        desc = Message(what_is_clear)
        desc['text'] = '\n平均通关时间是指在游戏中,从按下开始战斗到进入结算奖励界面所经过的时间(秒)\n' + \
                       '\n程序会在经过指定的时间后,再开始检测游戏画面是否进入了结算界面\n' + \
                       '\n如果设置一个较短的时间也可以,不过设置一个合理的时间,能节省你CPU资源\n(其实也没占多少_(:3」∠)_\n'
        desc['width'] = 300
        desc.pack()
        self.init_window_place(what_is_clear, 1.3, 3)

    def create_main(self):
        self.label_scaling['text'] = '缩放倍率'
        self.var_scaling.set(self.scaling)
        self.entry_scaling['textvariable'] = self.var_scaling
        self.label_scaling.grid(row=0, column=0, sticky='E')
        self.entry_scaling.grid(row=0, column=1, sticky='W', columnspan=2)

        self.button_scaling_explain['text'] = '?'
        self.button_scaling_explain['command'] = self.what_is_scaling_window
        self.button_scaling_explain['relief'] = 'flat'
        self.button_scaling_explain.grid(row=0, column=2, sticky='E')

        self.label_mode['text'] = '模式'
        self.var_mode.set('单刷')
        self.listbox_mode['textvariable'] = self.var_mode
        self.listbox_mode['width'] = 10
        self.listbox_mode['values'] = ["单刷", "乘客", "司机"]
        self.listbox_mode.bind("<<ComboboxSelected>>", self.turn_radio_on)
        self.label_mode.grid(row=1, column=0, sticky='E')
        self.listbox_mode.grid(row=1, column=1, sticky='W')

        self.button_mode_explain['text'] = '?'
        self.button_mode_explain['command'] = self.when_click_start_window
        self.button_mode_explain['relief'] = 'flat'
        self.button_mode_explain.grid(row=1, column=2, sticky='W')

        self.var_member.set(2)
        self.label_member['text'] = '车队人数'
        self.label_member.grid(row=2, column=0, sticky='E')
        self.radio1['text'] = '2人'
        self.radio1['variable'] = self.var_member
        self.radio1['value'] = 2
        # self.radio1['command'] = self.test_val3
        self.radio1.grid(row=2, column=1, sticky='W')
        self.radio1.configure(state='disabled')

        self.radio2['text'] = '3人'
        self.radio2['variable'] = self.var_member
        self.radio2['value'] = 3
        # self.radio2['command'] = self.test_val3
        self.radio2.grid(row=2, column=2, sticky='W')
        self.radio2.configure(state='disabled')

        self.label_clear_time['text'] = '平均通关时间'
        self.var_clear_time.set(self.clear_time)
        self.entry_clear_time['textvariable'] = self.var_clear_time
        self.label_clear_time.grid(row=3, column=0, sticky='E')
        self.entry_clear_time.grid(row=3, column=1, sticky='W', columnspan=2)

        self.button_clear_time_explain['text'] = '?'
        self.button_clear_time_explain['command'] = self.what_is_clear_time
        self.button_clear_time_explain['relief'] = 'flat'
        self.button_clear_time_explain.grid(row=3, column=2, sticky='E')

        self.label_offer['text'] = '好友发来悬赏'
        self.var_offer_mode.set('接受')
        self.listbox_offer_mode['textvariable'] = self.var_offer_mode
        self.listbox_offer_mode['width'] = 10
        self.listbox_offer_mode['values'] = ["接受", "拒绝"]
        self.listbox_offer_mode.bind("<<ComboboxSelected>>",
                                     self.turn_radio_on)
        self.label_offer.grid(row=4, column=0, sticky='E')
        self.listbox_offer_mode.grid(row=4, column=1, sticky='W')

        self.label_timing_mode['text'] = '预定结束'
        self.var_timing_mode.set('无')
        self.listbox_timing_mode['textvariable'] = self.var_timing_mode
        self.listbox_timing_mode['width'] = 10
        self.listbox_timing_mode['values'] = ["无", "定时[分钟]", "场数"]
        self.listbox_timing_mode.bind("<<ComboboxSelected>>",
                                      self.turn_entry_on)
        self.label_timing_mode.grid(row=5, column=0, sticky='E')
        self.listbox_timing_mode.grid(row=5, column=1, sticky='W')

        self.var_timing_value.set('')
        self.entry_timing_value['textvariable'] = self.var_timing_value
        self.entry_timing_value['width'] = 5
        self.entry_timing_value.configure(state='disabled')
        self.entry_timing_value.grid(row=5, column=2, sticky='W')

        self.start_ctn['text'] = 'START'
        self.start_ctn['width'] = 10
        self.start_ctn['height'] = 2
        self.start_ctn['command'] = self.fight_start
        self.start_ctn['relief'] = 'groove'
        self.start_ctn.grid(row=0, column=0, sticky='E')

        self.stop_ctn['text'] = 'STOP'
        self.stop_ctn['width'] = 10
        self.stop_ctn['height'] = 2
        self.stop_ctn['command'] = self.fight_stop
        self.stop_ctn['relief'] = 'groove'
        self.stop_ctn.grid(row=0, column=1, sticky='W')
        self.stop_ctn.configure(state='disabled')

        self.info_box['width'] = 40
        self.info_box['height'] = 20
        self.info_box.grid(row=1, column=0, columnspan=2)
        self.info_box.see(END)
        var = '请授予此程序管理员权限运行,否则在游戏窗口内鼠标无法被控制'
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)
コード例 #7
0
class OptimizerMainWindow():
    '''
    classdocs
    '''
    
    #TODO: change that name
    def reactToClick(self, event):
        a = AddRestrictionDialog(self)

    def __init__(self, optimizer):
        
        # always have a reference to model/controller
        self.optimizer = optimizer
        
        # setup main GUI and make stretchable
        self.guiRoot = Tk()
        self.guiRoot.title("OPTIMIZR")
        self.guiRoot.columnconfigure(1, weight=1)
        self.guiRoot.rowconfigure(0, weight=1)
        
        # left (settings) and right (sequences) part
        self.frameLeft = Frame(self.guiRoot)
        self.frameLeft.grid(row=0, column=0, sticky=W+E+N+S)
        self.frameLeft.columnconfigure(0, weight=1)
        self.frameRight = Frame(self.guiRoot)
        self.frameRight.grid(row=0, column=1, sticky=W+E+N+S)
        self.frameRight.columnconfigure(0, weight=1)
        self.frameRight.rowconfigure(0, weight=1)
        self.frameRight.rowconfigure(1, weight=1)
        
        
        self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10)
        self.frameSpeciesControll.columnconfigure(1, weight=1)
        self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10)
        self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10)
        self.frameSpeciesControll.grid(row=0, column=0, sticky=W+E, padx=10, pady=10)
        self.frameOptimizationControll.grid(row=1, column=0, sticky=W+E, padx=10, pady=10)
        self.frameRestrictionControll.grid(row=2, column=0, sticky=W+E, padx=10, pady=10)
        
        # Species Controll
        Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0)
        Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0)
        
        self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew")
        self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we")        
        self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List")
        self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e")
        
        self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        
        # Optimization Controll
        Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0)
        self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly")
        self.comboOptimizationStrategy.grid(row=0, column=1)
        self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies
        self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        
        # Restriction Enzymes
        self.listRestriction = Listbox(self.frameRestrictionControll)
        self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W+E)
        self.frameRestrictionControll.columnconfigure(0, weight=1)
        self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ")
        self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ")
        self.buttonRestricionAdd.grid(row=1, column=1, padx=5)
        self.buttonRestricionDel.grid(row=1, column=2, padx=5)
        
        # Source Sequence Frame
        self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10)
        self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10)
        self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10)
        self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10)
        
        
        self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ")
        self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10)
        self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5)
        self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens")
        self.frameSourceSequence.columnconfigure(0, weight=1)
        self.frameSourceSequence.rowconfigure(1, weight=1)
        self.textSourceSeq.frame.columnconfigure(1, weight=1)
        self.textSourceSeq.frame.rowconfigure(0, weight=1)
        
        self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ")
        self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize)
        
        self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ")
        self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion)
        
        self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ")
        self.textResultSequence = ScrolledText(self.frameResultSequence, height=10)
        self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w")
        self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w")
        self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens")
        self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e")
        self.frameResultSequence.columnconfigure(2, weight=1)
        self.frameResultSequence.rowconfigure(1, weight=1)
        self.textResultSequence.frame.columnconfigure(1, weight=1)
        self.textResultSequence.frame.rowconfigure(0, weight=1)
        
        self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified)
        self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified)
        
        #generate color tags for textboxes
        for i in range(101):
            
            #green for normal codons
            (r,g,b) = colorsys.hsv_to_rgb(210/360, i/100, 1.0)            
            colorHex = "#%02x%02x%02x" % (int(r*255), int(g*255), int(b*255))
            
            self.textSourceSeq.tag_config("normal"+str(i), background=colorHex)
            self.textResultSequence.tag_config("normal"+str(i), background=colorHex)
            
            #red for codons with restriction sites
            (r,g,b) = colorsys.hsv_to_rgb(5/360, i/100, 1.0)            
            colorHex = "#%02x%02x%02x" % (int(r*255), int(g*255), int(b*255))
            
            self.textSourceSeq.tag_config("restrict"+str(i), background=colorHex)
            self.textResultSequence.tag_config("restrict"+str(i), background=colorHex)
        
        
        # Set (minimum + max) Window size 
        self.guiRoot.update()
        self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height())
        
        self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick)
        self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete)
        self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton)
        
        self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence)
        self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence)
        
        # TEST
#         self.listRestriction.insert("end", "EcoRI")
#         self.listRestriction.insert("end", "BamHI")
#         
        
        # dummy event to manually trigger update
        self.guiRoot.bind("<<Update>>", self.actionUpdate)
        
        self.actionUpdate(None)
        
        self.guiRoot.mainloop()
    
    def actionRestrictionEnzymeDelete(self, event):
        try:
            selectedEnzyme = self.listRestriction.selection_get()
            self.optimizer.restrictionEnzymeList.remove(selectedEnzyme)
            self.guiRoot.event_generate("<<Update>>")
        except tkinter.TclError :
            # no selection
            pass    
        
    def actionUpdate(self, event):
#         print("update called")

        # clear list of restriction enzymes
        self.listRestriction.delete(0, "end")        
        for r in self.optimizer.restrictionEnzymeList:
            self.listRestriction.insert("end", r)
            
        self.comboSourceSpecies.delete(0, "end")
        self.comboTargetSpecies.delete(0, "end")
        
        speciesValues = list()        
        for (taxid, name) in self.optimizer.speciesList:
            speciesValues.append(taxid + ": " + name)
            
        self.comboSourceSpecies["values"] = speciesValues
        self.comboTargetSpecies["values"] = speciesValues
        
        if self.comboSourceSpecies.get() not in speciesValues:
            self.comboSourceSpecies.set("")
        if self.comboTargetSpecies.get() not in speciesValues:
            self.comboTargetSpecies.set("")
            
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
        
        self.optimizer.saveConfig("config.ini")
            
    def actionEditSpeciesButton(self, event):
        speciesListDialog = SpeciesListDialog(self)
        
    def actionOptimizerSettingsChanged(self, event=None):
#         print("Something happened")
        strategy = self.comboOptimizationStrategy.get()
        sourceString = self.comboSourceSpecies.get()
        targetString = self.comboTargetSpecies.get()
        
        if not (strategy and sourceString and targetString):
            return
        
        sourceTaxid = sourceString.split(":")[0]
        targetTaxid = targetString.split(":")[0]
        
        self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy)
        
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
#         self.optimizer.testPrint()

    def actionOptimize(self, event=None):
        self.optimizer.runOptimization()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
        
    def actionRemoveRestricion(self, event=None):
        self.optimizer.runRestricionRemoval()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
        
    def actionSequenceModified(self, event=None):
        # necessary if, otherwise -> infinite loop
        if self.textSourceSeq.edit_modified():
            
            seq = self.textSourceSeq.get("1.0", "end").strip()
            seq = stripCharsNotInList(seq.upper(), ['A', 'C', 'G', 'T'])
            self.optimizer.setSourceSeq(seq)
            
            oldInsert = self.textSourceSeq.index("insert")
            self.textSourceSeq.delete("1.0", "end")
            
            sourceCodons = self.optimizer.getCodonsForPrint(True)
            if not sourceCodons:
                self.textSourceSeq.insert("end", self.optimizer.sourceSequence)
            else:
                for (co, sc, r) in sourceCodons:
                    if sc:
                        if not r:
                            self.textSourceSeq.insert("end", co, "normal"+str(int(sc*100)))
                            #print("normal"+str(int(sc*100)))
                        else:
                            self.textSourceSeq.insert("end", co, "restrict"+str(int(sc*100)))
                    else:
                        # remainder without color
                        self.textSourceSeq.insert("end", co)
                    
                
            self.textSourceSeq.mark_set("insert", oldInsert)

            # reset the modified status at the very end
            self.textSourceSeq.edit_modified(False)

        if self.textResultSequence.edit_modified():
            
            seq = self.textResultSequence.get("1.0", "end").strip()
#             self.optimizer.setOptimizedSeq(seq)
            
            oldInsert = self.textResultSequence.index("insert")
            self.textResultSequence.delete("1.0", "end")
            
            targetCodons = self.optimizer.getCodonsForPrint(False)
            if not targetCodons:
                self.textSourceSeq.insert("end", self.optimizer.optimizedSequence)
            else:
                for (co, sc, r) in targetCodons:
                    if sc:
                        if not r:
                            self.textResultSequence.insert("end", co, "normal"+str(int(sc*100)))
                            #print("normal"+str(int(sc*100)))
                        else:
                            self.textResultSequence.insert("end", co, "restrict"+str(int(sc*100)))
                    else:
                        # remainder without color
                        self.textResultSequence.insert("end", co)
                    
                
            self.textSourceSeq.mark_set("insert", oldInsert)
            
            self.textResultSequence.edit_modified(False)

    def actionLoadSequence(self, event=None):
        filename = tkinter.filedialog.askopenfilename()
        if filename:
            seq = sequenceIO.readFile(filename)
            self.textSourceSeq.delete("1.0", "end")
            self.textSourceSeq.insert("end", seq)            
            self.textSourceSeq.edit_modified(True)
            
    def actionSaveSequence(self, event=None):
        filename = tkinter.filedialog.asksaveasfilename()
        if filename:
#             print("file is " + filename)
            with open(filename, mode='w') as fd:
                fd.write(self.optimizer.optimizedSequence)
コード例 #8
0
class App(Frame):
    """Гланое окно приложения"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # screen_width = self.winfo_screenwidth()
        # print(screen_width, self.winfo_screenheight())

        self.master.title(f'Mem-translate {__version__}')
        self.master.minsize(300, 200)

        menu = Menu(self.master)
        self.master.configure(menu=menu)

        menu_file = Menu(menu)
        menu_file.add_command(label='Импорт', command=self.on_import)
        menu.add_cascade(label='Файл', menu=menu_file)

        width = 73

        self.text = ScrolledText(self, bg='white', height=31, width=width, undo=True, wrap='word')
        self.text['font'] = DEFAULT_FONT
        self.text.tag_configure(TAG_BLUE, background='#aaf')
        self.text.focus_set()
        self.text.bind('<Key>', self.on_key_text)
        self.text.grid_configure(row=0, column=0, rowspan=2)

        self.text_fuzz = ScrolledText(self, bg='white', height=15, width=width, wrap='word')
        self.text_fuzz['font'] = DEFAULT_FONT
        self.text_fuzz.tag_configure(TAG_BLUE, background='#afa')
        self.text_fuzz.bind('<Key>', lambda event: 'break')
        self.text_fuzz.grid_configure(row=0, column=1, sticky='n')

        self.text_tran = ScrolledText(self, bg='white', height=15, width=width, wrap='word')
        self.text_tran['font'] = DEFAULT_FONT
        self.text_tran.bind('<Key>', lambda event: 'break')
        self.text_tran.grid_configure(row=1, column=1, sticky='s')

        self.grid_configure()

    def destroy(self):
        # todo
        log.info('destroy')
        super().destroy()

    def on_import(self):
        """Обработчик кнопки Импорт"""
        filename = Open(initialdir='../you-can/source/', filetypes=(('Текст', '*.txt'),)).show()
        text_ls = do_import(filename)
        self.do_open(text_ls)

    def do_open(self, text_ls: List[str]):
        """Отрисовать текст"""
        for line in text_ls:
            self.text.insert('end', line)
            # добавляем немного подсветки
            # if not line.startswith(PREFIX_TRANSLATE) and line != PREFIX_CUT:
            if not line.startswith('>>>'):
                i = self.text.index('insert').split('.', 1)[0]
                self.text.tag_add(TAG_BLUE, f'{i}.0', f'{i}.{len(line)}')
            self.text.insert('end', '\n')
        log.debug(self.text.tag_ranges(TAG_BLUE))

    def on_key_text(self, event):
        """Обработчик нажатий любой клавиши в главном textArea"""
        if event.keycode == 36:  # Return
            self.do_enter()
            return 'break'
        log.debug(event)

    def do_enter(self):
        tag_range = self.text.tag_nextrange(TAG_BLUE, self.text.index('insert'))
        if not tag_range:
            return
        index1, index2 = tag_range

        # двигаем курсор
        index = int(index2.split('.')[0]) + 1
        self.text.mark_set('insert', f'{index}.{len(PREFIX_TRANSLATE)}')
        self.text.see('insert')

        text: str = self.text.get(index1, index2)

        # переводим текст
        self.text_tran.delete('1.0', 'end')
        start_new_thread(self.thread_translate, (text,))

        # ...
        self.text_fuzz.delete('1.0', 'end')
        start_new_thread(self.thread_fuzz, (text,))

    def thread_translate(self, text: str):
        """Асинхронно запускаем машинный перевод"""
        try:
            text2 = translate_yandex(text)
        except BaseException as ex:
            text2 = str(ex)
        self.text_tran.insert('1.0', text2)

    def thread_fuzz(self, text: str):
        """Асинхронно ищем нечёткие совпадения"""
        # todo закешировать + парсить перевод + перенести в text.py
        ls: list = self.text.get('1.0', 'end').split('\n')
        ls.remove(text)
        choices = [f'{i + 1}: {line}' for i, line in enumerate(ls) if not line.startswith('>>>')]

        # result = [f'{line} ({p})' for line, p in extractBests(text, choices, score_cutoff=1, limit=7)]

        # result = [(line, fuzz.token_set_ratio(line, text)) for line in choices]

        ww = set(re.findall(r'\w{4,}', text)) - {'that', 'That', 'only', 'Only'}
        result = []
        for line in choices:
            p = len(set(re.findall(r'\w{4,}', line)) & ww)
            if p > 0:
                result.append((line, p))
        result = heapq.nlargest(7, result, key=lambda x: x[1])
        result = [line for line, p in result]

        # self.text_fuzz.insert('1.0', '\n'.join(result))
        for line in result:
            self.text_fuzz.insert('end', line)
            i = self.text_fuzz.index('insert').split('.', 1)[0]
            # for m in SequenceMatcher(None, line.lower(), text.lower()).get_matching_blocks():
            #     self.text_fuzz.tag_add(TAG_BLUE, f'{i}.{m.a}', f'{i}.{m.a + m.size}')
            for w in ww:
                for m in re.finditer(w, line):
                    self.text_fuzz.tag_add(TAG_BLUE, f'{i}.{m.start()}', f'{i}.{m.end()}')
            self.text_fuzz.insert('end', '\n')
コード例 #9
0
class OptimizerMainWindow:
    """
    classdocs
    """

    # TODO: change that name
    def reactToClick(self, event):
        a = AddRestrictionDialog(self)

    def __init__(self, optimizer):

        # always have a reference to model/controller
        self.optimizer = optimizer

        # setup main GUI and make stretchable
        self.guiRoot = Tk()
        self.guiRoot.title("OPTIMIZR")
        self.guiRoot.columnconfigure(1, weight=1)
        self.guiRoot.rowconfigure(0, weight=1)

        # left (settings) and right (sequences) part
        self.frameLeft = Frame(self.guiRoot)
        self.frameLeft.grid(row=0, column=0, sticky=W + E + N + S)
        self.frameLeft.columnconfigure(0, weight=1)
        self.frameRight = Frame(self.guiRoot)
        self.frameRight.grid(row=0, column=1, sticky=W + E + N + S)
        self.frameRight.columnconfigure(0, weight=1)
        self.frameRight.rowconfigure(0, weight=1)
        self.frameRight.rowconfigure(1, weight=1)

        self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10)
        self.frameSpeciesControll.columnconfigure(1, weight=1)
        self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10)
        self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10)
        self.frameSpeciesControll.grid(row=0, column=0, sticky=W + E, padx=10, pady=10)
        self.frameOptimizationControll.grid(row=1, column=0, sticky=W + E, padx=10, pady=10)
        self.frameRestrictionControll.grid(row=2, column=0, sticky=W + E, padx=10, pady=10)

        # Species Controll
        Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0)
        Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0)

        self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew")
        self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we")
        self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List")
        self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e")

        self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)

        # Optimization Controll
        Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0)
        self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly")
        self.comboOptimizationStrategy.grid(row=0, column=1)
        self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies
        self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)

        # Restriction Enzymes
        self.listRestriction = Listbox(self.frameRestrictionControll)
        self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W + E)
        self.frameRestrictionControll.columnconfigure(0, weight=1)
        self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ")
        self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ")
        self.buttonRestricionAdd.grid(row=1, column=1, padx=5)
        self.buttonRestricionDel.grid(row=1, column=2, padx=5)

        # Source Sequence Frame
        self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10)
        self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10)
        self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10)
        self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10)

        self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ")
        self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10)
        self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5)
        self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens")
        self.frameSourceSequence.columnconfigure(0, weight=1)
        self.frameSourceSequence.rowconfigure(1, weight=1)
        self.textSourceSeq.frame.columnconfigure(1, weight=1)
        self.textSourceSeq.frame.rowconfigure(0, weight=1)

        self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ")
        self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize)

        self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ")
        self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion)

        self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ")
        self.textResultSequence = ScrolledText(self.frameResultSequence, height=10)
        self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w")
        self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w")
        self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens")
        self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e")
        self.frameResultSequence.columnconfigure(2, weight=1)
        self.frameResultSequence.rowconfigure(1, weight=1)
        self.textResultSequence.frame.columnconfigure(1, weight=1)
        self.textResultSequence.frame.rowconfigure(0, weight=1)

        self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified)
        self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified)

        # generate color tags for textboxes
        for i in range(101):

            # green for normal codons
            (r, g, b) = colorsys.hsv_to_rgb(210 / 360, i / 100, 1.0)
            colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255))

            self.textSourceSeq.tag_config("normal" + str(i), background=colorHex)
            self.textResultSequence.tag_config("normal" + str(i), background=colorHex)

            # red for codons with restriction sites
            (r, g, b) = colorsys.hsv_to_rgb(5 / 360, i / 100, 1.0)
            colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255))

            self.textSourceSeq.tag_config("restrict" + str(i), background=colorHex)
            self.textResultSequence.tag_config("restrict" + str(i), background=colorHex)

        # Set (minimum + max) Window size
        self.guiRoot.update()
        self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height())

        self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick)
        self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete)
        self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton)

        self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence)
        self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence)

        # TEST
        #         self.listRestriction.insert("end", "EcoRI")
        #         self.listRestriction.insert("end", "BamHI")
        #

        # dummy event to manually trigger update
        self.guiRoot.bind("<<Update>>", self.actionUpdate)

        self.actionUpdate(None)

        self.guiRoot.mainloop()

    def actionRestrictionEnzymeDelete(self, event):
        try:
            selectedEnzyme = self.listRestriction.selection_get()
            self.optimizer.restrictionEnzymeList.remove(selectedEnzyme)
            self.guiRoot.event_generate("<<Update>>")
        except tkinter.TclError:
            # no selection
            pass

    def actionUpdate(self, event):
        #         print("update called")

        # clear list of restriction enzymes
        self.listRestriction.delete(0, "end")
        for r in self.optimizer.restrictionEnzymeList:
            self.listRestriction.insert("end", r)

        self.comboSourceSpecies.delete(0, "end")
        self.comboTargetSpecies.delete(0, "end")

        speciesValues = list()
        for (taxid, name) in self.optimizer.speciesList:
            speciesValues.append(taxid + ": " + name)

        self.comboSourceSpecies["values"] = speciesValues
        self.comboTargetSpecies["values"] = speciesValues

        if self.comboSourceSpecies.get() not in speciesValues:
            self.comboSourceSpecies.set("")
        if self.comboTargetSpecies.get() not in speciesValues:
            self.comboTargetSpecies.set("")

        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

        self.optimizer.saveConfig("config.ini")

    def actionEditSpeciesButton(self, event):
        speciesListDialog = SpeciesListDialog(self)

    def actionOptimizerSettingsChanged(self, event=None):
        #         print("Something happened")
        strategy = self.comboOptimizationStrategy.get()
        sourceString = self.comboSourceSpecies.get()
        targetString = self.comboTargetSpecies.get()

        if not (strategy and sourceString and targetString):
            return

        sourceTaxid = sourceString.split(":")[0]
        targetTaxid = targetString.split(":")[0]

        self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy)

        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

    #         self.optimizer.testPrint()

    def actionOptimize(self, event=None):
        self.optimizer.runOptimization()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

    def actionRemoveRestricion(self, event=None):
        self.optimizer.runRestricionRemoval()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

    def actionSequenceModified(self, event=None):
        # necessary if, otherwise -> infinite loop
        if self.textSourceSeq.edit_modified():

            seq = self.textSourceSeq.get("1.0", "end").strip()
            seq = stripCharsNotInList(seq.upper(), ["A", "C", "G", "T"])
            self.optimizer.setSourceSeq(seq)

            oldInsert = self.textSourceSeq.index("insert")
            self.textSourceSeq.delete("1.0", "end")

            sourceCodons = self.optimizer.getCodonsForPrint(True)
            if not sourceCodons:
                self.textSourceSeq.insert("end", self.optimizer.sourceSequence)
            else:
                for (co, sc, r) in sourceCodons:
                    if sc:
                        if not r:
                            self.textSourceSeq.insert("end", co, "normal" + str(int(sc * 100)))
                            # print("normal"+str(int(sc*100)))
                        else:
                            self.textSourceSeq.insert("end", co, "restrict" + str(int(sc * 100)))
                    else:
                        # remainder without color
                        self.textSourceSeq.insert("end", co)

            self.textSourceSeq.mark_set("insert", oldInsert)

            # reset the modified status at the very end
            self.textSourceSeq.edit_modified(False)

        if self.textResultSequence.edit_modified():

            seq = self.textResultSequence.get("1.0", "end").strip()
            #             self.optimizer.setOptimizedSeq(seq)

            oldInsert = self.textResultSequence.index("insert")
            self.textResultSequence.delete("1.0", "end")

            targetCodons = self.optimizer.getCodonsForPrint(False)
            if not targetCodons:
                self.textSourceSeq.insert("end", self.optimizer.optimizedSequence)
            else:
                for (co, sc, r) in targetCodons:
                    if sc:
                        if not r:
                            self.textResultSequence.insert("end", co, "normal" + str(int(sc * 100)))
                            # print("normal"+str(int(sc*100)))
                        else:
                            self.textResultSequence.insert("end", co, "restrict" + str(int(sc * 100)))
                    else:
                        # remainder without color
                        self.textResultSequence.insert("end", co)

            self.textSourceSeq.mark_set("insert", oldInsert)

            self.textResultSequence.edit_modified(False)

    def actionLoadSequence(self, event=None):
        filename = tkinter.filedialog.askopenfilename()
        if filename:
            seq = sequenceIO.readFile(filename)
            self.textSourceSeq.delete("1.0", "end")
            self.textSourceSeq.insert("end", seq)
            self.textSourceSeq.edit_modified(True)

    def actionSaveSequence(self, event=None):
        filename = tkinter.filedialog.asksaveasfilename()
        if filename:
            #             print("file is " + filename)
            with open(filename, mode="w") as fd:
                fd.write(self.optimizer.optimizedSequence)
コード例 #10
0
class Application(Frame):
    def __init__(self, master=None):
        """
        控件初始化
        :param master:
        """
        self.debug = False
        self.version = 'miss'
        self.warning = '【封号防止】\n' + \
                       '请尽量在自己的日常刷魂时间使用\n' + \
                       '请不要长时间连续使用,任何使你看起来明显违背人类正常作息规律的行为,很容易会被鬼使黑盯上\n' + \
                       '当你离开了常在城市,请不要使用,这会被认为是找了代练\n' + \
                       '点到为止,贪婪是万恶之源\n'
        self.label = r'阴阳师-网易游戏'
        self.hwnd = None
        self.shell = None
        if not self.info_get():
            self.scaling = 1
            self.clear_time = 35
            self.delay_time = 1
        self.fight = None
        self.timing_value = None

        # 控件初始化
        Frame.__init__(self, master)
        self.pack()
        self.frame1 = Frame(self)
        self.frame1.pack()
        self.frame2 = Frame(self)
        self.frame2.pack()

        self.label_mode = Label(self.frame1)
        self.var_mode = StringVar(self.frame1)
        self.listbox_mode = ttk.Combobox(self.frame1)

        self.button_mode_explain = Button(self.frame1)

        self.label_member = Label(self.frame1)
        self.var_member = IntVar()
        self.radio1 = Radiobutton(self.frame1)
        self.radio2 = Radiobutton(self.frame1)

        self.label_clear_time = Label(self.frame1)
        self.var_clear_time = StringVar(self.frame1)
        self.entry_clear_time = Entry(self.frame1)

        self.button_clear_time_explain = Button(self.frame1)

        self.label_delay_time = Label(self.frame1)
        self.var_delay_time = StringVar(self.frame1)
        self.entry_delay_time = Entry(self.frame1)

        self.button_delay_time_explain = Button(self.frame1)

        self.label_offer = Label(self.frame1)
        self.var_offer_mode = StringVar(self.frame1)
        self.listbox_offer_mode = ttk.Combobox(self.frame1)

        self.label_timing_mode = Label(self.frame1)
        self.var_timing_mode = StringVar(self.frame1)
        self.listbox_timing_mode = ttk.Combobox(self.frame1)

        self.var_timing_value = StringVar(self.frame1)
        self.entry_timing_value = Entry(self.frame1)

        self.label_done_action_mode = Label(self.frame1)
        self.var_done_action_mode = StringVar(self.frame1)
        self.listbox_done_action_mode = ttk.Combobox(self.frame1)

        self.entry_test = Entry(self.frame1)
        self.test_btn = Button(self.frame1)

        self.start_ctn = Button(self.frame2)
        self.stop_ctn = Button(self.frame2)

        self.info_box = ScrolledText(self.frame2)

        self.queue = Queue(maxsize=1)
        self._running = 0

        hot_key = threading.Thread(target=self.hotkey_thread,
                                   name='hotkey_thread')
        hot_key.setDaemon(True)
        hot_key.start()

    def setdebug(self, debug):
        self.debug = debug

    def setversion(self, version):
        self.version = version

    def get_clear_time(self):
        """
        校验平均通关时间输入值
        :return: 校验通过则返回浮点型数字,否则返回False
        """
        var = self.var_clear_time.get()
        try:
            var = float(var)
        except ValueError:
            messagebox.showinfo(title='提示', message='平均通关时间只能为数字')
            return False
        if var <= 5:
            messagebox.showinfo(title='提示', message='平均通关时间不能小于5')
            return False
        return var

    def get_delay_time(self):
        """
        校验平均通关时间输入值
        :return: 校验通过则返回浮点型数字,否则返回False
        """
        var = self.var_delay_time.get()
        try:
            var = float(var)
        except ValueError:
            messagebox.showinfo(title='提示', message='战斗后等待时间只能为数字')
            return False
        if var <= 0:
            messagebox.showinfo(title='提示', message='战斗后等待时间不能小于0')
            return False
        return var

    def get_timimg(self):
        """
        校验预定结束输入值
        :return: 校验通过则返回浮点型数字,否则返回False
        """
        if self.listbox_timing_mode.get() == '无' or \
           self.listbox_timing_mode.get() == '超鬼王模式1' or \
           self.listbox_timing_mode.get() == '超鬼王模式2':
            return True
        var = self.var_timing_value.get()
        try:
            var = float(var)
        except ValueError:
            messagebox.showinfo(title='提示', message='预定结束只能填入数字')
            return False
        if var < 1:
            messagebox.showinfo(title='提示', message='数字过小,无法执行')
            return False
        return var

    def info_get(self):
        """
        读取存储文件
        :return:
        """
        try:
            with shelve.open('mysetting.db') as data:
                setting_data = data['setting']
                self.scaling = setting_data['scaling']
                self.clear_time = setting_data['clear_time']
                self.delay_time = setting_data['delay_time']
        except KeyError:
            return False
        return True

    def info_save(self):
        """
        存储设置
        :return:
        """
        with shelve.open('mysetting.db') as data:
            setting_data = dict()
            setting_data['clear_time'] = self.var_clear_time.get()
            setting_data['delay_time'] = self.var_delay_time.get()
            data['setting'] = setting_data

    def turn_radio_on(self, *args):
        """
        根据条件激活相应控件
        :param args:
        :return:
        """
        type(args)
        var = self.listbox_mode.get()
        if var == '司机':
            self.radio1.configure(state='active')
            self.radio2.configure(state='active')
        else:
            self.radio1.configure(state='disabled')
            self.radio2.configure(state='disabled')

    def turn_entry_on(self, *args):
        """
        根据条件激活相应控件
        :param args:
        :return:
        """
        type(args)
        var = self.listbox_timing_mode.get()
        if var == '定时[分钟]' or var == '场数':
            self.entry_timing_value.configure(state='normal')
            self.listbox_done_action_mode.configure(state='normal')
            self.var_done_action_mode.set('关闭游戏窗口')
        elif var == '超鬼王模式1':
            self.entry_timing_value.configure(state='disabled')
            self.listbox_done_action_mode.configure(state='normal')
            self.var_done_action_mode.set('仅停止挂机')
            content = '\n超鬼王模式1:\n仅自己发现的鬼王\n'
            self.info_box.mark_set('insert', END)
            self.info_box.insert('insert', str(content) + '\n')
            self.info_box.see(END)
        elif var == '超鬼王模式2':
            self.entry_timing_value.configure(state='disabled')
            self.listbox_done_action_mode.configure(state='normal')
            self.var_done_action_mode.set('仅停止挂机')
            content = '\n超鬼王模式2:\n自己发现的鬼王或好友邀请的鬼王\n'
            self.info_box.mark_set('insert', END)
            self.info_box.insert('insert', str(content) + '\n')
            self.info_box.see(END)
        else:
            self.entry_timing_value.configure(state='disabled')
            self.var_done_action_mode.set('')
            self.listbox_done_action_mode.configure(state='disabled')

    def turn_all_widget_off(self):
        self.entry_clear_time.configure(state='disabled')
        self.entry_delay_time.configure(state='disabled')
        self.entry_timing_value.configure(state='disabled')
        self.listbox_mode.configure(state='disabled')
        self.listbox_offer_mode.configure(state='disabled')
        self.listbox_timing_mode.configure(state='disabled')
        self.listbox_done_action_mode.configure(state='disabled')

    def turn_all_widget_on(self):
        self.entry_clear_time.configure(state='normal')
        self.entry_delay_time.configure(state='normal')
        self.entry_timing_value.configure(state='normal')
        self.listbox_mode.configure(state='normal')
        self.listbox_offer_mode.configure(state='normal')
        self.listbox_timing_mode.configure(state='normal')
        self.listbox_done_action_mode.configure(state='normal')

    def fight_start(self):
        """
        START按钮响应流程
        :return:
        """
        self.clear_time = self.get_clear_time()
        if not self.clear_time:
            return False
        self.delay_time = self.get_delay_time()
        if not self.delay_time:
            return False
        self.timing_value = self.get_timimg()
        if not self.timing_value:
            return False
        self.info_save()

        # 获取游戏窗口句柄
        self.hwnd = check_hwnd(self.label)
        if not self.hwnd:
            messagebox.showinfo(title='提示', message='游戏没有运行')
            return False
        # self.shell = win32com.client.Dispatch("WScript.Shell")
        # self.shell.SendKeys('%')

        jump_window(self.hwnd)
        time.sleep(0.5)
        try:
            self.fight = GameController(self.hwnd)
            print('原分辨率 %s * %s' % (self.fight.resolution['width'],
                                    self.fight.resolution['height']))
            print('缩放后分辨率 %s * %s' % (self.fight.resolution['width_scale'],
                                      self.fight.resolution['height_scale']))
            print('缩放比例 %s' % self.fight.resolution['scaling'])
        except ResolutionGetError:
            messagebox.showinfo(title='提示', message='获取Windows缩放比例失败,无法计算坐标')
            return False
        if self.debug:
            self.fight.setdebug(True)
        threads = []
        thread1 = threading.Thread(target=self.fight_thread,
                                   name='fight_thread')
        threads.append(thread1)
        thread2 = threading.Thread(target=self.offer_thread,
                                   name='offer_thread')
        threads.append(thread2)
        thread3 = threading.Thread(target=self.fullrepo_thread,
                                   name='fullrepo_thread')
        threads.append(thread3)
        if self.listbox_timing_mode.get(
        ) == '超鬼王模式1' or self.listbox_timing_mode.get() == '超鬼王模式2':
            thread4 = threading.Thread(target=self.boss_monitoring_thread,
                                       name='boss_thread')
            threads.append(thread4)
        # 将线程状态、队列内容置为1
        self._running = 1
        if self.queue.empty():
            self.queue.put(1)
        else:
            self.queue.get()
            self.queue.put(1)
        self.start_ctn.configure(state='disabled')
        self.stop_ctn.configure(state='active')
        for thread in threads:
            thread.setDaemon(True)
            thread.start()

    def fight_stop(self):
        """
        STOP按钮响应流程
        :return:
        """
        # 将线程状态、队列内容置为0
        self._running = 0
        self.queue.put(0)
        self.start_ctn.configure(state='active')
        self.stop_ctn.configure(state='disabled')
        self.turn_all_widget_on()
        var = '[%s]挂机结束。记得关御魂buff' % datetime.datetime.now().strftime(
            "%H:%M:%S")
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)
        if self.debug:
            logging('STOP指令-----------------')
        if len(sys.argv) == 1 or (len(sys.argv) > 1
                                  and sys.argv[1] != 'debug'):
            self.setdebug(False)

    def fight_thread(self):
        """
        战斗控制线程,并输出相关信息
        :return:
        """
        jump_window(self.hwnd)
        if not self.queue.empty():
            self.queue.get()
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(self.warning) + '\n', 'RED')
        self.info_box.tag_config('RED', foreground='red')
        var = '[%s]挂机开始。按Ctrl + F1可以停止挂机' % datetime.datetime.now().strftime(
            "%H:%M:%S")
        if self.debug:
            var = var + '\n当前以debug模式运行,在当前目录下将生成debug.log'
        self.turn_all_widget_off()
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)
        rounds = 0
        total_time = 0
        beginning_time = int(time.time())
        while True:
            if self._running == 1:
                fight_start_time = time.time()
                self.fight.form_team_phase(self.listbox_mode.get(),
                                           self.var_member.get(), self.queue)
                self.fight.wait_fight_finish_phase(self.listbox_mode.get(),
                                                   self.clear_time, self.queue)
                jump_window(self.hwnd)
                self.fight.settle_phase(self.queue)
                if self._running == 1:
                    fight_end_time = int(time.time())
                    fight_time = fight_end_time - fight_start_time
                    rounds = rounds + 1
                    total_time = total_time + fight_time
                    elapsed_time = fight_end_time - beginning_time
                    var = '第 %s 场 耗时:%s 共计:%s' % \
                          (rounds, time_format(fight_time), time_format(elapsed_time))
                    self.info_box.mark_set('insert', END)
                    self.info_box.insert('insert', str(var) + '\n')
                    self.info_box.see(END)
                    if self.debug:
                        logging('------------------------')
                    # 检查是否到达预定结束场数或时间
                    if (self.listbox_timing_mode.get() == '场数' and rounds >= self.timing_value) or \
                       (self.listbox_timing_mode.get() == '定时[分钟]' and elapsed_time / 60 >= self.timing_value):
                        if self.listbox_done_action_mode.get() == '关闭游戏窗口':
                            win32gui.PostMessage(self.hwnd, win32con.WM_CLOSE,
                                                 0, 0)
                            time.sleep(1)
                            lebel_exit = '退出游戏'
                            hwnd_exit = check_hwnd(lebel_exit)
                            win32gui.PostMessage(hwnd_exit,
                                                 win32con.WM_KEYDOWN,
                                                 win32con.VK_RETURN, 0)
                            win32gui.PostMessage(hwnd_exit, win32con.WM_KEYUP,
                                                 win32con.VK_RETURN, 0)
                            var = '已到达预定目标,游戏窗口已关闭。下线15分钟后buff自动关闭'
                        elif self.listbox_done_action_mode.get() == '仅停止挂机':
                            var = '已到达预定目标,挂机已停止。'
                        self.fight_stop()
                        self.info_box.mark_set('insert', END)
                        self.info_box.insert('insert', str(var) + '\n')
                        self.info_box.see(END)
                    random.uniform(1, 2)
                    delay_time = int(self.delay_time) + random.uniform(
                        0.2, 0.5)
                    time.sleep(delay_time)
            elif self._running == 0:
                return

    def offer_thread(self):
        """
        悬赏协助控制线程
        :return:
        """
        while True:
            if self._running == 1:
                mode = None
                if self.listbox_offer_mode.get() == "接受":
                    mode = 1
                elif self.listbox_offer_mode.get() == "拒绝":
                    mode = 2
                self.fight.check_offer(mode, self.queue)
            elif self._running == 0:
                return

    def fullrepo_thread(self):
        """
        点击满仓提示控制线程
        :return:
        """
        while True:
            if self._running == 1:
                self.fight.check_fullrepo_alert(self.queue)
            elif self._running == 0:
                return

    def hotkey_thread(self):
        """
        快捷键监听线程
        :return:
        """
        user32 = ctypes.windll.user32
        byref = ctypes.byref
        user32.RegisterHotKey(None, 10001, win32con.MOD_CONTROL,
                              win32con.VK_F1)
        user32.RegisterHotKey(None, 10002, win32con.MOD_CONTROL,
                              win32con.VK_F2)

        try:
            msg = ctypes.wintypes.MSG()
            while user32.GetMessageA(byref(msg), None, 0, 0) != 0:
                if msg.message == win32con.WM_HOTKEY:
                    if self._running == 1 and msg.wParam == 10001:
                        self.fight_stop()
                    elif self._running == 0 and msg.wParam == 10002:
                        self.setdebug(True)
                        self.fight_start()
                user32.TranslateMessage(byref(msg))
                user32.DispatchMessageA(byref(msg))
        finally:
            user32.UnregisterHotKey(None, 10001)
            user32.UnregisterHotKey(None, 10002)

    def boss_monitoring_thread(self):
        """
        点击发现超鬼王提示控制线程
        :return: 
        """ ""
        mode = None
        if self.listbox_timing_mode.get() == '超鬼王模式1':
            mode = 1
        elif self.listbox_timing_mode.get() == '超鬼王模式2':
            mode = 2
        logging('mode:%s' % mode)
        while True:
            if self._running == 1:
                self.fight.click_boss_notice(mode, self.queue)
                self.fight_stop()
                time.sleep(3)
                audio_play()
                messagebox.showinfo('就你鬼王多', '发现超鬼王啦!还不快冲鸭!')
                audio_stop()
                return
            elif self._running == 0:
                return

    def when_click_start_window(self):
        when_click_start = Toplevel(self)
        when_click_start.title('模式说明')

        var = self.listbox_mode.get()
        if var == '单刷':
            title = Label(when_click_start)
            title['text'] = '\n【 单刷模式 】'
            title.pack()
            desc = Message(when_click_start)
            desc['text'] = '\n请把游戏调整至如图所示界面,再点START\n'
            desc['width'] = 300
            desc.pack()

            ipath = resource_path('image/single.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.7), load.size)))
            render = ImageTk.PhotoImage(load)
            img = Label(when_click_start, image=render)
            img.image = render
            img.pack()
        elif var == '乘客':
            title = Label(when_click_start)
            title['text'] = '\n【 乘客模式 】'
            title.pack()
            desc = Message(when_click_start)
            desc['text'] = '\n建议接受了司机的默认邀请,再点START\n' + \
                           '因为我不会在战斗里帮你点开始...不服憋着\n_(:3」∠)_\n'
            desc['width'] = 300
            desc.pack()

            ipath = resource_path('image/passenger_accept.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.7), load.size)))
            render = ImageTk.PhotoImage(load)
            img = Label(when_click_start, image=render)
            img.image = render
            img.pack()
        elif var == '司机':
            title = Label(when_click_start)
            title['text'] = '\n【 司机模式 】'
            title.pack()
            desc = Message(when_click_start)
            desc['text'] = '\n建议对乘客发出默认邀请,回到组队界面再点START\n' + \
                           '因为自动发出邀请这个功能没写...不服憋着\n_(:3」∠)_\n'
            desc['width'] = 300
            desc.pack()

            ipath = resource_path('image/driver_invite.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.5), load.size)))
            render = ImageTk.PhotoImage(load)
            img1 = Label(when_click_start, image=render)
            img1.image = render
            img1.pack()

            ipath = resource_path('image/driver_form.png')
            load = PLI_Image.open(ipath)
            load = load.resize(tuple(map(lambda x: int(x * 0.5), load.size)))
            render = ImageTk.PhotoImage(load)
            img2 = Label(when_click_start, image=render)
            img2.image = render
            img2.pack()

        init_window_position(when_click_start, 1.3, 3)

    def what_is_clear_time(self):
        what_is_clear = Toplevel(self)
        what_is_clear.title('平均通关时间说明')

        title = Label(what_is_clear)
        title['text'] = '\n【 平均通关时间 】'
        title.pack()
        desc = Message(what_is_clear)
        desc['text'] = '\n平均通关时间是指在游戏中,从按下开始战斗到进入结算奖励界面所经过的时间(秒)\n' + \
                       '\n程序会在经过指定的时间后,再开始检测游戏画面是否进入了结算界面\n' + \
                       '\n如果设置一个较短的时间也可以,不过设置一个合理的时间,能节省你CPU资源\n(其实也没占多少_(:3」∠)_\n'
        desc['width'] = 300
        desc.pack()
        init_window_position(what_is_clear, 1.3, 3)

    def what_is_delay_time(self):
        what_is_delay = Toplevel(self)
        what_is_delay.title('战斗后等待时间说明')

        title = Label(what_is_delay)
        title['text'] = '\n【 战斗后等待时间 】'
        title.pack()
        desc = Message(what_is_delay)
        desc['text'] = '\n战斗后等待时间是指,在下一次战斗开始前强制等待的时间(秒)\n' + \
                       '\n填入的时间还会加上一个300毫秒以内的随机时间\n'
        desc['width'] = 300
        desc.pack()
        init_window_position(what_is_delay, 1.3, 3)

    def create_main(self):
        """
        窗体、控件绘制
        :return:
        """
        self.label_mode['text'] = '模式'
        self.var_mode.set('单刷')
        self.listbox_mode['textvariable'] = self.var_mode
        self.listbox_mode['width'] = 10
        self.listbox_mode['values'] = ["单刷", "乘客", "司机"]
        self.listbox_mode.bind("<<ComboboxSelected>>", self.turn_radio_on)
        self.label_mode.grid(row=1, column=0, sticky='E')
        self.listbox_mode.grid(row=1, column=1, sticky='W')

        self.button_mode_explain['text'] = '?'
        self.button_mode_explain['command'] = self.when_click_start_window
        self.button_mode_explain['relief'] = 'flat'
        self.button_mode_explain.grid(row=1, column=2, sticky='W')

        self.var_member.set(2)
        self.label_member['text'] = '车队人数'
        self.label_member.grid(row=2, column=0, sticky='E')
        self.radio1['text'] = '2人'
        self.radio1['variable'] = self.var_member
        self.radio1['value'] = 2
        # self.radio1['command'] = self.test_val3
        self.radio1.grid(row=2, column=1, sticky='W')
        self.radio1.configure(state='disabled')

        self.radio2['text'] = '3人'
        self.radio2['variable'] = self.var_member
        self.radio2['value'] = 3
        # self.radio2['command'] = self.test_val3
        self.radio2.grid(row=2, column=2, sticky='W')
        self.radio2.configure(state='disabled')

        self.label_clear_time['text'] = '平均通关时间'
        self.var_clear_time.set(self.clear_time)
        self.entry_clear_time['textvariable'] = self.var_clear_time
        self.label_clear_time.grid(row=3, column=0, sticky='E')
        self.entry_clear_time.grid(row=3, column=1, sticky='W', columnspan=2)

        self.button_clear_time_explain['text'] = '?'
        self.button_clear_time_explain['command'] = self.what_is_clear_time
        self.button_clear_time_explain['relief'] = 'flat'
        self.button_clear_time_explain.grid(row=3, column=2, sticky='E')

        self.label_delay_time['text'] = '战斗结束后等待时间'
        self.var_delay_time.set(self.delay_time)
        self.entry_delay_time['textvariable'] = self.var_delay_time
        self.label_delay_time.grid(row=4, column=0, sticky='E')
        self.entry_delay_time.grid(row=4, column=1, sticky='W', columnspan=2)

        self.button_delay_time_explain['text'] = '?'
        self.button_delay_time_explain['command'] = self.what_is_delay_time
        self.button_delay_time_explain['relief'] = 'flat'
        self.button_delay_time_explain.grid(row=4, column=2, sticky='E')

        self.label_offer['text'] = '好友发来悬赏'
        self.var_offer_mode.set('接受')
        self.listbox_offer_mode['textvariable'] = self.var_offer_mode
        self.listbox_offer_mode['width'] = 10
        self.listbox_offer_mode['values'] = ["接受", "拒绝"]
        # self.listbox_offer_mode.bind("<<ComboboxSelected>>", self.turn_entry_on)
        self.label_offer.grid(row=5, column=0, sticky='E')
        self.listbox_offer_mode.grid(row=5, column=1, sticky='W')

        self.label_timing_mode['text'] = '预定结束'
        self.var_timing_mode.set('无')
        self.listbox_timing_mode['textvariable'] = self.var_timing_mode
        self.listbox_timing_mode['width'] = 10
        self.listbox_timing_mode['values'] = [
            "无", "定时[分钟]", "场数", "超鬼王模式1", "超鬼王模式2"
        ]
        self.listbox_timing_mode.bind("<<ComboboxSelected>>",
                                      self.turn_entry_on)
        self.label_timing_mode.grid(row=6, column=0, sticky='E')
        self.listbox_timing_mode.grid(row=6, column=1, sticky='W')

        self.var_timing_value.set('')
        self.entry_timing_value['textvariable'] = self.var_timing_value
        self.entry_timing_value['width'] = 5
        self.entry_timing_value.configure(state='disabled')
        self.entry_timing_value.grid(row=6, column=2, sticky='W')

        self.label_done_action_mode['text'] = '预定结束后动作'
        self.var_done_action_mode.set('')
        self.listbox_done_action_mode[
            'textvariable'] = self.var_done_action_mode
        self.listbox_done_action_mode['width'] = 10
        self.listbox_done_action_mode.configure(state='disabled')
        self.listbox_done_action_mode['values'] = ["关闭游戏窗口", "仅停止挂机"]
        # self.listbox_done_action_mode.bind("<<ComboboxSelected>>", self.turn_entry_on)
        self.label_done_action_mode.grid(row=7, column=0, sticky='E')
        self.listbox_done_action_mode.grid(row=7, column=1, sticky='W')

        self.start_ctn['text'] = 'START'
        self.start_ctn['width'] = 10
        self.start_ctn['height'] = 2
        self.start_ctn['command'] = self.fight_start
        self.start_ctn['relief'] = 'groove'
        self.start_ctn.grid(row=0, column=0, sticky='E')

        self.stop_ctn['text'] = 'STOP'
        self.stop_ctn['width'] = 10
        self.stop_ctn['height'] = 2
        self.stop_ctn['command'] = self.fight_stop
        self.stop_ctn['relief'] = 'groove'
        self.stop_ctn.grid(row=0, column=1, sticky='W')
        self.stop_ctn.configure(state='disabled')

        self.info_box['width'] = 40
        self.info_box['height'] = 20
        self.info_box.grid(row=1, column=0, columnspan=2)
        self.info_box.see(END)
        var = 'Build ' + self.version
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)
        var = '请授予此程序管理员权限运行,否则在游戏窗口内鼠标无法被控制'
        self.info_box.mark_set('insert', END)
        self.info_box.insert('insert', str(var) + '\n')
        self.info_box.see(END)
コード例 #11
0
class SpinDelight(Frame):

    def __init__(self):
        Frame.__init__(self)
        self.master.geometry("1020x600+150+50")
        self.master.title("Spin Delight 1.0 - Copyright (c) Robin Thomas")
        self.master.resizable(0,0)
        self.grid()
        self.brwe = Button(self, text = "Browse", command = self.open_file, width = 10, relief = "groove")
        self.rtxt = Label(self, text="Input Text:")
        self.txt1 = ScrolledText(self, width = 50, height = 25)
        self.txt1.bind("<Control-Key-a>", self.select_all_txt1)
        self.txt1.bind("<Control-Key-A>", self.select_all_txt1)
        self.spin = Button(self, text = "Spin", command = self.spin_file, width = 10, relief = "groove")
        self.stxt = Label(self, text="Spun Text:")
        self.txt2 = ScrolledText(self, width = 50, height = 25)
        self.txt2.bind("<Control-Key-a>", self.select_all_txt2)
        self.txt2.bind("<Control-Key-A>", self.select_all_txt2)
        self.brwe.grid(row = 2, column = 2, pady = 15)
        self.rtxt.grid(row = 2, column = 0, padx = 25)
        self.txt1.grid(row = 3, column = 0, columnspan = 10, padx = 25)
        self.spin.grid(row = 3, column = 12)
        self.stxt.grid(row = 2, column = 13, padx = 25, pady = 5)
        self.txt2.grid(row = 3, column = 13, columnspan = 10, padx = 25)

    def select_all_txt1(self,event):
        self.txt1.tag_add(SEL, "1.0", END)
        self.txt1.mark_set(INSERT, "1.0")
        self.txt1.see(INSERT)
        return 'break'

    def select_all_txt2(self,event):
        self.txt2.tag_add(SEL, "1.0", END)
        self.txt2.mark_set(INSERT, "1.0")
        self.txt2.see(INSERT)
        return 'break'

    def open_file(self):
        fname = askopenfilename(filetypes=(("Text files", "*.txt"), ("All files", "*.*") ))
        if fname:
            try:
                self.txt1.delete(0.0, END)
                f = open(fname,'r')
                self.txt1.insert(INSERT,f.read())
            except:
                showerror("Open Source File", "Failed to read file\n'%s'" % fname)
    
    def spin_file(self):
        txt = self.txt1.get("1.0", END)
        self.txt2.delete(0.0, END)
        if len(txt):
            try:
                words = sub(r'([.,?])+', r' \1 ', sub(r'[^a-zA-Z0-9 .,?]+', ' ', txt)).split()
                w1 = words[0]
                z = [(words[j - 1], words[j]) for j in range(1, len(words))]
                values = self.generate_dict(z, w1)
                string = self.generate_sent(values)
                if len(string):
                    self.txt2.insert(INSERT, string)
                else:
                    showerror("Error", "Insufficient data to spin !!")
            except:
                showerror("Error", "Nothing to spin !!")

                    
    def generate_dict(self, x, w1):
        values = {'.': [w1]}
        for (wa, wb) in x:
            if wa in values:
                values[wa].append(wb)
            else:
                values[wa] = [wb]
        return values


    def generate_sent(self, values):
        w1 = '.'
        w2 = choice(values[w1])
        string = w2
        values[w1].remove(w2)
        while values:
            w1 = w2
            if len(values[w1]):
                w2 = choice(values[w1])
            else:
                del values[w1]
                w1 = '.'
                break
            if w2 in ('.', ',', '?'):
                string += w2
            else:
                string += " " + w2
            values[w1].remove(w2)
        return string
コード例 #12
0
ファイル: editor_window.py プロジェクト: ra2003/PyEditor
class EditorWindow:
    def __init__(self):
        self.root = Tk(className="EDITOR")

        self.python_files = PythonFiles(self)

        self.root.geometry("%dx%d+%d+%d" % (
            self.root.winfo_screenwidth() * 0.5,
            self.root.winfo_screenheight() * 0.4,
            # self.root.winfo_screenwidth() * 0.1, self.root.winfo_screenheight() * 0.1
            0,
            0))

        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)

        self.base_title = "PyEditor v%s" % __version__
        self.root.title(self.base_title)

        self.text_frame = Frame(master=self.root)

        self.text = ScrolledText(master=self.root, background="white")
        self.text.bind("<Tab>", self.tab_event)
        self.text.grid(row=0, column=0, sticky=NSEW)

        #TODO: find a right height
        self.exec_output = ScrolledText(master=self.root,
                                        height=10,
                                        state=DISABLED,
                                        background="#dddddd")

        # for information text like load/save/run:
        self.exec_output.tag_config(
            "info",
            foreground="#0000ff",
            #background="#eeeeee"
        )

        self.exec_output.grid(row=1, column=0, sticky=NSEW)

        self.text.focus_set()

        # self.script_list = ScriptList(self)

        p = Percolator(self.text)
        d = ColorDelegator()
        p.insertfilter(d)

        # add statusbar to window
        self.init_statusbar()

        # add menu to window
        self.init_menu()

        # Add special RPi/Minecraft features, if available
        self.rpi = MinecraftSpecials(self)

        if self.rpi.mcpi_available:
            # minecraft is available
            self.set_content(DEFAULT_MCPI_SCRIPT)
            if not self.rpi.is_running:
                self.rpi.startup_minecraft()
        else:
            # no minecraft available
            self.set_content(DEFAULT_SCRIPT)

        self.root.update()

    ###########################################################################
    # Status bar

    FILENAME_LABEL = "filename"

    def get_filename(self):
        filename = self.status_bar.get_textEntry(self.FILENAME_LABEL)
        return filename

    def set_filename(self, filename):
        filename = os.path.split(filename)[-1]
        self.status_bar.set_textEntry(self.FILENAME_LABEL, filename)

    def update_filename(self, event=None):
        filename = self.get_filename()
        if filename and not filename.endswith(".py"):
            filename = "%s.py" % filename
            self.set_filename(filename)

    def init_statusbar(self):
        self.status_bar = MyMultiStatusBar(self.root)
        if sys.platform == "darwin":
            # Insert some padding to avoid obscuring some of the statusbar
            # by the resize widget.
            self.status_bar.set_label('_padding1', '    ', side=RIGHT)
        self.status_bar.grid(row=2, column=0)

        self.text.bind("<<set-line-and-column>>", self.set_line_and_column)
        self.text.event_add("<<set-line-and-column>>", "<KeyRelease>",
                            "<ButtonRelease>")
        self.text.after_idle(self.set_line_and_column)
        self.status_bar.new_textEntry(self.FILENAME_LABEL,
                                      'unnamed.py',
                                      callback=self.update_filename)

    def set_line_and_column(self, event=None):
        line, column = self.text.index(INSERT).split('.')
        self.status_bar.set_label('column', 'Column: %s' % column)
        self.status_bar.set_label('line', 'Line: %s' % line)

    ###########################################################################
    # Menu

    def init_menu(self):
        self.menubar = Menu(self.root)
        filemenu = Menu(self.menubar, tearoff=0)

        self.menubar.add_command(label="Run", command=self.command_run)
        self.menubar.add_command(label="Load", command=self.command_load_file)
        # filemenu.add_command(label="Load", command=self.command_load_file)
        self.menubar.add_command(label="Save", command=self.command_save_file)
        self.menubar.add_command(label="Exit", command=self.root.quit)
        #
        # self.menubar.add_cascade(label="File", menu=filemenu)

        self.root.config(menu=self.menubar)

    def command_run(self):
        source_listing = self.get_content()
        self.exec_output.config(state=NORMAL)
        self.exec_output.delete("1.0", END)
        filename = self.get_filename()
        self.python_files.run_source_listing(source_listing, filename)
        log.debug("Adding to terminal out")
        #self.exec_output.insert(END, "Run Script")
        self.exec_output.config(state=DISABLED)

    def command_load_file(self):
        infile = askopenfile(
            parent=self.root,
            mode="r",
            title="Select a Python file to load",
            filetypes=DEFAULT_FILETYPES,
            initialdir=BASE_PATH,
        )
        if infile is not None:
            source_listing = infile.read()
            infile.close()
            self.set_content(source_listing)

            self.set_filename(infile.name)  # FIXME: insert only name!
            self.append_feedback_to_output("Script %r loaded." % infile.name)

    def command_save_file(self):
        self.update_filename()  # FIXME: add .py if missing

        content = self.get_content()
        filename = self.get_filename()
        filepath = os.path.join(BASE_PATH, filename)

        if os.path.isfile(filepath):
            self.python_files.move_to_backup(filepath)

        with open(filepath, "w") as f:
            f.write(content)

        self.append_feedback_to_output("Save to: %r" % filepath)

    ###########################################################################

    def get_content(self):
        content = self.text.get("1.0", END)
        content = content.strip()
        return content

    def set_content(self, source_listing):
        self.text.delete("1.0", END)

        log.critical("insert %i Bytes listing.", len(source_listing))
        self.text.insert(END, source_listing)

        self.text.mark_set(INSERT, '1.0')  # Set cursor at start
        self.text.focus()

    def append_exec_output(self, text):
        self.exec_output.config(state=NORMAL)
        self.exec_output.insert(END, text)
        self.exec_output.config(state=DISABLED)

    def append_feedback_to_output(self, text):
        text = "%s\n" % text.rstrip()
        self.exec_output.config(state=NORMAL)
        self.exec_output.insert(END, text, "info")
        self.exec_output.config(state=DISABLED)

    ###########################################################################

    indent_pad = " " * 4

    def tab_event(self, event):
        log.debug("Tab event")
        self.text.insert("insert", self.indent_pad)
        return BREAK
コード例 #13
0
class PiDiteur(Frame):
    def __init__(self, parent=None, nom_fichier=None):
        Frame.__init__(self, parent)
        self.pack(expand=YES, fill=BOTH)
        self.fichier_courant = nom_fichier
        self.nom_editeur = self.__class__.__name__
        self.creer_composants()
        self.gerer_evenements()
        self.afficher_fichier(nom_fichier)

    def creer_composants(self):
        self.creer_zone_texte()
        self.creer_barre_menu()
        self.creer_barre_texte()

    def creer_zone_texte(self):
        self.zone_texte = ScrolledText(
            self,
            padx=5,
            pady=5,
            wrap=WORD,
            relief=SUNKEN,
            font=('courier', 14, 'normal'),
            bg='white',
            fg='black',
            undo=True,
            autoseparators=True,
        )
        self.zone_texte.pack(side=TOP, fill=BOTH, expand=YES)

    def creer_barre_texte(self):
        self.barre_texte = Label(self, relief=SUNKEN, bd=2)
        self.barre_texte.pack(side=BOTTOM, fill=X)

    def creer_barre_menu(self):
        self.barre_menu = Menu(self.master)
        self.master.config(menu=self.barre_menu)
        self.menu_fichier()
        self.menu_editer()

    def menu_fichier(self):
        menu = Menu(self.barre_menu, tearoff=False)
        menu.add_command(label='Ouvrir (Ctrl+o)', command=self.ouvrir)
        menu.add_command(label='Nouveau (Ctrl+n)',
                         command=self.afficher_fichier)
        menu.add_command(label='Enregistrer (Ctrl+s)',
                         command=self.enregistrer)
        menu.add_command(label='Enregistrer sous',
                         command=self.enregistrer_sous)
        menu.add_command(label='Fermer (Alt+F4)', command=self.quitter)
        self.barre_menu.add_cascade(label='Fichier', menu=menu)

    def menu_editer(self):
        menu = Menu(self.barre_menu, tearoff=False)
        menu.add_command(label='Couper (Ctrl+x)',
                         command=lambda: self.copier(True))
        menu.add_command(label='Copier (Ctrl+c)', command=self.copier)
        menu.add_command(label='Coller (Ctrl+v)', command=self.coller)
        menu.add_command(label='Chercher (Ctrl+f)', command=self.chercher)
        self.barre_menu.add_cascade(label='Edition', menu=menu)

    def gerer_evenements(self):
        self.master.bind('<Control-Key-f>', lambda ev: self.chercher())
        self.master.bind('<Control-Key-o>', lambda ev: self.ouvrir())
        self.master.bind('<Control-Key-s>', lambda ev: self.enregistrer())
        self.master.bind('<Control-Key-n>', lambda ev: self.afficher_fichier())
        self.master.protocol("WM_DELETE_WINDOW", self.quitter)

    def afficher_fichier(self, nom_fichier=None):
        if nom_fichier:
            with open(nom_fichier, 'r', encoding='utf-8') as f:
                texte = f.read()
            self.barre_texte.config(text=nom_fichier)
            self.master.title('%s - %s' % (self.nom_editeur, nom_fichier))
        else:
            texte = ''
            nouveau = 'Nouveau fichier'
            self.barre_texte.config(text=nouveau)
            self.master.title('%s - %s' % (self.nom_editeur, nouveau))
        self.fichier_courant = nom_fichier
        self.zone_texte.delete('0.0', END)
        self.zone_texte.insert('0.0', texte)
        self.zone_texte.mark_set(INSERT, '0.0')
        self.zone_texte.focus()
        self.update()

    def ouvrir(self):
        fichier = askopenfilename()
        if fichier:
            self.afficher_fichier(nom_fichier=fichier)

    def enregistrer(self):
        if not self.fichier_courant:
            fichier = asksaveasfilename()
            if fichier:
                self.fichier_courant = fichier
            else:
                return
        fichier = self.fichier_courant
        texte = self.zone_texte.get('0.0', END)
        with open(fichier, 'w', encoding='utf-8') as f:
            f.write(texte)
        self.barre_texte.config(text=fichier)
        self.master.title('%s - %s' % (self.nom_editeur, fichier))

    def enregistrer_sous(self):
        fichier = asksaveasfilename()
        if fichier:
            self.fichier_courant = fichier
            self.enregistrer()

    def copier(self, couper=False):
        try:
            texte = self.zone_texte.get(SEL_FIRST, SEL_LAST)
        except TclError:
            showinfo(message='Selectionnez du texte à copier !')
            return
        if couper:
            self.zone_texte.delete(SEL_FIRST, SEL_LAST)
        self.clipboard_clear()
        self.clipboard_append(texte)

    def coller(self):
        try:
            texte = self.selection_get(selection='CLIPBOARD')
            self.zone_texte.insert(INSERT, texte)
        except TclError:
            pass

    def chercher(self):
        caractere = askstring('Recherche',
                              'Tapez votre chaîne de caractères :')
        if caractere:
            trouve = self.zone_texte.search(caractere, INSERT, END)
            if trouve:
                aprestrouve = trouve + ('+%dc' % len(caractere))
                self.zone_texte.tag_add(SEL, trouve, aprestrouve)
                self.zone_texte.mark_set(INSERT, aprestrouve)
                self.zone_texte.see(INSERT)
                self.zone_texte.focus()

    def quitter(self):
        if askyesno(
                'Confirmation',
                'Voulez-vous vraiment fermer {0} ?'.format(self.nom_editeur)):
            Frame.quit(self)
コード例 #14
0
ファイル: messages.py プロジェクト: ehmurray8/KytonUI
class LogView(ttk.Frame):
    """
    Widget for the program log messages, ttk Frame implementation.

    :ivar List[MessageType] message_types: the MessageTypes to include in the filter combobox
    :ivar List[MessageType] all_types: a list of all the message types
    :ivar List[MessageDelay] message_delays: a list of all of the message delays
    :ivar Dict[str: collections.deque] messages: mapping of message type title string to dequeues of fixed
                                                 size containing messages' body
    :ivar Dict[str: float] message_time: message body without timestamp mapped to time in s
    :ivar Dict[str: MessageDelay] message_time_filer: message body without timestamp mapped to MessageDelay
    :ivar float first_click_time: the time the header text was first clicked (Used for developer messages)
    :ivar int num_clicks: the number of times the header text was clicked within the specified time (Used for dev msgs)
    :ivar bool showing: True if developer messages are in the filter, False otherwise
    :ivar MessageType current_filter: the current message type to filter messages
    :ivar ttk.Combobox filter_box: the combobox tkinter widget used for selecting a filter level
    :ivar ttk.ScrolledText log_view: the scrolled text tkinter widget used for displaying log messages
    """
    def __init__(self, container: ttk.Frame, **kwargs):
        """
        Setup the log view widgets, and the data structures for storing messages.

        :param container: parent frame
        :param kwargs: additional arguments for the Frame
        """
        super().__init__(container, **kwargs)
        self.message_types = [
            MessageType.INFO, MessageType.WARNING, MessageType.ERROR
        ]
        self.all_types = self.message_types + [
            MessageType.CRITICAL, MessageType.DEVELOPER
        ]
        self.message_delays = [
            MessageDelay.FIRST, MessageDelay.SHORT, MessageDelay.LONG,
            MessageDelay.MAX
        ]

        self.messages = {}
        self.message_time = SizeDict(maxsize=1000)  # type: Dict[str, float]
        self.message_time_filter = SizeDict(
            maxsize=1000)  # type: Dict[str, MessageDelay]

        self.first_click_time = time.time()
        self.num_clicks = 0
        self.showing = False

        self.current_filter = MessageType.INFO
        for t in self.all_types:
            self.messages[t.name.title()] = collections.deque(maxlen=25000)
        self.pack()
        header_frame = ttk.Frame(self)
        header_frame.pack(expand=True, fill=tk.BOTH)
        header_lbl = ttk.Label(header_frame, text="Program Log")
        header_lbl.pack(anchor=tk.W, side=tk.LEFT)
        header_lbl.bind("<Button-1>", self.click_handler)

        self.filter_box = ttk.Combobox(
            header_frame,
            values=[_type.name.title() for _type in self.message_types])
        self.filter_box.config(state="readonly")
        self.filter_box.set(MessageType.INFO.name.title())
        self.filter_box.pack(anchor=tk.E, side=tk.RIGHT)

        self.filter_box.bind("<<ComboboxSelected>>", self.filter_msg)
        self.filter_box.pack(anchor=tk.E)
        self.log_view = ScrolledText(self,
                                     wrap=tk.WORD,
                                     background=LOG_BACKGROUND_COLOR)
        for t in self.all_types:
            self.log_view.tag_configure(t.name,
                                        font=Font(family="Helvetica", size=10),
                                        foreground=t.color)
        self.log_view.pack(expand=True, fill=tk.BOTH)
        ttk.Button(self, text="Export",
                   command=self.export).pack(anchor=tk.CENTER)

    def click_handler(self, _):
        """Click handler for the Program Log header to allow the user to view developer messages."""
        if time.time() - self.first_click_time > 15.:
            self.first_click_time = time.time()
            self.num_clicks = 0
        else:
            self.num_clicks += 1

        if self.num_clicks == 10:
            self.num_clicks = 0
            if not self.showing:
                self.message_types.append(MessageType.DEVELOPER)
            else:
                self.message_types.remove(MessageType.DEVELOPER)
            self.showing = not self.showing
            self.filter_box.config(
                values=[_type.name.title() for _type in self.message_types])

    def export(self):
        """Export the messages to a log text file in the log folder."""
        t = time.time()
        timestamp = datetime.datetime.fromtimestamp(t).strftime(
            "%Y%m%dT%H%M%S")
        if not os.path.isdir("log"):
            os.mkdir("log")
        with open(os.path.join("log", "{}_log.txt".format(str(timestamp))),
                  "w") as f:
            _type = MessageType.INFO.filter_num
            if MessageType.DEVELOPER in self.message_types:
                _type = MessageType.DEVELOPER.filter_num
            msgs = self.get_msgs(_type)
            msgs_sorted = sort_messages(msgs)
            for t, (text, tag) in msgs_sorted:
                f.write(text)

    def clear(self):
        """Clear the log view scrolled text."""
        self.log_view.config(state='normal')
        for t in self.all_types:
            try:
                self.log_view.tag_remove(t.name, "1.0", tk.END)
            except tk.TclError:
                pass
        self.log_view.delete("1.0", tk.END)

    def add_msg(self, msg: Message):
        """
        Add the msg to the log view, and the message store data structures.

        :param msg: message to add to the log view
        """
        self.message_time[msg.msg] = msg.time
        self.messages[msg.type.name.title()].append((msg.time, msg.text))
        if msg.type.filter_num <= self.current_filter.filter_num:
            self.write_msg(msg.text, msg.type.name)

    def write_msg(self, text: str, tag: str, start: str = "1.0"):
        """
        Write the text to the Scrolled Text tkinter widget, color it based on the tag, add it to the beginning
        if start is '1.0', if start tk.END add it to the end.

        :param text: text to write to the scrolled text view
        :param tag: name of the tag that defines the style for the text, based on MessageType
        :param start: the position to start writing the text
        """
        self.log_view.config(state='normal')
        self.log_view.insert(start, text)
        self.highlight_pattern(text, tag)
        self.log_view.config(state='disabled')

    def highlight_pattern(self,
                          pattern: str,
                          tag: str,
                          start: str = "1.0",
                          end: str = "end",
                          regexp: bool = False):
        """
        Apply the given tag to all text that matches the given pattern.

        :param pattern: pattern to match when looking to format the text using the tag.
        :param tag: tkinter scrolled text tag corresponding to a tk font
        :param start: where to start looking for the pattern from
        :param end: where to end looking for the pattern
        :param regexp: If True, pattern will be treated as a Tcl regular expression
        """
        start = self.log_view.index(start)
        end = self.log_view.index(end)
        self.log_view.mark_set("matchStart", start)
        self.log_view.mark_set("matchEnd", start)
        self.log_view.mark_set("searchLimit", end)

        count = tk.IntVar()
        while True:
            index = self.log_view.search(pattern,
                                         "matchEnd",
                                         "searchLimit",
                                         count=count,
                                         regexp=regexp)
            if index == "":
                break
            if count.get() == 0:
                break
            self.log_view.mark_set("matchStart", index)
            self.log_view.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
            self.log_view.tag_add(tag, "matchStart", "matchEnd")

    def get_msgs(self, filter_num: int) -> collections.OrderedDict:
        """
        Get all of the messages that have a filter number less than or equal the filter number.

        :param filter_num: the number used for filtering messages
        :return: time mapped to (text, tag) for all filtered messages
        """
        msgs = {}
        for _type in self.all_types:
            if _type.filter_num <= filter_num:
                for msg in self.messages[_type.name.title()]:
                    msgs[msg[0]] = (msg[1], _type.name)
        return collections.OrderedDict(msgs.items(), key=lambda t: t[0])

    def filter_msg(self, _):
        """Filters messages when the filter combobox value is changed."""
        for t in self.all_types:
            selection = self.filter_box.current()
            if t.name.title() == self.message_types[selection].name.title():
                self.current_filter = t
        msgs = self.get_msgs(self.current_filter.filter_num)
        self.clear()
        msgs_sorted = sort_messages(msgs)
        for t, (text, tag) in msgs_sorted:
            self.write_msg(text, tag, start=tk.END)
コード例 #15
0
class PiDiteur(Frame):
    def __init__(self, parent=None, nom_fichier=None):
        Frame.__init__(self, parent)
        self.pack(expand=YES, fill=BOTH)
        self.fichier_courant = nom_fichier
        self.nom_editeur = self.__class__.__name__
        self.creer_composants()
        self.gerer_evenements()
        self.afficher_fichier(nom_fichier)

    def creer_composants(self):
        self.creer_zone_texte()
        self.creer_barre_menu()
        self.creer_barre_texte()

    def creer_zone_texte(self):
        self.zone_texte = ScrolledText(
            self,
            padx=5,
            pady=5,
            wrap=WORD,
            relief=SUNKEN,
            font=("courier", 14, "normal"),
            bg="white",
            fg="black",
            undo=True,
            autoseparators=True,
        )
        self.zone_texte.pack(side=TOP, fill=BOTH, expand=YES)

    def creer_barre_texte(self):
        self.barre_texte = Label(self, relief=SUNKEN, bd=2)
        self.barre_texte.pack(side=BOTTOM, fill=X)

    def creer_barre_menu(self):
        self.barre_menu = Menu(self.master)
        self.master.config(menu=self.barre_menu)
        self.menu_fichier()
        self.menu_editer()

    def menu_fichier(self):
        menu = Menu(self.barre_menu, tearoff=False)
        menu.add_command(label="Ouvrir (Ctrl+o)", command=self.ouvrir)
        menu.add_command(label="Nouveau (Ctrl+n)",
                         command=self.afficher_fichier)
        menu.add_command(label="Enregistrer (Ctrl+s)",
                         command=self.enregistrer)
        menu.add_command(label="Enregistrer sous",
                         command=self.enregistrer_sous)
        menu.add_command(label="Fermer (Alt+F4)", command=self.quitter)
        self.barre_menu.add_cascade(label="Fichier", menu=menu)

    def menu_editer(self):
        menu = Menu(self.barre_menu, tearoff=False)
        menu.add_command(label="Couper (Ctrl+x)",
                         command=lambda: self.copier(True))
        menu.add_command(label="Copier (Ctrl+c)", command=self.copier)
        menu.add_command(label="Coller (Ctrl+v)", command=self.coller)
        menu.add_command(label="Chercher (Ctrl+f)", command=self.chercher)
        self.barre_menu.add_cascade(label="Edition", menu=menu)

    def gerer_evenements(self):
        self.master.bind("<Control-Key-f>", lambda ev: self.chercher())
        self.master.bind("<Control-Key-o>", lambda ev: self.ouvrir())
        self.master.bind("<Control-Key-s>", lambda ev: self.enregistrer())
        self.master.bind("<Control-Key-n>", lambda ev: self.afficher_fichier())
        self.master.protocol("WM_DELETE_WINDOW", self.quitter)

    def afficher_fichier(self, nom_fichier=None):
        if nom_fichier:
            with open(nom_fichier, "r", encoding="utf-8") as f:
                texte = f.read()
            self.barre_texte.config(text=nom_fichier)
            self.master.title("%s - %s" % (self.nom_editeur, nom_fichier))
        else:
            texte = ""
            nouveau = "Nouveau fichier"
            self.barre_texte.config(text=nouveau)
            self.master.title("%s - %s" % (self.nom_editeur, nouveau))
        self.fichier_courant = nom_fichier
        self.zone_texte.delete("0.0", END)
        self.zone_texte.insert("0.0", texte)
        self.zone_texte.mark_set(INSERT, "0.0")
        self.zone_texte.focus()
        self.update()

    def ouvrir(self):
        fichier = askopenfilename()
        if fichier:
            self.afficher_fichier(nom_fichier=fichier)

    def enregistrer(self):
        if not self.fichier_courant:
            fichier = asksaveasfilename()
            if fichier:
                self.fichier_courant = fichier
            else:
                return
        fichier = self.fichier_courant
        texte = self.zone_texte.get("0.0", END)
        with open(fichier, "w", encoding="utf-8") as f:
            f.write(texte)
        self.barre_texte.config(text=fichier)
        self.master.title("{} - {}".format(self.nom_editeur, fichier))

    def enregistrer_sous(self):
        fichier = asksaveasfilename()
        if fichier:
            self.fichier_courant = fichier
            self.enregistrer()

    def copier(self, couper=False):
        try:
            texte = self.zone_texte.get(SEL_FIRST, SEL_LAST)
        except TclError:
            showinfo(message="Selectionnez du texte à copier !")
            return
        if couper:
            self.zone_texte.delete(SEL_FIRST, SEL_LAST)
        self.clipboard_clear()
        self.clipboard_append(texte)

    def coller(self):
        try:
            texte = self.selection_get(selection="CLIPBOARD")
            self.zone_texte.insert(INSERT, texte)
        except TclError:
            pass

    def chercher(self):
        caractere = askstring("Recherche",
                              "Tapez votre chaîne de caractères :")
        if caractere:
            trouve = self.zone_texte.search(caractere, INSERT, END)
            if trouve:
                aprestrouve = trouve + ("+%dc" % len(caractere))
                self.zone_texte.tag_add(SEL, trouve, aprestrouve)
                self.zone_texte.mark_set(INSERT, aprestrouve)
                self.zone_texte.see(INSERT)
                self.zone_texte.focus()

    def quitter(self):
        if askyesno("Confirmation",
                    f"Voulez-vous vraiment fermer {self.nom_editeur} ?"):
            Frame.quit(self)
コード例 #16
0
class EditorTab(tk.Frame):
    def __init__(self, master, filepath: str, new_file=False):
        tk.Frame.__init__(self, master)
        self.new_file = new_file
        self.filepath = filepath
        self.filename = get_filename(filepath) if not new_file else filepath
        self.master = master
        self.modified = False
        self.text_editor = ScrolledText(self,
                                        font=("", 15),
                                        undo=True,
                                        maxundo=-1,
                                        wrap="none")
        self.text_editor.config(highlightthickness=0, bd=0)
        self.text_editor.grid(row=0, column=1, sticky=tk.NSEW)
        self.scrollbar_x = tk.Scrollbar(self,
                                        orient=tk.HORIZONTAL,
                                        command=self.text_editor.xview)
        self.scrollbar_x.grid(row=1, column=0, columnspan=2, stick=tk.EW)
        self.text_editor.configure(xscrollcommand=self.scrollbar_x.set)
        self.line_nb_canvas = tk.Canvas(self,
                                        bg=self.text_editor.cget("bg"),
                                        bd=0,
                                        highlightthickness=0)
        self.line_nb_canvas.grid_propagate(False)
        self.line_nb_canvas.grid(row=0, column=0, sticky=tk.NS)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)
        self.default_file_content = str()

    @property
    def id(self) -> str:
        return str(self)

    def get(self) -> str:
        return self.text_editor.get("1.0", "end-1c")

    @property
    def lines(self):
        return self.get().splitlines()

    def update_lines(self):
        self.line_nb_canvas.delete("all")
        font = self.text_editor.cget("font")
        i = 1
        y = 0
        while self.text_editor.compare(f"{i}.0", "<", tk.END):
            dline = self.text_editor.dlineinfo(f"{i}.0")
            if dline:
                y = dline[1]
            else:
                y = -20
            self.line_nb_canvas.create_text(1,
                                            y,
                                            anchor="ne",
                                            text=str(i),
                                            font=font,
                                            fill=Color(175, 175, 175).hex)
            i += 1
        all_boxes = [
            self.line_nb_canvas.bbox(item)
            for item in self.line_nb_canvas.find_all()
        ]
        max_width = (min(box[2] - box[0] for box in all_boxes)) * 4
        self.line_nb_canvas.configure(width=max_width + 20)
        for item in self.line_nb_canvas.find_all():
            self.line_nb_canvas.move(item, max_width, 0)

    def get_filename_from_champion_name(self) -> (str, None):
        content = self.lines
        for line in content:
            if line.startswith(".name"):
                first_quote = line.find('"')
                if first_quote == -1:
                    break
                second_quote = line.find('"', first_quote + 1)
                if second_quote == -1:
                    break
                name = line[first_quote + 1:second_quote]
                if len(name) == 0:
                    break
                return name.replace(" ", "_").lower() + ".s"
        return None

    def open(self) -> bool:
        if not os.path.isfile(self.filepath):
            showwarning("An error occurs...", f"Can't open '{self.filepath}'")
            return False
        with open(self.filepath, "r") as file:
            self.default_file_content = file.read()
            self.text_editor.insert("1.0", self.default_file_content)
            self.text_editor.edit_reset()
            self.text_editor.edit_modified(False)
        self.set_modified_status(False, on_opening=True)
        return True

    def save(self) -> bool:
        if self.new_file:
            return self.master.save_file_as()
        self.default_file_content = self.text_editor.get("1.0", "end-1c")
        with open(self.filepath, "w") as file:
            file.write(self.default_file_content)
        self.set_modified_status(False)
        self.text_editor.edit_modified(False)
        return True

    def save_as(self, filepath: str) -> bool:
        self.master.files_opened[filepath] = self.master.files_opened[
            self.filepath]
        self.master.files_opened.pop(self.filepath)
        self.filepath = filepath
        self.filename = get_filename(filepath)
        self.new_file = False
        return self.save()

    def close(self) -> bool:
        if self.modified:
            save_file = askyesnocancel(
                f"{self.filename} - Modifications not saved",
                "This file was modified and was not saved.\nDo you want to save this file ?"
            )
            if save_file is None:
                return False
            if save_file and not self.save():
                return False
        self.master.forget(self.id)
        self.master.files_opened.pop(self.filepath)
        return True

    def undo(self) -> None:
        try:
            self.text_editor.edit_undo()
        except tk.TclError:
            pass

    def redo(self) -> None:
        try:
            self.text_editor.edit_redo()
        except tk.TclError:
            pass

    def copy_to_clipboard(self, remove_from_editor=False) -> bool:
        try:
            txt = self.text_editor.get("sel.first", "sel.last")
            self.clipboard_clear()
            self.clipboard_append(txt)
            if remove_from_editor:
                self.text_editor.delete("sel.first", "sel.last")
        except tk.TclError:
            return False
        return True

    def paste_from_clipboard(self) -> None:
        try:
            self.text_editor.get("sel.first", "sel.last")
        except tk.TclError:
            pass
        else:
            self.text_editor.mark_set("insert", "sel.first")
            self.text_editor.delete("sel.first", "sel.last")
        self.text_editor.insert("insert", self.clipboard_get())

    def check_file_status(self) -> None:
        actual = self.text_editor.get("1.0", "end-1c")
        if self.text_editor.edit_modified():
            self.text_editor.edit_separator()
            self.text_editor.edit_modified(False)
        self.set_modified_status(actual != self.default_file_content)

    def set_modified_status(self, status: bool, on_opening=False) -> None:
        self.modified = status
        if not on_opening:
            if self.modified and not self.new_file:
                self.master.tab(self.id, text=self.filename + " - Modified")
            else:
                self.master.tab(self.id, text=self.filename)

    def add(self) -> None:
        self.master.add(self, text=self.filename)

    def select(self) -> None:
        self.master.select(self.id)
        self.text_editor.focus_set()

    def set_template(self, name: str, comment: str, author: str) -> None:
        content = [
            line for line in self.lines
            if not line.startswith(".name") and not line.startswith(".comment")
        ]
        header = [
            "#", "# {name} champion for CoreWar".format(name=name), "#",
            "# By {author}".format(author=author), "#",
            "# {date}".format(date=date.today().strftime("%c")), "#", ""
            ".name \"{name}\"".format(name=name),
            ".comment \"{comment}\"".format(comment=comment), ""
        ]
        content = header + content
        self.text_editor.delete("1.0", "end")
        self.text_editor.insert("1.0", "\n".join(content))

    def insert_command(self, cmd: str) -> None:
        insert = self.text_editor.index(tk.INSERT).split(".")
        end_of_line = insert[0] + "." + tk.END
        self.text_editor.insert(end_of_line, "\n" + cmd)
コード例 #17
0
class GroceryProgram:

    def __init__(self, master,
                 email_config: EmailAccessBase = None,
                 wunderpy_config: WunderpyAccessBase = None,
                 inital_grocery_content: str = ''):
        self.inital_menu_content = inital_grocery_content
        self.wunderpy_config = wunderpy_config
        self.email_config = email_config
        self.master = master

        self.master.wm_title('Grocery shopping')
        self.master.geometry('1000x500')

        self.current_menu = None

        # Grid definition:

        tk.Grid.rowconfigure(self.master, 0, weight=1)
        tk.Grid.columnconfigure(self.master, 0, weight=1)

        frame = tk.Frame(self.master)
        frame.grid(row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W)
        grid = tk.Frame(frame)
        grid.grid(sticky=tk.N + tk.S + tk.E + tk.W, column=0, row=0)
        tk.Grid.rowconfigure(frame, 0, weight=1)
        tk.Grid.columnconfigure(frame, 0, weight=1)

        ## Grocery list
        self.grocery_list = ScrolledText(frame, undo=True)
        self.grocery_list.grid(rowspan=2, columnspan=1, row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W, padx=10,
                               pady=10)

        # Set callback on all key presses:
        bindtags = list(self.grocery_list.bindtags())
        bindtags.insert(2, "custom")  # index 1 is where most default bindings live
        self.grocery_list.bindtags(tuple(bindtags))
        self.grocery_list.bind_class("custom", "<Key>", self.callback_any_key_grocery_list)
        self.grocery_list.bind('<Control-Return>', self.callback_controll_return_grocery_list)
        self.grocery_list.bind('<Control-BackSpace>', self.callback_get_recipe_from_parsed)
        # self.grocery_list.bind('<Key>', self.callback_parse_grocery_list)

        # set initial grocery_list:
        self.grocery_list.insert(tk.INSERT,
                                 inital_grocery_content)

        ## Menu list
        self.menu_box = ScrolledText(frame, undo=True)
        self.menu_box.grid(rowspan=2, columnspan=3, row=0, column=1, sticky=tk.N + tk.S + tk.E + tk.W, padx=10, pady=10)

        ## View menu
        self.view_menu_button = tk.Button(frame, text='View menu', command=self.callback_view_menu)
        self.view_menu_button.grid(rowspan=1, columnspan=1, row=2, column=0, sticky=tk.N + tk.S + tk.E + tk.W,
                                   padx=10, pady=10)

        ## View grocery list
        self.view_grocery_list = tk.Button(frame, text='View grocery list',
                                           command=self.callback_view_grocery_list)
        self.view_grocery_list.grid(rowspan=1, columnspan=1, row=3, column=0, sticky=tk.N + tk.S + tk.E + tk.W,
                                    padx=10, pady=10)

        ## View categories
        self.categories_button = tk.Button(frame, text='View categories', command=self.calback_show_categories_list)
        self.categories_button.grid(rowspan=1, columnspan=1, row=2, column=1, sticky=tk.N + tk.S + tk.E + tk.W, padx=10,
                                    pady=10)

        ## Commands
        self.command_text = tk.Label(frame, text='Ctrl+Enter: Reroll recipe suggestion.\nCtrl+Backspace: Lock suggestion.')
        self.command_text.grid(rowspan=1, columnspan=1, row=3, column=1, sticky=tk.N + tk.S + tk.E + tk.W, padx=10,
                               pady=10)

        ## Email recipients
        self.email_target_entry = tk.Entry(frame)
        self.email_target_entry.grid(rowspan=1, columnspan=1, row=2, column=2, sticky=tk.N + tk.S + tk.E + tk.W,
                                     padx=10, pady=10)
        if self.email_config:
            self.email_target_entry.insert(tk.INSERT,
                                           ', '.join(self.email_config.recipients))

        ## Send email_sender button
        self.email_button = tk.Button(frame, text='Send menu to email_sender', command=self.callback_send_menu_to_email)
        self.email_button.grid(rowspan=1, columnspan=1, row=2, column=3, sticky=tk.N + tk.S + tk.E + tk.W, padx=10,
                               pady=10)
        if not self.email_config:
            self.email_button['state'] = tk.DISABLED

        ## Wunderlist target entry
        self.wunderlist_target_entry = tk.Entry(frame)
        self.wunderlist_target_entry.grid(rowspan=1, columnspan=1, row=3, column=2, sticky=tk.N + tk.S + tk.E + tk.W,
                                          padx=10, pady=10)
        if self.wunderpy_config:
            self.wunderlist_target_entry.insert(tk.INSERT, self.wunderpy_config.default_list)

        ## Send to wunderlist button:
        self.send_to_wunderlist_button = tk.Button(frame, text='Send groceries to Wunderlist',
                                                   command=self.callback_send_to_wunderlist_button)
        self.send_to_wunderlist_button.grid(rowspan=1, columnspan=1, row=3, column=3, sticky=tk.N + tk.S + tk.E + tk.W,
                                            padx=10, pady=10)
        if not self.wunderpy_config:
            self.send_to_wunderlist_button['state'] = tk.DISABLED

        rows = range(3)
        columns = []

        for row in rows:
            tk.Grid.rowconfigure(frame, row, weight=1)
        for column in columns:
            tk.Grid.columnconfigure(frame, column, weight=1)

        self.parse_grocery_list()

    def callback_get_recipe_from_parsed(self, event):
        cursor_position = self.grocery_list.index(tk.INSERT)
        row = int(cursor_position.split('.')[0])
        corresponding_line = self.menu_box.get(1.0, tk.END).split('\n')[row - 1]
        all_lines = self.grocery_list.get(1.0, tk.END).split('\n')
        # Swap line:
        all_lines[row - 1] = corresponding_line

        self.grocery_list.delete(1.0, tk.END)
        self.grocery_list.insert(tk.INSERT, '\n'.join(all_lines))
        self.grocery_list.mark_set(tk.INSERT, cursor_position)
        print("I've hit control+backspace at row {0} and column {1}".format(
            *self.grocery_list.index(tk.INSERT).split('.')))
        return 'break'

    def callback_send_menu_to_email(self):
        print('send menu by email_sender button')
        sender = 'GroceryProgram'
        recipients = self.email_target_entry.get().split(', ')
        text = html.escape(self.current_menu.generate_menu_str(), quote=True)
        template = '<html><pre><font face="Courier New, Courier, monospace">%s</font></pre></html>' % text
        template = template.replace('\n', '<br />')

        send_email(self.email_config, 'Week menu', recipients, template)
        print('email_sender ok')

    def callback_send_to_wunderlist_button(self):
        print('send to wunderlist button')
        target_list = self.wunderlist_target_entry.get()

        # Create a list of {item, description} for all groceries
        processed_groceries = []
        for grocery in self.current_menu.groceries.components():
            item = ''
            if grocery['amount']:
                item += grocery['amount'] + ' '
            item += grocery['name']

            descriptions = []
            for source_dict in grocery['components']:
                source = ''
                source_name = ''
                if source_dict['amount']:
                    source_name += source_dict['amount'] + ' '
                source_name += source_dict['name']

                source += source_name

                if source_dict['comments']:
                    comments = '(' + ', '.join(source_dict['comments']) + ')'
                    source += comments + ' '

                if source_dict['recipe']:
                    recipe = ' til %s' % source_dict['recipe']
                    if not source_dict['recipe'] == config.language.no_recipe_name:
                        if source_dict['recipe_multiplier'] == 1:
                            recipe += ' for %d pers' % source_dict['recipe_made_for']
                        else:
                            recipe += ' x%f' % source_dict['recipe_multiplier']
                    source += recipe

                descriptions += [source]

            processed_groceries += [{'item': item, 'description': ', '.join(descriptions)}]

        response = add_groceries_to_wunderlist(self.wunderpy_config, target_list_name=target_list,
                                               groceries=processed_groceries)

        print(response)

    def callback_controll_return_grocery_list(self, event):
        self.parse_grocery_list(smart=False)
        return 'break'

    def callback_any_key_grocery_list(self, event):
        self.parse_grocery_list()

    def callback_button_parse_grocery_list(self):
        self.parse_grocery_list(smart=False)

    def parse_grocery_list(self, smart=True):
        print('callback works')
        text = self.grocery_list.get(1.0, tk.END)

        self.menu_box.delete(1.0, tk.END)

        if text.strip() == 'tags':
            string = '\n'.join([tag for tag in COOKBOOK.available_tags.keys()])
            self.menu_box.insert(tk.INSERT, string)
        if text.strip() == 'recipes':
            string = '\n'.join(COOKBOOK.available_recipes)
            self.menu_box.insert(tk.INSERT, string)
        else:
            # Intelligent update: Only update the lines that have changed.
            if not self.current_menu or not smart:
                self.current_menu = COOKBOOK.parse_menu(self.grocery_list.get(1.0, tk.END))
            else:
                new_menu = COOKBOOK.parse_menu(self.grocery_list.get(1.0, tk.END))

                for index, line in enumerate(new_menu.input_lines):
                    if line in self.current_menu.input_lines:
                        current_index = self.current_menu.input_lines.index(line)
                        new_menu.input_lines[index] = self.current_menu.input_lines[current_index]
                        new_menu.processed_lines[index] = self.current_menu.processed_lines[current_index]

                new_menu.input_plan = '\n'.join(new_menu.input_lines)
                new_menu.processed_plan = new_menu.create_output_lines(new_menu.processed_lines)
                self.current_menu = new_menu

                self.current_menu.process_input()

            self.menu_box.insert(tk.INSERT, self.current_menu.processed_plan)

    def callback_view_menu(self):
        """Callback for the send menu as email_sender button."""
        print('callback_send_menu_email')
        if isinstance(self.current_menu, Menu):
            self.menu_box.delete(1.0, tk.END)
            self.menu_box.insert(tk.INSERT, '\n'+self.current_menu.generate_menu_str())
        else:
            print('No menu to view')

    def callback_view_grocery_list(self):
        """Callback for the send menu as email_sender button."""
        print('callback_view_grocery_list')
        if isinstance(self.current_menu, Menu):
            self.menu_box.delete(1.0, tk.END)
            string = '\n'.join(self.current_menu.groceries.ingredients_formatted(pretty=True, sort='alphabetical'))
            self.menu_box.insert(tk.INSERT, string)
        else:
            print('No menu to view')

    def calback_show_categories_list(self):
        self.menu_box.delete(1.0, tk.END)
        string = '\n'.join(sorted(COOKBOOK.tags))
        self.menu_box.insert(tk.INSERT, string)
コード例 #18
0
class ScrolledTextInfoFrame(Frame):

    def __init__(self, master, *args, **kwargs):
        self.master = master
        super(ScrolledTextInfoFrame, self).__init__(self.master, *args,
                                                    **kwargs)

        self.saved_time = StringVar()

        self.highlighter = Highlighter()

        self._create_widgets()

        # the associated file
        self._file = None

    # TODO: rename the textentry
    def _create_widgets(self):
        # create a Text widget and read in the file
        self.textentry = ScrolledText(self, wrap=WORD)
        self.textentry.grid(column=0, row=0, columnspan=2, sticky='nsew')
        for key, value in self.highlighter.style:
            self.textentry.tag_configure(key, foreground=value)
        self.save_label = Label(self, textvar=self.saved_time)
        self.save_label.grid(column=0, row=1, sticky='es')
        self.save_btn = Button(self, text="Save", command=self.save_file)
        self.save_btn.grid(column=1, row=1, sticky='es')
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=0)
        self.grid_rowconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=0)

    def update(self):
        self._update_savetime()
        self.textentry.delete(1.0, END)
        with open(self.file.file, 'r') as file:
            self.textentry.insert(END, file.read())
        if HAS_PYGMENTS:
            if self.highlighter.change_type(self.file.dtype):
                # remove current tags
                for tag in self.textentry.tag_names():
                    self.textentry.tag_configure(tag, foreground="#000000")
                for key, value in self.highlighter.style.items():
                    self.textentry.tag_configure(key, foreground=value)
            self.syn()

    def _update_savetime(self):
        self.saved_time.set("Last saved:\t{0}\t".format(self.file.saved_time))

    @threaded
    def syn(self, event=None):
        """
        Allow for syntax highlighting.
        Source: https://stackoverflow.com/a/30199105
        This will highlight the entire document once. Dynamic highlighting not
        yet supported.
        #TODO: (maybe?): https://stackoverflow.com/questions/32058760/improve-pygments-syntax-highlighting-speed-for-tkinter-text/32064481  # noqa

        This is threaded to hopefully stop it blocking the view from displaying
        and causing a race condition.
        """
        self.textentry.mark_set("range_start", "1.0")
        data = self.textentry.get("1.0", "end-1c")
        lexer = self.highlighter.lexer
        if lexer is not None:
            for token, content in lex(data, lexer()):
                self.textentry.mark_set("range_end",
                                        "range_start + %dc" % len(content))
                self.textentry.tag_add(str(token), "range_start", "range_end")
                self.textentry.mark_set("range_start", "range_end")

    def save_file(self):
        """ Write the current data in the text widget back to the file """
        file_contents = self.textentry.get("1.0", "end-1c")
        with open(self.file.file, 'w') as file:
            file.write(file_contents)
        savetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.file.saved_time = savetime
        self._update_savetime()
        # also re-apply the syntax highlighting
        self.syn()

    @property
    def file(self):
        return self._file

    @file.setter
    def file(self, other):
        """
        Set the file property to whatever the new file is.
        When this happens the update command will be called which will redraw
        the channel info list
        """
        # if the file is being set as a con_file continue
        if other != self._file:
            self._file = other
            self.update()
コード例 #19
0
class Window(Listbox):

    # Initializes the variables and settings for the project. Finally
    # executes the create_menu for the menu bar, and the create_notepad
    # for the text window
    def __init__(self, master, **kw):
        # Sets master, or root
        super().__init__(master, **kw)
        self.master = master
        # Set some variables
        self.current_file_path = ''
        self.current_file_text = ''
        self.is_saved = True
        # Set up the context menu and the text box
        self.context_popup_menu = Menu(self.master, tearoff=0)
        self.text_window = ScrolledText(self.master, undo=True)
        self.text_window.focus()
        self.user_data = self.text_window.get('1.0', END + '-1c')
        # Name the window, icon, and start the create functions
        self.master.title(NAME)
        # self.master.iconbitmap('./tk/images/icon.ico')
        self.initiate_shortcuts()
        self.create_menu()
        self.create_notepad()
        self.create_context_menu()

    # Creates the context menu
    def create_context_menu(self):
        # Adds a command for button, separator for separator
        self.context_popup_menu.add_command(label="Undo",
                                            command=lambda: self.undo())
        self.context_popup_menu.add_command(label="Redo",
                                            command=lambda: self.redo())
        self.context_popup_menu.add_separator()
        self.context_popup_menu.add_command(
            label="Cut",
            command=lambda: self.text_window.event_generate("<<Cut>>"))
        self.context_popup_menu.add_command(
            label="Copy",
            command=lambda: self.text_window.event_generate("<<Copy>>"))
        self.context_popup_menu.add_command(
            label="Paste",
            command=lambda: self.text_window.event_generate("<<Paste>>"))
        self.context_popup_menu.add_separator()
        self.context_popup_menu.add_command(label="Delete",
                                            command=lambda: self.clear())
        self.context_popup_menu.add_separator()
        self.context_popup_menu.add_command(label="Select All",
                                            command=lambda: self.select_all())

    # Creates the top bar menu
    def create_menu(self):
        # Creating menu bar and adding it to master
        menu_bar = Menu(self.master)
        text = self.text_window
        # Telling root that menu_bar is the Window's menu
        self.master.config(menu=menu_bar)
        # Creating the File menu dropdown
        file_menu = Menu(menu_bar, tearoff=False)
        file_menu.add_command(label="New Document...",
                              command=self.new_file,
                              accelerator="Ctrl+N")
        file_menu.add_command(label="Open Document...",
                              command=self.open_file,
                              accelerator="Ctrl+O")
        file_menu.add_command(label="Save...",
                              command=self.save_file,
                              accelerator="Ctrl+S")
        file_menu.add_command(label="Save as...",
                              command=self.save_as_file,
                              accelerator="Ctrl+Shift+S")
        file_menu.add_separator()
        file_menu.add_command(label="Quit",
                              command=self.exit,
                              accelerator="Ctrl+Q")
        # Adding it to the menu_bar
        menu_bar.add_cascade(label="File", menu=file_menu, underline=0)
        # Creating the Edit menu dropdown
        edit_menu = Menu(menu_bar, tearoff=False)
        edit_menu.add_command(label="Undo",
                              command=self.undo,
                              accelerator="Ctrl+Z")
        edit_menu.add_command(label="Redo",
                              command=self.redo,
                              accelerator="Ctrl+Y")
        edit_menu.add_separator()
        edit_menu.add_command(label="Cut",
                              command=lambda: text.event_generate("<<Cut>>"),
                              accelerator="Ctrl+X")
        edit_menu.add_command(label="Copy",
                              command=lambda: text.event_generate("<<Copy>>"),
                              accelerator="Ctrl+C")
        edit_menu.add_command(label="Paste",
                              command=lambda: text.event_generate("<<Paste>>"),
                              accelerator="Ctrl+V")
        edit_menu.add_separator()
        edit_menu.add_command(label="Select All",
                              command=lambda: self.select_all(),
                              accelerator="Ctrl+A")
        edit_menu.add_command(label="Delete",
                              command=self.clear,
                              accelerator="Del")
        # edit_menu.add_separator()
        # edit_menu.add_command(label="Settings...", command=settings, accelerator="Ctrl+S")
        # Adding it to the menu_bar
        menu_bar.add_cascade(label="Edit", menu=edit_menu)
        # Creating the Help menu
        help_menu = Menu(menu_bar, tearoff=False)
        help_menu.add_command(label="About...", command=about)
        # Adding it to the menu_bar
        menu_bar.add_cascade(label="Help", menu=help_menu)

    # Bind the shortcuts to their specified functions
    def initiate_shortcuts(self):
        self.master.bind("<KeyRelease>", lambda event: self.on_text_change())
        self.master.bind("<Control-n>", lambda event: self.new_file())
        self.master.bind("<Control-o>", lambda event: self.open_file())
        self.master.bind("<Control-s>", lambda event: self.save_file())
        self.master.bind("<Control-Shift-s>",
                         lambda event: self.save_as_file())
        self.master.bind("<Control-q>", lambda event: self.exit())
        self.master.bind("<Control-z>", lambda event: self.undo())
        self.master.bind("<Control-y>", lambda event: self.redo())
        self.text_window.bind("<Control-a>", lambda event: self.select_all())
        # self.master.bind("<Control-s>", lambda event: settings())
        self.master.bind("<Button-3>",
                         lambda event: self.right_click_popup(event))

    # Display context menu popup
    def right_click_popup(self, event):
        try:
            # Used +45 and + 12 to corner it
            self.context_popup_menu.tk_popup(event.x_root + 45,
                                             event.y_root + 12, 0)
        finally:
            self.context_popup_menu.grab_release()

    # Scaling the text_window to fit the screen
    def create_notepad(self):
        self.text_window.pack(fill="both", expand=True)

    # Returns the value of the text field
    def get_text_data(self):
        return self.text_window.get('1.0', END + '-1c')

    # Clears the text off the screen, resets the variables
    def clear_text(self):
        self.text_window.delete('1.0', END)
        self.current_file_path = ''
        self.current_file_text = ''

    # Called when typing, sets the is_saved variable
    def on_text_change(self):
        # If the text in the textbox is equal to the saved text in the variable
        # This is used when opening a file, changing something, then undoing that change
        if self.get_text_data() == self.current_file_text:
            self.is_saved = True
        else:
            # If the saved file exists or is valid
            if os.path.isfile(self.current_file_path):
                # Open the file, save it's data to this_file
                with open(self.current_file_path, "r") as f:
                    this_file = f.read()
                    # If this_file is equal to the same text in the textbox
                    # Used if no changes were made, and if they were, set to False
                self.is_saved = True if this_file == self.get_text_data(
                ) else False
            else:
                # If the data is not equal to variable, and no file, then changes
                # must have been made
                self.is_saved = False

    # MENU CONTROL FUNCTIONS

    # Clear current selection, erase the current file if saved
    def new_file(self):
        # If it's saved, clear it and set the file to saved
        if self.is_saved is True:
            self.clear_text()
            self.is_saved = True
        else:
            # Popup the saved popup
            popup_value = is_saved_popup()
            if popup_value == "yes":
                # Save the file, clear it and set the is_saved to True
                if self.save_file() is True:
                    self.clear_text()
                    self.is_saved = True
            elif popup_value == "no":
                # Don't save the file, but clear it and set the is_saved to True
                self.clear_text()
                self.is_saved = True
            else:
                # Something went wrong
                print("Error: new_file error")

    # Open a file if the current file is saved, then insert new file data
    def open_file(self):
        # If file is saved, open the open_file window
        if self.is_saved is True:
            self.open_file_popup()
        else:
            # Save the file, if it's saved, open the open_file window
            popup_value = is_saved_popup()
            if popup_value == "yes":
                if self.save_file() is True:
                    self.is_saved = True
                    self.open_file_popup()
            # Open the open_file window
            elif popup_value == "no":
                self.open_file_popup()
            else:
                # An error occurred
                print("Error: open_file error")

    # The function that displays the open_file popup
    def open_file_popup(self):
        # Gets old data from current file
        old_file = self.current_file_path
        # Opens the file location, stores it in file_name
        file_name = filedialog.askopenfilename(
            title="Open",
            filetypes=(("Text files", "*.txt"), ("All files", "*.*")))
        # If a file was actually selected, open it
        if file_name is not '':
            with open(file_name) as f:
                data = f.read()
            # Clear current text
            self.clear_text()
            # Set the path variable of the new file
            self.current_file_path = file_name if os.path.isfile(
                file_name) else old_file
            # Add the file data to the text_box
            self.text_window.insert(INSERT, data)
            # Add the file data to the variable
            self.current_file_text = data
            # is_saved is True
            self.is_saved = True

    # Save file, if file exists, overwrite it, otherwise, call save_as_file function
    def save_file(self):
        # If the file path exists
        if os.path.isfile(self.current_file_path):
            # Stores the current text data into the variable
            self.current_file_text = self.get_text_data()
            # Saves the data to the existing file (overwriting)
            with open(self.current_file_path, "w") as f:
                return True if f.writelines(
                    self.get_text_data()) is True else False
        else:
            # File doesn't exist, call save_as_file
            if self.save_as_file() is True:
                return True

    # Saves file with asksaveasfile to open a save as window.
    def save_as_file(self):
        # Gets old file path
        old_file = self.current_file_path
        # Opens save_as window
        file_name = filedialog.asksaveasfilename(
            title="Save As",
            defaultextension=".txt",
            filetypes=(("Text files", "*.txt"), ("All files", "*.*")))
        # Set current file path
        self.current_file_path = old_file if file_name is None else file_name

        # If the file_path already exists
        if os.path.isfile(self.current_file_path):
            # Copy the current text to the variable
            self.current_file_text = self.get_text_data()
            # Writes to the named file
            with open(self.current_file_path, "w") as f:
                f.writelines(self.get_text_data())
                return True
        else:
            # A file wasn't selected
            if file_name is '':
                print("Error: File is none")
                return False
            # Create a new file to store the data
            self.current_file_text = self.get_text_data()
            with open(file_name, 'w'):
                pass
            self.is_saved = True
            return True

    # Exit override command
    def exit(self):
        # If the file is saved, exit
        if self.is_saved is True:
            self.master.quit()
        else:
            # If the file is not saved, call the saved_popup
            popup_value = is_saved_popup()
            if popup_value == "yes":
                # Save and then quit
                if self.save_file() is True:
                    self.is_saved = True
                    self.quit()
            elif popup_value == "no":
                # Don't save, just quit
                self.master.quit()
            else:
                # An error occurred
                print("Error: open_file error")

    # Undo last action
    def undo(self):
        self.text_window.edit_undo()

    # Redo last action
    def redo(self):
        self.text_window.edit_redo()

    # Clear (delete) the selected text
    def clear(self):
        self.text_window.delete(SEL_FIRST, SEL_LAST)
        self.text_window.update()

    # Select the selected text (without new line)
    def select_all(self):
        self.text_window.tag_add(SEL, "1.0", END + '-1c')
        self.text_window.mark_set(INSERT, "1.0")
        self.text_window.see(INSERT)
        return 'break'
コード例 #20
0
class Editor(Toplevel):
    @property
    def text(self):
        return self.sc_text.get('1.0', END)

    @text.setter
    def text(self, value):
        pos = self.sc_text.yview()
        self.sc_text.delete('1.0', END)
        self.sc_text.insert(END, value)
        self.sc_text.yview_moveto(pos[0])

    def __init__(self, master):
        super().__init__(master)

        self.index_matches = None
        self.current_index = None

        self.search_content = StringVar()
        self.sc_text = ScrolledText(self, wrap=NONE)

        self.x_scrollbar_content_text = Scrollbar(self,
                                                  orient=HORIZONTAL,
                                                  command=self.sc_text.xview)
        self.sc_text.configure(
            xscrollcommand=self.x_scrollbar_content_text.set)
        self.wrap_text = IntVar()
        self.wrap_text.set(False)

        Button(self, text='<-', command=self.click_prev_button).grid(row=0,
                                                                     column=0)
        self.search_content_entry = Entry(self,
                                          textvariable=self.search_content)
        self.search_content_entry.bind(
            '<KeyRelease>',
            lambda event: self.highlight_pattern(event.widget.get()))
        self.search_content_entry.grid(row=0, column=1, sticky=W + E)
        Button(self, text='->', command=self.click_next_button).grid(row=0,
                                                                     column=2)
        Checkbutton(self,
                    text="Wrap Text",
                    variable=self.wrap_text,
                    command=lambda: self.sc_text.config(
                        wrap=NONE
                        if not self.wrap_text.get() else WORD)).grid(row=1,
                                                                     column=0)
        self.sc_text.grid(row=2, column=0, columnspan=3, sticky=N + S + E + W)
        self.x_scrollbar_content_text.grid(row=3,
                                           column=0,
                                           columnspan=3,
                                           sticky=W + E)

        self.columnconfigure(1, weight=1)
        self.rowconfigure(2, weight=1)
        self.withdraw()
        self.protocol('WM_DELETE_WINDOW', lambda t=self: t.withdraw())

    def click_next_button(self):
        if not self.index_matches:
            return
        if self.current_index is None:
            self.current_index = 0
        else:
            self.current_index += 1
        self.current_index %= len(self.index_matches)
        self.sc_text.see(self.index_matches[self.current_index])

    def click_prev_button(self):
        if not self.index_matches:
            return
        if self.current_index is None:
            self.current_index = len(self.index_matches) - 1
        else:
            self.current_index -= 1
        self.current_index %= len(self.index_matches)
        self.sc_text.see(self.index_matches[self.current_index])

    def highlight_pattern(self, pattern, start="1.0", end="end"):
        for t in self.sc_text.tag_names():
            self.sc_text.tag_delete(t)

        if not pattern:
            return
        self.index_matches = []
        self.current_index = None

        self.sc_text.tag_config('found', background="green")
        start = self.sc_text.index(start)
        end = self.sc_text.index(end)
        self.sc_text.mark_set("matchStart", start)
        self.sc_text.mark_set("matchEnd", start)
        self.sc_text.mark_set("searchLimit", end)
        count = IntVar()
        while True:
            index = self.sc_text.search(pattern,
                                        "matchEnd",
                                        "searchLimit",
                                        count=count)
            if index == "":
                break
            self.sc_text.mark_set("matchStart", index)
            match_index = "%s+%sc" % (index, count.get())
            self.index_matches.append(match_index)
            self.sc_text.mark_set("matchEnd", match_index)
            self.sc_text.tag_add('found', "matchStart", "matchEnd")
コード例 #21
0
class WbRunner(tk.Frame):
    def __init__(self, tool_name=None, master=None):
        # First, try to find the WhiteboxTools exe directory
        if _platform == 'win32':
            ext = '.exe'
        else:
            ext = ''

        exe_name = "whitebox_tools{}".format(ext)

        self.exe_path = path.dirname(path.abspath(__file__))
        os.chdir(self.exe_path)
        for filename in glob.iglob('**/*', recursive=True):
            if filename.endswith(exe_name):
                self.exe_path = path.dirname(path.abspath(filename))
                break

        wbt.set_whitebox_dir(self.exe_path)

        ttk.Frame.__init__(self, master)
        self.script_dir = os.path.dirname(os.path.realpath(__file__))
        self.grid()
        self.tool_name = tool_name
        self.master.title("WhiteboxTools Runner")
        # widthpixels = 800
        # heightpixels = 600
        # self.master.geometry('{}x{}'.format(widthpixels, heightpixels))
        # self.master.resizable(0, 0)
        # self.master.lift()
        if _platform == "darwin":
            os.system(
                '''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' '''
            )
        self.create_widgets()
        self.working_dir = str(Path.home())

    def create_widgets(self):
        toplevel_frame = ttk.Frame(self, padding='0.1i')

        (self.toolslist, selected_item) = self.get_tools_list()
        self.tools_frame = ttk.LabelFrame(toplevel_frame,
                                          text="{} Available Tools".format(
                                              len(self.toolslist)),
                                          padding='0.1i')
        self.toolnames = tk.StringVar(value=self.toolslist)
        self.tools_listbox = tk.Listbox(self.tools_frame,
                                        height=22,
                                        listvariable=self.toolnames)
        self.tools_listbox.bind("<<ListboxSelect>>", self.update_tool_help)
        self.tools_listbox.grid(row=0, column=0, sticky=tk.NSEW)
        self.tools_listbox.columnconfigure(0, weight=10)
        self.tools_listbox.rowconfigure(0, weight=1)
        s = ttk.Scrollbar(self.tools_frame,
                          orient=tk.VERTICAL,
                          command=self.tools_listbox.yview)
        s.grid(row=0, column=1, sticky=(tk.N, tk.S))
        self.tools_listbox['yscrollcommand'] = s.set
        self.tools_frame.grid(row=0, column=0, sticky=tk.NSEW)
        self.tools_frame.columnconfigure(0, weight=10)
        self.tools_frame.columnconfigure(1, weight=1)
        self.tools_frame.rowconfigure(0, weight=1)

        overall_frame = ttk.Frame(toplevel_frame, padding='0.1i')

        # json_str = '{"default_value": null, "description": "Directory containing data files.", "flags": ["--wd"], "name": "Working Directory", "optional": true, "parameter_type": "Directory"}'
        # self.wd = FileSelector(json_str, overall_frame)
        # self.wd.grid(row=0, column=0, sticky=tk.NSEW)

        current_tool_frame = ttk.Frame(overall_frame, padding='0.1i')
        self.current_tool_lbl = ttk.Label(
            current_tool_frame,
            text="Current Tool: {}".format(self.tool_name),
            justify=tk.LEFT)  # , font=("Helvetica", 12, "bold")
        self.current_tool_lbl.grid(row=0, column=0, sticky=tk.W)
        self.view_code_button = ttk.Button(current_tool_frame,
                                           text="View Code",
                                           width=12,
                                           command=self.view_code)
        self.view_code_button.grid(row=0, column=1, sticky=tk.E)
        current_tool_frame.grid(row=1, column=0, sticky=tk.NSEW)
        current_tool_frame.columnconfigure(0, weight=1)
        current_tool_frame.columnconfigure(1, weight=1)

        tool_args_frame = ttk.Frame(overall_frame, padding='0.0i')
        self.tool_args_frame = ttk.Frame(overall_frame, padding='0.0i')
        self.tool_args_frame.grid(row=2, column=0, sticky=tk.NSEW)
        self.tool_args_frame.columnconfigure(0, weight=1)

        # args_frame = ttk.Frame(overall_frame, padding='0.1i')
        # self.args_label = ttk.Label(args_frame, text="Tool Arguments:", justify=tk.LEFT)
        # self.args_label.grid(row=0, column=0, sticky=tk.W)
        # args_frame2 = ttk.Frame(args_frame, padding='0.0i')
        # self.args_value = tk.StringVar()
        # self.args_text = ttk.Entry(args_frame2, width=45, justify=tk.LEFT, textvariable=self.args_value)
        # self.args_text.grid(row=0, column=0, sticky=tk.NSEW)
        # self.args_text.columnconfigure(0, weight=1)
        # self.clearButton = ttk.Button(args_frame2, text="Clear", width=4, command=self.clear_args_box)
        # self.clearButton.pack(pady=10, padx=10)
        # self.clearButton.grid(row=0, column=1, sticky=tk.E)
        # self.clearButton.columnconfigure(0, weight=1)
        # args_frame2.grid(row=1, column=0, sticky=tk.NSEW)
        # args_frame2.columnconfigure(0, weight=10)
        # args_frame2.columnconfigure(1, weight=1)
        # args_frame.grid(row=2, column=0, sticky=tk.NSEW)
        # args_frame.columnconfigure(0, weight=1)

        # # Add the bindings
        # if _platform == "darwin":
        #     self.args_text.bind("<Command-Key-a>", self.args_select_all)
        # else:
        #     self.args_text.bind("<Control-Key-a>", self.args_select_all)

        buttonsFrame = ttk.Frame(overall_frame, padding='0.1i')
        self.run_button = ttk.Button(buttonsFrame,
                                     text="Run",
                                     width=8,
                                     command=self.run_tool)
        # self.run_button.pack(pady=10, padx=10)
        self.run_button.grid(row=0, column=0)
        self.quitButton = ttk.Button(buttonsFrame,
                                     text="Cancel",
                                     width=8,
                                     command=self.cancel_operation)
        self.quitButton.grid(row=0, column=1)
        buttonsFrame.grid(row=3, column=0, sticky=tk.E)

        output_frame = ttk.Frame(overall_frame, padding='0.1i')
        outlabel = ttk.Label(output_frame, text="Output:", justify=tk.LEFT)
        outlabel.grid(row=0, column=0, sticky=tk.NW)
        k = wbt.tool_help(self.tool_name)
        self.out_text = ScrolledText(output_frame,
                                     width=63,
                                     height=10,
                                     wrap=tk.NONE,
                                     padx=7,
                                     pady=7)
        self.out_text.insert(tk.END, k)
        self.out_text.grid(row=1, column=0, sticky=tk.NSEW)
        self.out_text.columnconfigure(0, weight=1)
        output_frame.grid(row=4, column=0, sticky=tk.NSEW)
        output_frame.columnconfigure(0, weight=1)

        # Add the binding
        if _platform == "darwin":
            self.out_text.bind("<Command-Key-a>", self.select_all)
            # self.out_text.bind("<Command-Key-A>", self.select_all)
        else:
            self.out_text.bind("<Control-Key-a>", self.select_all)

        progress_frame = ttk.Frame(overall_frame, padding='0.1i')
        self.progress_label = ttk.Label(progress_frame,
                                        text="Progress:",
                                        justify=tk.LEFT)
        self.progress_label.grid(row=0, column=0, sticky=tk.E, padx=5)
        self.progress_var = tk.DoubleVar()
        self.progress = ttk.Progressbar(progress_frame,
                                        orient="horizontal",
                                        variable=self.progress_var,
                                        length=200,
                                        maximum=100)
        self.progress.grid(row=0, column=1, sticky=tk.E)
        progress_frame.grid(row=5, column=0, sticky=tk.E)

        overall_frame.grid(row=0, column=1, sticky=tk.NSEW)

        overall_frame.columnconfigure(0, weight=1)
        toplevel_frame.columnconfigure(0, weight=1)
        toplevel_frame.columnconfigure(1, weight=4)
        # self.pack(fill=tk.BOTH, expand=1)
        # toplevel_frame.columnconfigure(0, weight=1)
        # toplevel_frame.rowconfigure(0, weight=1)

        toplevel_frame.grid(row=0, column=0, sticky=tk.NSEW)

        # Select the appropriate tool, if specified, otherwise the first tool
        self.tools_listbox.select_set(selected_item)
        self.tools_listbox.event_generate("<<ListboxSelect>>")
        self.tools_listbox.see(selected_item)

        menubar = tk.Menu(self)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Set Working Directory",
                             command=self.set_directory)
        filemenu.add_command(label="Locate WhiteboxTools exe",
                             command=self.select_exe)
        filemenu.add_command(label="Refresh Tools", command=self.refresh_tools)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.quit)
        menubar.add_cascade(label="File", menu=filemenu)

        editmenu = tk.Menu(menubar, tearoff=0)
        editmenu.add_command(
            label="Cut",
            command=lambda: self.focus_get().event_generate("<<Cut>>"))
        editmenu.add_command(
            label="Copy",
            command=lambda: self.focus_get().event_generate("<<Copy>>"))
        editmenu.add_command(
            label="Paste",
            command=lambda: self.focus_get().event_generate("<<Paste>>"))

        menubar.add_cascade(label="Edit ", menu=editmenu)

        helpmenu = tk.Menu(menubar, tearoff=0)
        helpmenu.add_command(label="About", command=self.help)

        helpmenu.add_command(label="License", command=self.license)

        menubar.add_cascade(label="Help ", menu=helpmenu)

        self.master.config(menu=menubar)

        # self.get_toolboxes()

    def help(self):
        self.print_to_output(wbt.version())

    def license(self):
        self.print_to_output(wbt.license())

    def set_directory(self):
        try:
            self.working_dir = filedialog.askdirectory(
                initialdir=self.exe_path)
            wbt.set_working_dir(self.working_dir)
        except:
            messagebox.showinfo(
                "Warning", "Could not find WhiteboxTools executable file.")

    def select_exe(self):
        try:
            filename = filedialog.askopenfilename(initialdir=self.exe_path)
            self.exe_path = path.dirname(path.abspath(filename))
            wbt.set_whitebox_dir(self.exe_path)
            self.refresh_tools()
        except:
            messagebox.showinfo(
                "Warning", "Could not find WhiteboxTools executable file.")

    def run_tool(self):
        # wd_str = self.wd.get_value()
        wbt.set_working_dir(self.working_dir)
        # args = shlex.split(self.args_value.get())

        args = []
        for widget in self.tool_args_frame.winfo_children():
            v = widget.get_value()
            if v:
                args.append(v)
            elif not widget.optional:
                messagebox.showinfo(
                    "Error", "Non-optional tool parameter not specified.")
                return

        self.print_line_to_output("")
        # self.print_line_to_output("Tool arguments:{}".format(args))
        # self.print_line_to_output("")
        # Run the tool and check the return value for an error
        if wbt.run_tool(self.tool_name, args, self.custom_callback) == 1:
            print("Error running {}".format(self.tool_name))

        else:
            self.run_button["text"] = "Run"
            self.progress_var.set(0)
            self.progress_label['text'] = "Progress:"
            self.progress.update_idletasks()

    def print_to_output(self, value):
        self.out_text.insert(tk.END, value)
        self.out_text.see(tk.END)

    def print_line_to_output(self, value):
        self.out_text.insert(tk.END, value + "\n")
        self.out_text.see(tk.END)

    def cancel_operation(self):
        wbt.cancel_op = True
        self.print_line_to_output("Cancelling operation...")
        self.progress.update_idletasks()

    def view_code(self):
        webbrowser.open_new_tab(wbt.view_code(self.tool_name).strip())

    def update_tool_help(self, event):
        selection = self.tools_listbox.curselection()
        self.tool_name = self.tools_listbox.get(selection[0])
        self.out_text.delete('1.0', tk.END)
        for widget in self.tool_args_frame.winfo_children():
            widget.destroy()

        k = wbt.tool_help(self.tool_name)
        self.print_to_output(k)

        j = json.loads(wbt.tool_parameters(self.tool_name))
        param_num = 0
        for p in j['parameters']:
            json_str = json.dumps(p,
                                  sort_keys=True,
                                  indent=2,
                                  separators=(',', ': '))
            pt = p['parameter_type']
            if 'ExistingFileOrFloat' in pt:
                ff = FileOrFloat(json_str, self, self.tool_args_frame)
                ff.grid(row=param_num, column=0, sticky=tk.NSEW)
                param_num = param_num + 1
            elif ('ExistingFile' in pt or 'NewFile' in pt
                  or 'Directory' in pt):
                fs = FileSelector(json_str, self, self.tool_args_frame)
                fs.grid(row=param_num, column=0, sticky=tk.NSEW)
                param_num = param_num + 1
            elif 'FileList' in pt:
                b = MultifileSelector(json_str, self, self.tool_args_frame)
                b.grid(row=param_num, column=0, sticky=tk.W)
                param_num = param_num + 1
            elif 'Boolean' in pt:
                b = BooleanInput(json_str, self.tool_args_frame)
                b.grid(row=param_num, column=0, sticky=tk.W)
                param_num = param_num + 1
            elif 'OptionList' in pt:
                b = OptionsInput(json_str, self.tool_args_frame)
                b.grid(row=param_num, column=0, sticky=tk.W)
                param_num = param_num + 1
            elif ('Float' in pt or 'Integer' in pt or 'String' in pt
                  or 'StringOrNumber' in pt or 'StringList' in pt):
                b = DataInput(json_str, self.tool_args_frame)
                b.grid(row=param_num, column=0, sticky=tk.NSEW)
                param_num = param_num + 1
            else:
                messagebox.showinfo(
                    "Error", "Unsupported parameter type: {}.".format(pt))

        self.update_args_box()
        self.out_text.see("%d.%d" % (1, 0))

    def update_args_box(self):
        s = ""
        self.current_tool_lbl['text'] = "Current Tool: {}".format(
            self.tool_name)
        # self.spacer['width'] = width=(35-len(self.tool_name))
        for item in wbt.tool_help(self.tool_name).splitlines():
            if item.startswith("-"):
                k = item.split(" ")
                if "--" in k[1]:
                    value = k[1].replace(",", "")
                else:
                    value = k[0].replace(",", "")

                if "flag" in item.lower():
                    s = s + value + " "
                else:
                    if "file" in item.lower():
                        s = s + value + "='{}' "
                    else:
                        s = s + value + "={} "

        # self.args_value.set(s.strip())

    def clear_args_box(self):
        self.args_value.set("")

    def args_select_all(self, event):
        self.args_text.select_range(0, tk.END)
        return 'break'

    def custom_callback(self, value):
        ''' A custom callback for dealing with tool output.
        '''
        if "%" in value:
            try:
                str_array = value.split(" ")
                label = value.replace(str_array[len(str_array) - 1],
                                      "").strip()
                progress = float(str_array[len(str_array) - 1].replace(
                    "%", "").strip())
                self.progress_var.set(int(progress))
                self.progress_label['text'] = label
            except ValueError as e:
                print("Problem converting parsed data into number: ", e)
            except Exception as e:
                print(e)
        else:
            self.print_line_to_output(value)

        self.update(
        )  # this is needed for cancelling and updating the progress bar

    def select_all(self, event):
        self.out_text.tag_add(tk.SEL, "1.0", tk.END)
        self.out_text.mark_set(tk.INSERT, "1.0")
        self.out_text.see(tk.INSERT)
        return 'break'

    def get_tools_list(self):
        list = []
        selected_item = -1
        for item in wbt.list_tools().splitlines():
            if item:
                if "available tools" not in item.lower():
                    value = item.split(":")[0]
                    list.append(value)
                    if value == self.tool_name:
                        selected_item = len(list) - 1
        if selected_item == -1:
            selected_item = 0
            self.tool_name = list[0]

        return (list, selected_item)

    def get_toolboxes(self):
        toolboxes = set()
        for item in wbt.toolbox().splitlines(
        ):  # run wbt.toolbox with no tool specified--returns all
            if item:
                tb = item.split(":")[1].strip()
                toolboxes.add(tb)

        for v in sorted(toolboxes):
            # print(v)
            self.print_line_to_output(v)

    def refresh_tools(self):
        (self.toolslist, selected_item) = self.get_tools_list()
        self.tools_listbox.delete(0, len(self.toolslist))
        for item in self.toolslist:
            self.tools_listbox.insert(len(self.toolslist), item)

        self.tools_frame["text"] = "{} Available Tools".format(
            len(self.toolslist))
コード例 #22
0
ファイル: iqtree_out.py プロジェクト: luhuimeng/iqtreeGUI
class IqtreeWindow():
	displayed_output =""
	command = ""
	partition_command = ""
	wd = "~"
	
		
	def __init__(self, master, settings):
		self.settings = settings
		self.master = master
		self.master.resizable(False, False)
		self.master.protocol( "WM_DELETE_WINDOW", self.close)
		self.master.title("iqtree Output")
		self.checkpoints = Listbox(self.master)
		self.checkpoints.grid(column=1,row=1, sticky=N+W+S)
		#self.checkpoints.bind("<Button-1>", self.jump_to_selection)
		self.checkpoints.bind("<<ListboxSelect>>", self.jump_to_selection)
		self.output_label = ScrolledText(self.master, font=("Helvetica", 10), width=100)
		self.output_label.grid(column=2,row=1)
		self.save_button = Button(self.master, text="Save Output")
		self.save_button.grid(column=1,row=2)
		self.line_number = 0
		self.checkpoints_dict = {}
		self.checkpoints_dict["Start of run"] = self.line_number
		self.checkpoints.insert(END, "Start of run")
		self.n_empty_lines = 0
		
	def jump_to_selection(self, ef):
		selection = self.checkpoints.curselection()
		line = self.checkpoints_dict[self.checkpoints.get(selection[0])]
		print(line)
		self.output_label.mark_set("section", "%s.1"%line)
		self.output_label.see("section")

	def display(self, text):
		if text == "":
			self.n_empty_lines += 1
		if self.n_empty_lines >= 10:
			self.process.kill()
		else:
			self.line_number += 1
			self.displayed_output = str(self.line_number) + " " + text
			self.displayed_output = " " + text
			self.output_label.insert(END,self.displayed_output)
			self.output_label.see(END)
			if self.displayed_output.startswith("IQ-TREE"):
				self.checkpoints.insert(END, "IQ-TREE")
				self.checkpoints_dict["IQ-TREE"] = self.line_number
			if self.displayed_output.startswith("ModelFinder"):
				self.checkpoints.insert(END, "ModelFinder")
				self.checkpoints_dict["ModelFinder"] = self.line_number	
			if self.displayed_output.startswith("Akaike Information Criterion:"):
				self.checkpoints.insert(END, "Best Model")
				self.checkpoints_dict["Best Model"] = self.line_number
			if "INITIALIZING CANDIDATE TREE SET" in self.displayed_output:
				self.checkpoints.insert(END, "Initialize tree")
				self.checkpoints_dict["Initialize tree"] = self.line_number
			if "OPTIMIZING CANDIDATE TREE SET" in self.displayed_output:
				self.checkpoints.insert(END, "Optimize tree")
				self.checkpoints_dict["Optimize tree"] = self.line_number
			if "FINALIZING TREE SEARCH" in self.displayed_output:
				self.checkpoints.insert(END, "Finalize tree")
				self.checkpoints_dict["Finalize tree"] = self.line_number
			#print self.checkpoints_dict
			#self.frame.configure(text=self.displayed_output)
	
	def send_command(self, command):
		self.command = command
	
	def send_partitions(self, partition_command):
		self.partition_command = partition_command
		
	def spawn_process(self):
		print("Command is:", self.command)
		#cmd_list = shlex.split(self.command)
		if "Windows" in platform.system():
			separator="\\"
		else:
			separator="/"
		os.chdir(self.settings.wd + separator + self.settings.analysisname)
		self.process = Popen(self.command, stdout=PIPE, stderr=STDOUT, universal_newlines=True, shell=True)

		self.q = Queue(maxsize=1024)
		self.t = Thread(target=self.reader_thread, args=[self.q])
		self.t.setDaemon(True)
		self.t.start()
		self.update(self.q)

	def reader_thread(self, q):
		# Read subprocess output and put it into the queue.
		print("READING")
		try:
			with self.process.stdout as pipe:
				for line in iter(pipe.readline, b''):
					q.put(line)
		finally:
			q.put(None)
			self.process.kill()
		try:
			with self.process.stderr as pipe:
				for line in iter(pipe.readline, b''):
					q.put(line)
		finally:
			q.put(None)
			self.process.kill()
		

	def update(self, q):
		# Update GUI with items from the queue.
		for line in iter_except(q.get_nowait, Empty): # display all content
			if line is None:
				#self.quit()
				return
			else:
				self.display(line) # update GUI
				break # display no more than one line per 40 milliseconds
		self.master.after(40, self.update, q) # schedule next update
		
	def close(self):
		self.process.kill()
		self.master.destroy()

		
		
コード例 #23
0
class Gui():
    def __init__(self):
        self.file_path = None
        self.simulation_data = None  # A ScriptOutput object

        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.file_quit)

        self.set_title()

        self.scriptLabel = None
        self.scriptField = None
        self._create_widgets()
        self._assign_accelerators()

        self.root.mainloop()

    def _create_widgets(self):
        # The frame containing the widgets
        frame = tk.Frame(self.root)

        # The menu bar
        menu_bar = tk.Menu(self.root, tearoff=0)

        # The File menu
        file_menu = tk.Menu(
            menu_bar, tearoff=0)  # tearoff = 0: can't be seperated from window
        file_menu.add_command(label="New", underline=0,
                              command=self.file_new)  # , accelerator="Ctrl+N")
        file_menu.add_command(
            label="Open...", underline=0,
            command=self.file_open)  # , accelerator="Ctrl+O")
        file_menu.add_command(
            label="Save", underline=0,
            command=self.file_save)  # , accelerator="Ctrl+S")
        file_menu.add_command(label="Save As...",
                              underline=1,
                              command=self.file_save_as)
        file_menu.add_separator()
        file_menu.add_command(label="Exit",
                              underline=1,
                              command=self.file_quit)
        menu_bar.add_cascade(label="File", underline=0, menu=file_menu)

        # The Run menu
        run_menu = tk.Menu(
            menu_bar, tearoff=0)  # tearoff = 0: can't be seperated from window
        run_menu.add_command(label="Simulate and Plot",
                             underline=0,
                             command=self.simulate,
                             accelerator="F5")
        run_menu.add_command(label="Plot", underline=0, command=self.plot)
        menu_bar.add_cascade(label="Run", underline=0, menu=run_menu)

        # The Edit menu
        edit_menu = tk.Menu(
            menu_bar, tearoff=0)  # tearoff = 0: can't be seperated from window
        edit_menu.add_command(label="Undo",
                              underline=0,
                              command=self.undo,
                              accelerator="Ctrl+Z")
        edit_menu.add_command(label="Redo",
                              underline=0,
                              command=self.redo,
                              accelerator="Ctrl+Y")
        menu_bar.add_cascade(label="Edit", underline=0, menu=edit_menu)

        self.root.config(menu=menu_bar)

        # The label
        lbltxt = "Place your script in the box below or open a text file"
        # lbltxt = "Simulate: F5, Open: Ctrl+O, Save: Ctrl+S, New: Ctrl+N"
        scriptLabel = tk.Label(frame, text=lbltxt)
        scriptLabel.pack(side="top", anchor="w")

        # The Text widget
        self.scriptField = ScrolledText(frame)
        self.scriptField.pack(side="top", fill=BOTH, expand=YES)

        self.scriptField.config(undo=True)
        self.scriptField.focus_set()

        # self.scriptField.config(
        #     borderwidth=0,
        #     font="{Lucida Sans Typewriter} 12",
        #     foreground="green",
        #     background="black",
        #     insertbackground="white",  # cursor
        #     selectforeground="green",  # selection
        #     selectbackground="#008000",
        #     wrap=tk.WORD,  # use word wrapping
        #     width=64,
        #     undo=True,  # Tk 8.4
        # )

        # The Quit button
        # quitButton = tk.Button(frame, text="Quit", command=self.quit)
        # quitButton.pack(side="right")

        # The Close All button
        closefigButton = tk.Button(frame,
                                   text="Close All Figures",
                                   command=self.close_figs)
        closefigButton.pack(side="right")

        # The Simulate button
        simButton = tk.Button(frame,
                              text="Simulate and Plot",
                              command=self.simulate)
        simButton.pack(side="left")

        # The Plot button
        plotButton = tk.Button(frame, text="Plot", command=self.plot)
        plotButton.pack(side="left")

        frame.pack(fill=BOTH, expand=YES)

    def simulate(self, event=None):
        try:
            script = self.scriptField.get("1.0", "end-1c")
            script_obj = LsScript.LsScript(script)
            self.simulation_data = script_obj.run()
            script_obj.postproc(self.simulation_data)
        except Exception as ex:
            self.handle_exception(ex)

    def plot(self):
        try:
            if self.simulation_data is None:
                raise LsGuiException("No simulation data to plot.")
            script = self.scriptField.get("1.0", "end-1c")
            script_obj = LsScript.LsScript(script)
            script_obj.postproc(self.simulation_data)
        except Exception as ex:
            self.handle_exception(ex)

    def close_figs(self):
        plt.close("all")

    def handle_exception(self, ex):
        # err_msg = ex.args[0]
        err_msg = str(ex)
        # if len(ex.args) == 2:
        #     err_msg = "{0} {1}".format(err_msg, ex.args[1])
        #     # err_msg = err_msg + ex.args[1]
        messagebox.showerror("Error", err_msg)
        print(traceback.format_exc())

    # def file_open(self):
    #     filename = filedialog.askopenfilename()
    #     # filename = "C:/Python/Python36-32/_Markus/scriptexempel2.txt"  # XXX
    #     file = open(filename, "r")
    #     self.scriptField.delete("1.0", "end-1c")
    #     self.scriptField.insert("1.0", file.read())
    #     self.scriptField.mark_set("insert", "1.0")
    #     file.close()  # Make sure you close the file when done

    def save_changes(self):
        if self.scriptField.edit_modified():
            msg = "This document has been modified. Do you want to save changes?"
            save_changes = messagebox.askyesnocancel("Save?", msg)
            if save_changes is None:  # Cancel
                return False
            elif save_changes is True:  # Yes
                self.file_save()
        return True

    def file_new(self, event=None):
        save_changes = self.save_changes()
        if not save_changes:
            return
        self.scriptField.delete(1.0, "end")
        self.scriptField.edit_modified(False)
        self.scriptField.edit_reset()
        self.file_path = None
        self.set_title()

    def file_open(self, event=None):  # , filepath=None):
        save_changes = self.save_changes()
        if not save_changes:
            return

        # XXX
        initialdir = '.'
        if os.path.isdir('/home/markus/Dropbox/'):
            initialdir = '/home/markus/Dropbox/LearningSimulator/Scripts'

        filepath = filedialog.askopenfilename(filetypes=FILETYPES,
                                              initialdir=initialdir)
        if filepath is not None and len(filepath) != 0:
            with open(filepath, encoding="utf-8") as f:
                file_contents = f.read()
            # Set current text to file contents
            self.scriptField.delete(1.0, "end")
            self.scriptField.insert(1.0, file_contents)
            self.scriptField.edit_modified(False)
            self.scriptField.mark_set("insert", "1.0")
            self.file_path = filepath
            self.set_title()

    def file_save(self, event=None):
        self.file_save_as(filepath=self.file_path)

    def file_save_as(self, filepath=None, event=None):
        if filepath is None:
            filepath = filedialog.asksaveasfilename(filetypes=FILETYPES)
            if len(
                    filepath
            ) == 0:  # Empty tuple or empty string is returned if cancelled
                return  # "cancelled"
        try:
            with open(filepath, 'wb') as f:
                text = self.scriptField.get(1.0, "end-1c")
                f.write(bytes(text, 'UTF-8'))
                self.scriptField.edit_modified(False)
                self.file_path = filepath
                self.set_title()
                return  # "saved"
        except IOError as e:
            self.handle_exception(e)
            return  # "cancelled"

    def file_quit(self, event=None):
        save_changes = self.save_changes()
        if not save_changes:
            return
        self.close_figs()
        self.root.destroy()  # sys.exit(0)

    def set_title(self, event=None):
        if self.file_path is not None:
            # title = os.path.basename(self.file_path)
            title = os.path.abspath(self.file_path)
        else:
            title = "Untitled"
        self.root.title(title + " - " + TITLE)

    def undo(self, event=None):
        try:
            self.scriptField.edit_undo()
        except Exception as e:
            self.handle_exception(e)
        return "break"

    def redo(self, event=None):
        self.scriptField.edit_redo()
        return "break"

    def _assign_accelerators(self):
        # self.scriptField.bind("<Control-n>", self.file_new)
        # self.scriptField.bind("<Control-N>", self.file_new)
        # self.scriptField.bind("<Control-o>", self.file_open)
        # self.scriptField.bind("<Control-O>", self.file_open)
        # self.scriptField.bind("<Control-S>", self.file_save)
        # self.scriptField.bind("<Control-s>", self.file_save)
        self.scriptField.bind("<Control-y>", self.redo)
        self.scriptField.bind("<Control-Y>", self.redo)
        self.scriptField.bind("<Control-z>", self.undo)
        self.scriptField.bind("<Control-Z>", self.undo)

        # self.root.bind_class("Text", ",<Control-z>", self.undo)
        # self.root.bind_class("Text", ",<Control-Z>", self.undo)
        # self.root.bind_class("Text", ",<Control-y>", self.redo)
        # self.root.bind_class("Text", ",<Control-Y>", self.redo)

        self.scriptField.bind("<F5>", self.simulate)
コード例 #24
0
ファイル: THAT_IDE.py プロジェクト: TheRealSAP36/That_IDE
class main:
    def __init__(self, master, lexer):
        self.master = master
        self.master.title("PyDE - Untitled")
        self.filename = None
        self.lexer = lexer
        self.x, self.y = 0, 10
        self.ftsize = 15
        self.end = ""

        self.img = PhotoImage(file="C:/Users/shiven/Desktop/anime.png")
        self.__anime__ = self.img.subsample(3, 3)

        self.mario1 = PhotoImage(
            file="C:/Users/shiven/Desktop/C++/mariofinal1.png")
        self.mario2 = PhotoImage(
            file="C:/Users/shiven/Desktop/C++/mariofinal2.png")

        self.mario1 = self.mario1.subsample(2, 2)

        self.types = [("All Files", "*.*"), ("Text Files", "*.txt")]

        self.draw()
        self.text.bind("<Control-N>", self.newfile)
        self.text.bind("<Control-n>", self.newfile)
        self.text.bind("<Control-S>", self.savefile)
        self.text.bind("<Control-s>", self.savefile)
        self.text.bind("<Control-o>", self.openfile)
        self.text.bind("<Control-O>", self.openfile)

        self.text.bind("<Control-d>", self.copy_cur_line)
        self.text.bind("<Control-D>", self.copy_cur_line)

        self.text.bind("<Tab>", self.spaces)
        self.text.bind("<KeyRelease>", self.cur_line_col)
        self.text.bind("<Button-1>", self.cur_line_col)
        self.text.bind("<Button-3>", self.cur_line_col)
        self.text.bind("<Button-2>", self.cur_line_col)
        self.text.bind("<Motion>", self.cur_line_col)
        self.text.bind("<Configure>", self.cur_line_col)

        self.master.bind("<Control-[>", self.indent)
        self.master.bind("<Control-]>", self.dedent)
        self.master.bind("<Control-/>", self.comment)
        self.master.bind("<Alt-s>", self.uncomment)

        self.master.bind("<Alt-Up>", self.zoom_in)
        self.master.bind("<F3>", self.zoom_out)

        self.master.bind("<Shift-(>", self.insert_paren)
        self.master.bind("<[>", self.insert_paren)
        self.master.bind("<Shift-{>", self.insert_paren)

        self.master.bind("<Control-b>", self.runscript)

        self.animation()
        self.display_time()
        self.__styles()

        self.master.bind("<KeyRelease>", self.highlight)
        self.master.bind("<Key>", self.highlight)

    def highlight(self, e):
        self.recolor()

    def highlight_(self):
        self.recolor()
        self.master.after(1000, self.highlight_())

    def __styles(self):
        self.bdfont = font.Font(self.text, self.text.cget("font"))
        self.bdfont.config(weight=font.BOLD)

        self.itfont = font.Font(self.text, self.text.cget("font"))
        self.itfont.config(slant=font.ITALIC)

        self.style = __get__('default')

        for ttype, ndef in self.style:
            self.tag_font = None
            if ndef['bold']:
                self.tag_font = self.bdfont
            elif ndef['italic']:
                self.tag_font = self.itfont

            if ndef['color']:
                self.fg = "#%s" % ndef['color']

            else:
                self.fg = None

            self.text.tag_configure(str(ttype),
                                    foreground=self.fg,
                                    font=self.tag_font)

    def recolor(self):
        self.code = self.text.get("1.0", "end-1c")
        self.tokensource = self.lexer.get_tokens(self.code)
        self.start_line = 1
        self.start_index = 0

        self.end_line = 1
        self.end_index = 0

        for ttype, value in self.tokensource:
            if "\n" in value:
                self.end_line += value.count("\n")
                self.end_index = len(value.rsplit("\n", 1)[1])

            else:
                self.end_index += len(value)

            if value not in (" ", "\n"):
                idx1 = "%s.%s" % (self.start_line, self.start_index)
                idx2 = "%s.%s" % (self.end_line, self.end_index)

                for tagname in self.text.tag_names(idx1):
                    self.text.tag_remove(tagname, idx1, idx2)

                self.text.tag_add(str(ttype), idx1, idx2)
            self.start_line = self.end_line
            self.start_index = self.end_index

    def draw(self):
        self.filename = None
        self.path = None
        self.master.title("PyDE - {}".format("Untitled"))
        self.master.config(bg="Gray")

        self.anime__ = Canvas(self.master,
                              width=1200,
                              height=25,
                              bg="Gray",
                              relief=RAISED,
                              highlightbackground='Gray')
        self.anime__.pack(anchor=NE)

        self.__display = Label(self.master,
                               text="",
                               bg="Gray",
                               fg="White",
                               padx=55,
                               pady=10,
                               justify=RIGHT,
                               font=("8514oem", 1, 'normal'))
        self.__display.place(x=0, y=0)

        self.lcol = Label(self.master, bg="Gray")
        self.lcol.pack(side=BOTTOM, fill=X)

        self.scrollx = Scrollbar(self.master, orient=HORIZONTAL)
        self.scrollx.pack(side=BOTTOM, fill=X)

        self.text = ST(self.master,
                       xscrollcommand=self.scrollx.set,
                       selectbackground="Gray",
                       fg="Gray",
                       height=400,
                       bg="Black",
                       width=500,
                       wrap=NONE,
                       blockcursor=True)
        self.text.pack(side=TOP)

        self.scrollx.config(command=self.text.xview)

        self.text.config(fg="White",
                         font=("8514oem", self.ftsize, 'bold'),
                         insertbackground="Red")

        self.l_c = Label(self.lcol, bg="Gray")
        self.l_c.pack(side=RIGHT)

        self.timelabel = Label(self.lcol,
                               text="",
                               bg=self.anime__['bg'],
                               font=("8514oem", self.ftsize, "bold"))
        self.timelabel.place(x=0, y=self.master.winfo_height() - 3)

    def newfile(self, e):
        self.filename = None
        self.path = None
        self.curname = "Untitled"
        if len(self.text.get(0.0, END)) > 1:
            self.asknew = askyesno("File changed", "Save file?")
            if self.asknew == True:
                self.savefile_()
            else:
                self.text.delete(1.0, END)
                self.master.title("PyDE - {}".format(self.curname))
                self.__display.config(text="Untitled.py")
        else:
            self.__display.config(text="Untitled.py")

    def savefile_(self):
        if self.filename == None:
            self.s = asksaveasfile(defaultextension=self.types,
                                   filetypes=self.types)
            self.path = self.s.name
            self.curname = self.s.name.split("/")[-1]
            self.master.title("PyDE - {}".format(self.curname))
            self.__display.config(text=self.curname)
        else:
            self.s.write(self.text.get(1.0, END))

    def savefile(self, e):
        if self.filename == None:
            self.s = asksaveasfile(defaultextension=self.types,
                                   filetypes=self.types)
            self.path = self.s.name
            self.curname = self.s.name.split("/")[-1]
            self.master.title("PyDE - {}".format(self.curname))
            self.__display.config(text=self.curname)
        else:
            self.s.write(self.text.get(1.0, END))

    def openfile(self, e):
        try:
            self.o = askopenfile(filetypes=self.types,
                                 defaultextension=self.types)
            self.curname = self.o.name.split("/")[-1]
            self.path = self.o.name
            self.master.title("PyDE - {}".format(self.curname))
            self.__display.config(text=self.curname)
            if self.text.edit_modified():
                self.a_open = askyesno("save this thing?", "Save file?")
                if self.a_open == True:
                    self.savefile_()
                else:
                    pass
            else:
                self.text.delete(0.0, END)
                self.op = self.o.read()
                self.text.insert(END, self.op)
        except UnicodeDecodeError:
            self.unable = showerror("Invalid file", "Invalid file")

    def openfile_(self):
        try:
            if self.text.edit_modified():
                self.savefile_()
            else:
                self.o = askopenfile(filetypes=self.types,
                                     defaultextension=self.types)
                self.op = self.o.read()
                self.path = self.o.name
                self.text.insert(END, self.op)
        except UnicodeDecodeError:
            self.unable = showerror("Invalid file", "Invalid file")

    def animation(self):
        self.x += 5
        self.anime__.delete(ALL)
        self.anime__.create_image(self.x * 2, self.y + 5, image=self.mario1)
        if (self.x - 10) >= self.anime__.winfo_width():
            self.x = 0
        self.master.after(100, self.animation)


#          self.y-=5

    def cur_line_col(self, e):
        self.l_raw = self.text.index(INSERT)
        self.lines = self.l_raw.split(".")[0]
        self.cols = self.l_raw.split(".")[1]
        self.binder_ = int(self.cols)
        self.l_c.config(text="lines:{0}  columns:{1}".format(
            self.lines, self.cols),
                        font=("8514oem", 9, 'bold'))

    def spaces(self, e):
        self.text.insert(INSERT, " " * 4)
        return 'break'

    def indent(self, e):
        self.tab = "    "
        self.untabbed = self.text.get("sel.first", "sel.last")
        self.splitted = self.untabbed.split("\n")
        self.text.delete("sel.first", "sel.last")
        self.conts = []
        for self.conts in list(self.splitted):
            self.conts = self.tab + self.conts + "\n"
            self.text.insert(INSERT, self.conts)

    def dedent(self, e):
        self.tab = "    "
        self.tabbed = self.text.get("sel.first", "sel.last")
        self.splitted = self.tabbed.split("\n")
        self.text.delete("sel.first", "sel.last")
        self.conts = []
        for self.conts in list(self.splitted):
            self.conts = self.conts.replace(self.tab, "") + "\n"
            self.text.insert(INSERT, self.conts)

    def comment(self, e):
        self.comment = "#"
        self.uncommented = self.text.get("sel.first", "sel.last")
        self.split_comment = self.uncommented.split("\n")
        self.split_comment = list(self.split_comment)
        self.text.delete("sel.first", "sel.last")
        self.commconts = []
        for self.commconts in self.split_comment:
            self.commconts = self.comment + self.commconts + "\n"
            self.text.insert(INSERT, self.commconts)

    def uncomment(self, e):
        self.comment = "#"
        self.commented = self.text.get("sel.first", "sel.last")
        self.split_uncomm = self.commented.split("\n")
        self.split_uncomm = list(self.split_uncomm)
        self.text.delete("sel.first", "sel.last")
        self.unconts = []
        for self.unconts in self.split_uncomm:
            self.unconts = self.unconts.replace(self.comment, "") + "\n"
            self.text.insert(INSERT, self.unconts)

    def runscript(self, e):
        if self.path == None:
            self.asksave = askyesno("Save this file?", "Save?")
            if self.asksave == True:
                self.savefile()
                os.system("python {}".format(self.path))
                self.result = str(
                    subprocess.check_output(['python', self.path]))
                self.output = showinfo("Output", "%s" % (self.result))

            else:
                showinfo("Cant run before saving..",
                         "Cant run before saving..")
        else:
            os.system("python {}".format(self.path))
            self.result = str(subprocess.check_output(['python', self.path]))
            self.output = showinfo("Output", "%s" % (self.result))

    def zoom_in(self, event):
        self.ftsize += 2
        self.bdfont.config(size=self.ftsize)
        self.itfont.config(size=self.ftsize)
        self.text.config(font=("8514oem", self.ftsize, 'bold'))

    def zoom_out(self, e):
        self.ftsize -= 2
        self.bdfont.config(size=self.ftsize)
        self.itfont.config(size=self.ftsize)
        self.text.config(font=("8514oem", self.ftsize, "bold"))

    def display_time(self):
        self.curtime = strftime("%H : %M : %S")
        self.timelabel.config(text=self.curtime)
        self.master.after(1000, self.display_time)

    def insert_paren(self, e):
        self.startparams = "([{"
        self.endparams = ")]}"
        self.cursor = self.text.index(INSERT)
        self.linecur = str(self.cursor.split(".")[0])
        self.colcur = int(self.cursor.split(".")[1])
        if e.char == self.startparams[0]:
            self.text.insert(INSERT, self.endparams[0])
            self.text.mark_set(INSERT, self.linecur + "." + str(self.colcur))
        elif e.char == self.startparams[1]:
            self.text.insert(INSERT, self.endparams[1])
            self.text.mark_set(INSERT, self.linecur + "." + str(self.colcur))
        elif e.char == self.startparams[2]:
            self.text.insert(INSERT, self.endparams[2])
            self.text.mark_set(INSERT, self.linecur + "." + str(self.colcur))
        else:
            pass

    def copy_cur_line(self, e):
        self.linetext = self.text.get("insert linestart", "insert lineend")
        self.newidx = float(self.text.index(INSERT)) + 1.1
        self.text.insert(INSERT, "\n")
        self.text.insert(self.newidx, self.linetext + "\n")
        self.text.mark_set("insert", self.newidx)

        return 'break'
コード例 #25
0
class myPanel(tkinter.Tk):
    def __init__(self):
        tkinter.Tk.__init__(self, 'lsx')
        self.withdraw()  # 先withdraw隐藏再deiconify显示可使setCenter不会导致页面闪烁

        self.title('电话簿v1.05 (联系作者:QQ11313213)')  # TODO 是否有用

        self.keys_var = tkinter.StringVar()
        self.tex1 = ScrolledText(self)
        ent1 = tkinter.Entry(self, textvariable=self.keys_var, width=125)
        ent1.pack(padx=2,
                  pady=2,
                  fill=tkinter.constants.BOTH,
                  side=tkinter.constants.TOP)
        self.tex1.pack(padx=2,
                       pady=2,
                       fill=tkinter.constants.BOTH,
                       expand=True)

        self.menu = tkinter.Menu(self, tearoff=0)
        self.menu.add_command(label='复制', command=self.copyItem)
        self.menu.add_separator()
        self.menu.add_command(label='来源')
        self.menu.add_separator()
        self.menu.add_command(label='刷新', command=readContacts2)
        self.menu.add_command(label='前后文', command=self.location)
        self.menu.add_separator()
        self.menu.add_command(label='导入文件', command=ImportFiles)
        self.menu.add_command(label='新增和更改', command=UpdateFile)

        self.menu0 = tkinter.Menu(self, tearoff=0)
        self.menu0.add_command(label='刷新', command=readContacts2)
        self.menu0.add_separator()
        self.menu0.add_command(label='导入文件', command=ImportFiles)
        self.menu0.add_command(label='新增和更改', command=UpdateFile)
        self.menu0.add_separator()

        submenu = [tkinter.Menu(self, tearoff=0)]
        self.menu0.add_cascade(label='Designed by Lsx. ', menu=submenu[0])

        for key, value in [['Name', 'Li Shixian'], ['Mail', '*****@*****.**'],
                           ['Website', 'github.com/znsoooo/contacts'],
                           ['Wechat', 'Xian_2'], ['Donate', 'xxxx']]:
            submenu.append(tkinter.Menu(self, tearoff=0))
            submenu.append(tkinter.Menu(self, tearoff=0))
            submenu[-1].add_command(label=value)
            submenu[0].add_cascade(label=key, menu=submenu[-1])
        self.img_wechat = tkinter.PhotoImage(
            data=Image.img1)  # 没有self会导致显示图片为空白
        self.img_donate = tkinter.PhotoImage(data=Image.img2)
        submenu[8].entryconfig(0, image=self.img_wechat)
        submenu[10].entryconfig(0, image=self.img_donate)
        submenu[0].add_separator()
        submenu[0].add_command(label='All Rights Reserved.', command=bonus)

        setCenter(self)
        self.deiconify()

        ent1.focus()
        ent1.bind('<KeyRelease>', self.onKeyRelease)
        self.tex1.bind('<ButtonRelease-3>', self.onRightClick)

    def select(self, row):
        self.tex1.mark_set('insert', '%d.0' % row)
        self.tex1.tag_remove('sel', '0.0', 'end')
        self.tex1.tag_add('sel', '%d.0' % row, '%d.0' % (row + 1))

    def location(self, row=0):
        if not row:
            row = self.current_index + 1
        self.onKeyRelease(keys='')
        self.select(row)
        self.tex1.see('%d.0' % row)

    def copyItem(self):
        text = self.tex1.selection_get()
        self.clipboard_clear()
        self.clipboard_append(text[:-1])  # 去掉文末换行符

    def onRightClick(self, evt=0):
        self.tex1.focus()  # 当焦点在ent1中时
        self.current = int(self.tex1.index('current').split('.')[0])
        if len(self.index):
            self.current_index = self.index[self.current - 1]

            line_last = 0
            for line, file in file_list:
                if line > self.current_index:
                    break
                else:
                    line_last = line
            self.menu.entryconfig(2,
                                  label='来源: %s (line:%s)' %
                                  (file, self.current_index - line_last + 1))
            self.menu.entryconfig(
                2,
                command=lambda: os.popen('explorer /select, %s\\%s\\%s' %
                                         (os.getcwd(), DATA_FOLDER, file)))

            self.select(self.current)
            self.menu.post(evt.x_root, evt.y_root)
        else:
            self.menu0.post(evt.x_root, evt.y_root)

        return self.current

    def onKeyRelease(self, evt=0, keys=None):
        if keys is None:
            keys = self.keys_var.get()
        keys = keys.lower().split(' ')
        ss_new = []
        self.index = []
        for n, s in enumerate(ss):
            ok = True
            for key in keys:
                if key not in s[1]:
                    ok = False
            if ok:
                ss_new.append(s[0])
                self.index.append(n)  # TODO 提出搜索部分到独立的函数

        self.tex1.config(state='normal')
        self.tex1.delete('1.0', 'end')
        self.tex1.insert('1.0', '\n'.join(ss_new))
        self.tex1.config(state='disabled')  # 禁止编辑
        self.title('电话簿v1.05 (联系作者:QQ11313213) - %s结果' %
                   len(ss_new))  # title更改耗时短可以做到'同时'更改的效果

        return ss_new
コード例 #26
0
class NoteEditor:
    def __init__(self):
        self.id = None
        self.page_name = None
        self.font_name = 'arial'
        self.font_size = 12
        self.font_weight = tk.NORMAL
        self.editor = None
        self.file_io = FileIO()
        self.syntax_file_io = FileIO()

    def create_editor(self, master):
        self.editor = ScrolledText(master,
                                   undo=True,
                                   autoseparators=True,
                                   maxundo=-1)

        # Styling of text area
        self.set_editor_font(None, None)

        self.editor.pack(side="left")
        self.editor.focus()
        self.editor.pack(fill="both", expand=True)

        # Configuring style tags
        self.editor.tag_config("BACKGROUND", background="yellow")
        self.editor.tag_configure("HIGHLIGHT", foreground="red")
        self.editor['wrap'] = tk.NONE

        self.editor.bind('<Button-3>', self.rClicker, add='')

    def set_editor_font(self, font_name, font_size, font_weight=None):
        if font_name is not None:
            self.font_name = font_name

        if font_size is not None and int(font_size) > 0:
            self.font_size = font_size

        if font_weight is not None:
            self.font_weight = font_weight

        self.editor['font'] = Font(family=self.font_name,
                                   size=self.font_size,
                                   weight=self.font_weight)

    def set_editor_bgcolor(self, hex_color):
        self.editor['background'] = hex_color

    def set_editor_fgcolor(self, hex_color):
        self.editor['foreground'] = hex_color

    def set_emphasis(self, on):
        if on == 1:
            bold_font = Font(family=self.font_name,
                             size=self.font_size,
                             weight="bold")
            self.editor.tag_configure("BOLDFONT", font=bold_font)
            if self.editor.tag_ranges(tk.SEL):
                self.editor.tag_add("BOLDFONT", tk.SEL_FIRST, tk.SEL_LAST)
            else:
                self.editor.tag_add("BOLDFONT", "1.0", tk.END)
        else:
            self.editor.tag_remove("BOLDFONT", "1.0", tk.END)

    def toggle_wrap(self, on):
        if on == 1:
            self.editor['wrap'] = tk.WORD
        else:
            self.editor['wrap'] = tk.NONE

    def search_forward(self, text):
        located_start = self.editor.search(text,
                                           tk.INSERT,
                                           stopindex=tk.END,
                                           forwards=True,
                                           nocase=True)
        located_end = '{}+{}c'.format(located_start, len(text))
        if located_start is '' or located_end is '':
            return False

        self.select_editor_location(located_start, located_end)

        # Start position is moved after current found location.
        self.editor.mark_set(tk.INSERT, located_end)
        return True

    def search_backward(self, text):
        located_start = self.editor.search(text,
                                           tk.INSERT,
                                           stopindex='1.0',
                                           backwards=True,
                                           nocase=True)
        located_end = '{}+{}c'.format(located_start, len(text))
        if located_start is '' or located_end is '':
            return False

        self.select_editor_location(located_start, located_end)

        # Start position is moved after current found location.
        self.editor.mark_set(tk.INSERT, located_start)
        return True

    def replace_selected_text(self, new_text):
        self.editor.delete('sel.first', 'sel.last')
        self.editor.insert('insert', new_text)

    def select_editor_location(self, selection_start, selection_end):
        print('Found location start: ', selection_start)
        print('Found location end: ', selection_end)
        selection_start_float = float(selection_start)
        self.editor.tag_remove(tk.SEL, "1.0", 'end')
        self.editor.tag_add(tk.SEL, selection_start, selection_end)
        self.editor.focus_force()
        self.editor.see(selection_start_float)

    def is_dirty(self):
        return self.editor.edit_modified()

    def rClicker(self, e):
        ''' right click context menu for all Tk Entry and Text widgets
        '''

        try:

            def rClick_Copy(e, apnd=0):
                e.widget.event_generate('<Control-c>')

            def rClick_Cut(e):
                e.widget.event_generate('<Control-x>')

            def rClick_Paste(e):
                e.widget.event_generate('<Control-v>')

            def rClick_Highlight_Keyword(e):
                self.highlight_syntax(True)

            e.widget.focus()

            nclst = [
                (' Cut', lambda e=e: rClick_Cut(e)),
                (' Copy', lambda e=e: rClick_Copy(e)),
                (' Paste', lambda e=e: rClick_Paste(e)),
                (' Highlight Keyword',
                 lambda e=e: rClick_Highlight_Keyword(e)),
            ]

            rmenu = tk.Menu(None, tearoff=0, takefocus=0)

            for (txt, cmd) in nclst:
                rmenu.add_command(label=txt, command=cmd)

            rmenu.tk_popup(e.x_root + 40, e.y_root + 10, entry="0")

        except tk.TclError:
            print
            ' - rClick menu, something wrong'
            pass

        return "break"

    def highlight_syntax(self, enable=True):
        syntax_file = Path(Path(
            self.file_io.file_name).suffix[1:]).with_suffix('.hs')
        hs_config_data = Configuration.get_hs_configuration(syntax_file)
        if hs_config_data is None:
            print('No syntax file ', syntax_file)
            return
        #print(hs_config_data)
        keywords = hs_config_data['keyword']['tags']
        keyword_fgcolor = hs_config_data['keyword']['color']
        constant_fgcolor = hs_config_data['constant']['color']

        numbers = re.findall(r'\d{1,3}', self.file_io.file_data)
        self.editor.tag_config('tg_kw', foreground=keyword_fgcolor)
        self.editor.tag_config('tg_num', foreground=constant_fgcolor)
        #keywords = ['package', 'public', 'private', 'abstract', 'internal', 'new', 'static', 'final', 'long', 'extends',
        #            'class', 'import', 'null', 'for', 'if', 'return', 'int', 'char', 'float', 'double', 'implements']
        for keyword in keywords:
            self.editor.mark_set(tk.INSERT, '1.0')
            while True:
                located_end = self.highlight_keyword(keyword + ' ', 'tg_kw')
                if located_end == 0:
                    break
                self.editor.mark_set(tk.INSERT, located_end)

        self.editor.mark_set(tk.INSERT, '1.0')
        for each_number in numbers:
            located_end = self.highlight_keyword(each_number, 'tg_num')
            if located_end != 0:
                self.editor.mark_set(tk.INSERT, located_end)

        print("Syntax highlight executed.")

    def highlight_keyword(self, text, tag):
        located_start = self.editor.search(text,
                                           tk.INSERT,
                                           stopindex=tk.END,
                                           forwards=True,
                                           nocase=False)
        located_end = '{}+{}c'.format(located_start, len(text))
        print(located_start, ',', located_end)
        print('keyword', text)
        if located_start is '' or located_end is '':
            return 0

        self.editor.tag_add(tag, located_start, located_end)
        return located_end