python - Why is my widget being overlapped? -


i using bryan oakley's code @ tkinter adding line number text widget create text widget line numbers. want create custom widget can use text widget optional line numbers. in:

t = linedtext(top) t.insert("insert", "hello") t.show() 

but of now, when show line numbers, covers text widget. window resized automatically. why happening? code:

import tkinter tk   class textlinenumbers(tk.canvas):      def __init__(self, *args, **kwargs):         tk.canvas.__init__(self, *args, **kwargs)         self.textwidget = none      def attach(self, text_widget):         self.textwidget = text_widget      def redraw(self, *args):         '''redraw line numbers'''         self.delete("all")          = self.textwidget.index("@0,0")         while true :             dline= self.textwidget.dlineinfo(i)             if dline none: break             y = dline[1]             linenum = str(i).split(".")[0]             self.create_text(2,y,anchor="nw", text=linenum)             = self.textwidget.index("%s+1line" % i)   class customtext(tk.text):     def __init__(self, *args, **kwargs):         tk.text.__init__(self, *args, **kwargs)          self.tk.eval('''             proc widget_proxy {widget widget_command args} {                  # call real tk widget command real args                 set result [uplevel [linsert $args 0 $widget_command]]                  # generate event types of commands                 if {([lindex $args 0] in {insert replace delete}) ||                     ([lrange $args 0 2] == {mark set insert}) ||                      ([lrange $args 0 1] == {xview moveto}) ||                     ([lrange $args 0 1] == {xview scroll}) ||                     ([lrange $args 0 1] == {yview moveto}) ||                     ([lrange $args 0 1] == {yview scroll})} {                      event generate  $widget <<change>> -when tail                 }                  # return result real widget command                 return $result             }             ''')         self.tk.eval('''             rename {widget} _{widget}             interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}         '''.format(widget=str(self)))   class linedtext(customtext):      def __init__(self, *args, **kwargs):         customtext.__init__(self, *args, **kwargs)          self.settings = self.settings()         self.linenumbers = none          self.text = super()                self.vsb = tk.scrollbar(orient="vertical", command=self.yview)         self.vsb.pack(side="right", fill="y")          self.text.configure(yscrollcommand=self.vsb.set)         self.text.tag_configure("bigfont", font=("helvetica", "24", "bold"))         self.text.pack(side="left", fill="both", expand=true)         self.text.bind("<<change>>", self._on_change)         self.text.bind("<configure>", self._on_change)         self.text.insert("end", "one\ntwo\nthree\n")         self.text.insert("end", "four\n",("bigfont",))         self.text.insert("end", "five\n")         self.text.pack(side="left")      def hide(self,event=none):         if not self.settings.hide_linenumbers:             self.settings.hide_linenumbers = true             self.linenumbers.pack_forget()      def show(self,event=none):         if self.linenumbers == none:             self.linenumbers = textlinenumbers(self, width=30)             self.linenumbers.attach(self.text)             self.linenumbers.pack(side="left", fill="y")         elif self.settings.hide_linenumbers:             self.settings.hide_linenumbers = false             self.linenumbers.pack(side="left", fill="y")      def _on_change(self, event):         if self.linenumbers:             self.linenumbers.redraw()      class settings():         def __init__(self):             self.hide_linenumbers = true   if __name__ == "__main__":     root = tk.tk()     text = linedtext(root)     #text.pack(side="right", fill="both", expand=true)     button = tk.button(root, text="hide", command=text.hide)     button.pack()     button = tk.button(root, text="show", command=text.show)     button.pack()     root.mainloop() 

also, assuming .pack() opposed .pack(side="left"), widget drawn below previous widgets. buttons being drawn right. how them draw below text , line widgets? absolutely need use .grid() or frame?

first of all, not sure understood logic in functions show , hide, in code below, see, have changed little bit functions.

i not sure why using super() initialise self.text in linedtext class, think problem starts there.

what first did make linedtext inherit frame instead of customtext, , create instance variable called self.text of type customtext in linedtext class. did because think of linedtext class container 2 other objects of type customtext , textlinenumbers.

i decided split main window (the root) in 2 frames, 1 linedtext object, , 1 contain buttons show , hide. in way, can pack frames, instead of single widgets, , can example pack frame buttons @ bottom, , frame linedtext object @ top.

using frames organise data right , easier way go when creating layouts.

one thing changed make textlinenumber pretty numbers drawn. check comments on code.

another thing want should compare value of object none using is or is not, instead of == , !=.

also, not seeing point of having class (settings) instance variable, not make sense, , guess doing because class become larger in future.

if have problems regarding fact window shrinks when introduce or remove widget, check out question

how stop tkinter frame shrinking fit contents?

i hope understand logic of methods show , hide, if not, ask.

here's full code:

import tkinter tk   class textlinenumbers(tk.canvas):      def __init__(self, *args, **kwargs):         tk.canvas.__init__(self, *args, **kwargs)         self.textwidget = none      def attach(self, text_widget):         self.textwidget = text_widget      def redraw(self, *args):         '''redraw line numbers'''         self.delete("all")          = self.textwidget.index("@0,0")          while true :             dline= self.textwidget.dlineinfo(i)             if dline none: break             y = dline[1]             linenum = str(i).split(".")[0]              # changed text draw: starts 4             self.create_text(4, y, anchor="nw", text=linenum)               = self.textwidget.index("%s+1line" % i)   class customtext(tk.text):     def __init__(self, *args, **kwargs):         tk.text.__init__(self, *args, **kwargs)          self.tk.eval('''             proc widget_proxy {widget widget_command args} {                  # call real tk widget command real args                 set result [uplevel [linsert $args 0 $widget_command]]                  # generate event types of commands                 if {([lindex $args 0] in {insert replace delete}) ||                     ([lrange $args 0 2] == {mark set insert}) ||                      ([lrange $args 0 1] == {xview moveto}) ||                     ([lrange $args 0 1] == {xview scroll}) ||                     ([lrange $args 0 1] == {yview moveto}) ||                     ([lrange $args 0 1] == {yview scroll})} {                      event generate  $widget <<change>> -when tail                 }                  # return result real widget command                 return $result             }             ''')         self.tk.eval('''             rename {widget} _{widget}             interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}         '''.format(widget=str(self)))   class linedtext(tk.frame):      def __init__(self, *args, **kwargs):         tk.frame.__init__(self, *args, **kwargs)          self.settings = self.settings()         self.linenumbers = none          self.text = customtext(self)         self.vsb = tk.scrollbar(orient="vertical", command=self.text.yview)         self.vsb.pack(side="right", fill="y")          self.text.configure(yscrollcommand=self.vsb.set)         self.text.tag_configure("bigfont", font=("helvetica", "24", "bold"))         self.text.bind("<<change>>", self._on_change)         self.text.bind("<configure>", self._on_change)         self.text.insert("end", "one\ntwo\nthree\n")         self.text.insert("end", "four\n",("bigfont",))         self.text.insert("end", "five\n")         self.text.focus()                 self.text.pack(side="right", fill="both", expand=true)      def hide(self,event=none):         if not self.settings.hide_linenumbers:             self.settings.hide_linenumbers = true             self.linenumbers.pack_forget()             self.linenumbers = none      def show(self,event=none):         if self.linenumbers none:             self.linenumbers = textlinenumbers(self, width=30)             self.linenumbers.attach(self.text)             self.linenumbers.pack(side="left", fill="y")             self.settings.hide_linenumbers = false      def _on_change(self, event):         if self.linenumbers:             self.linenumbers.redraw()      class settings():         def __init__(self):             self.hide_linenumbers = true   if __name__ == "__main__":     root = tk.tk()      top_frame = tk.frame(root)     text = linedtext(top_frame)     text.pack(expand=1, fill="both")     top_frame.pack(side="top", expand=1, fill="both")      bottom_frame = tk.frame(root)     button = tk.button(bottom_frame, text="hide", command=text.hide)     button.pack(side="right")     button = tk.button(bottom_frame, text="show", command=text.show)     button.pack(side="right")     bottom_frame.pack(side="bottom", fill="x")      root.mainloop() 

Comments

Popular posts from this blog

qt - Using float or double for own QML classes -

Create Outlook appointment via C# .Net -

ios - Swift Array Resetting Itself -