how come .insert() don't work

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bennie

    #1

    how come .insert() don't work

    Hi all,

    I have a little problem.

    def tekst_in(self, tag):
    tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
    print tekst_tag[tag]
    works fine in my class

    But...
    def tekst_in(self, tag):
    tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
    self.tekst.inse rt(INSERT, tekst_tag[tag])

    Then I get a AttributeError. ..
    I seached the net, can come op white a answer.
    So I hope You all can!

    Bennie,

  • Martin v. Löwis

    #2
    Re: how come .insert() don't work

    Bennie wrote:[color=blue]
    > def tekst_in(self, tag):
    > tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
    > self.tekst.inse rt(INSERT, tekst_tag[tag])
    >
    > Then I get a AttributeError. ..
    > I seached the net, can come op white a answer.[/color]

    What specific attribute is mentioned in the AttributeError?
    That self has no attribute tekst, or that self.tekst has
    no attribute insert?

    If the former, you need to arrange your class so that self has
    an attribute tekst (e.g. by initializing tekst in __init__).

    If the latter: what kind of thing is self.tekst?

    Regards,
    Martin

    Comment

    • Bennie

      #3
      Re: how come .insert() don't work

      Martin v. Löwis wrote:[color=blue]
      > Bennie wrote:
      >[color=green]
      >> def tekst_in(self, tag):
      >> tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
      >> self.tekst.inse rt(INSERT, tekst_tag[tag])
      >>
      >> Then I get a AttributeError. ..
      >> I seached the net, can come op white a answer.[/color]
      >
      >
      > What specific attribute is mentioned in the AttributeError?
      > That self has no attribute tekst, or that self.tekst has
      > no attribute insert?
      >
      > If the former, you need to arrange your class so that self has
      > an attribute tekst (e.g. by initializing tekst in __init__).
      >
      > If the latter: what kind of thing is self.tekst?
      >
      > Regards,
      > Martin[/color]
      self.tekst is a Tkinter.Text() so it has a insert attribute, .insert()

      Comment

      • David M. Cooke

        #4
        Re: how come .insert() don't work

        Bennie <bennie@rotzjes .nl> writes:[color=blue]
        > Martin v. Löwis wrote:[color=green]
        >> Bennie wrote:
        >>[color=darkred]
        >>> def tekst_in(self, tag):
        >>> tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
        >>> self.tekst.inse rt(INSERT, tekst_tag[tag])
        >>>
        >>> Then I get a AttributeError. ..
        >>> I seached the net, can come op white a answer.[/color]
        >> What specific attribute is mentioned in the AttributeError?
        >> That self has no attribute tekst, or that self.tekst has
        >> no attribute insert?
        >> If the former, you need to arrange your class so that self has
        >> an attribute tekst (e.g. by initializing tekst in __init__).
        >> If the latter: what kind of thing is self.tekst?
        >> Regards,
        >> Martin[/color]
        > self.tekst is a Tkinter.Text() so it has a insert attribute, .insert()[/color]

        See, you should have mentioned that before. What you should also
        mention is:

        1) the _exact_ text of the traceback. Saying "I get an AttributeError"
        is not nearly enough: the full message has info that
        people-in-the-know know how to interpret. Copy-and-paste it.

        2) the smallest (or so) of *working* code that will exhibit the error.
        The snippet in your original post doesn't work. Again, copy-and-paste.

        Basically, put enough info in your question that we don't have to read
        your mind.

        Now I'll put my mind-reading cap on...

        - Are you sure that tekst_in() is a method, not a function? The
        indentation suggests function, while the self parameter suggests method.

        - Are you positive self.tekst is a Tkinter.Text()? Throw in some
        print statements to check. 'print repr(self)' is a good one.

        - tekst_tag[tag] shouldn't be the problem (as suggested by your
        original post), as that would raise a KeyError, not an AttributeError.

        etc.

        (I'll bet once you've done what I've suggested, you'll have found the bug...)

        --
        |>|\/|<
        /--------------------------------------------------------------------------\
        |David M. Cooke
        |cookedm(at)phy sics(dot)mcmast er(dot)ca

        Comment

        • Bennie

          #5
          Re: how come .insert() don't work


          Hi,

          This is a chunck out of my program:
          --------------------------------------------------
          from Tkinter import *

          class App:
          def __init__(self, master):
          frame = Frame(master)
          frame.pack()

          self.menubar = Menu(root)
          self.html = Menu(self.menub ar, tearoff=0)
          self.html.add_c ommand(label="p ", command=self.te kst_in('p'))
          # self.html.add_c ommand(label="p ", command=self.te kst_a)
          self.menubar.ad d_cascade(label ="html", menu=self.html)

          root.config(men u=self.menubar)

          self.tekst = Text()
          self.tekst.pack (fill=BOTH, expand=YES)

          def tekst_in(self, tag):
          tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
          self.tekst.inse rt(INSERT, tekst_tag[tag])

          # This works
          #def tekst_a(self):
          # self.tekst.inse rt(INSERT, "<p> </p>")


          if __name__ == '__main__':
          root = Tk()
          app = App(root)
          root.mainloop()


          --------------------------------------------------


          The error is:
          -------------------------------
          Traceback (most recent call last):
          File "test.py", line 30, in ?
          app = App(root)
          File "test.py", line 10, in __init__
          self.html.add_c ommand(label="p ", command=self.te kst_in('p'))
          File "test.py", line 21, in tekst_in
          self.tekst.inse rt(INSERT, tekst_tag[tag])
          AttributeError: App instance has no attribute 'tekst'
          ------------------------------------------------------
          hope this is enough info.

          Comment

          • Eric Brunel

            #6
            Re: how come .insert() don't work

            Bennie wrote:[color=blue]
            >
            > Hi,
            >
            > This is a chunck out of my program:
            > --------------------------------------------------
            > from Tkinter import *
            >
            > class App:
            > def __init__(self, master):
            > frame = Frame(master)
            > frame.pack()
            >
            > self.menubar = Menu(root)
            > self.html = Menu(self.menub ar, tearoff=0)
            > self.html.add_c ommand(label="p ", command=self.te kst_in('p'))[/color]

            You're using your tekst_in method before setting the attribute self.tekst, so
            when the method code is executed, there is actully no attribute named tekst;
            hence the Attribute error.

            Move the previous line after the self.tekst.pack (...) line and everything should
            be fine.
            [color=blue]
            > # self.html.add_c ommand(label="p ", command=self.te kst_a)
            > self.menubar.ad d_cascade(label ="html", menu=self.html)
            >
            > root.config(men u=self.menubar)
            >
            > self.tekst = Text()
            > self.tekst.pack (fill=BOTH, expand=YES)
            >
            > def tekst_in(self, tag):
            > tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
            > self.tekst.inse rt(INSERT, tekst_tag[tag])
            >
            > # This works
            > #def tekst_a(self):
            > # self.tekst.inse rt(INSERT, "<p> </p>")
            >
            >
            > if __name__ == '__main__':
            > root = Tk()
            > app = App(root)
            > root.mainloop()
            >
            >
            > --------------------------------------------------
            >
            >
            > The error is:
            > -------------------------------
            > Traceback (most recent call last):
            > File "test.py", line 30, in ?
            > app = App(root)
            > File "test.py", line 10, in __init__
            > self.html.add_c ommand(label="p ", command=self.te kst_in('p'))
            > File "test.py", line 21, in tekst_in
            > self.tekst.inse rt(INSERT, tekst_tag[tag])
            > AttributeError: App instance has no attribute 'tekst'
            > ------------------------------------------------------
            > hope this is enough info.[/color]

            HTH
            --
            - Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
            PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

            Comment

            • Bennie

              #7
              Re: how come .insert() don't work

              Eric Brunel wrote:
              [color=blue]
              > Bennie wrote:
              >[color=green]
              >>
              >> Hi,
              >>
              >> This is a chunck out of my program:
              >> --------------------------------------------------
              >> from Tkinter import *
              >>
              >> class App:
              >> def __init__(self, master):
              >> frame = Frame(master)
              >> frame.pack()
              >> self.menubar = Menu(root)
              >> self.html = Menu(self.menub ar, tearoff=0)
              >> self.html.add_c ommand(label="p ", command=self.te kst_in('p'))[/color]
              >
              >
              > You're using your tekst_in method before setting the attribute
              > self.tekst, so when the method code is executed, there is actully no
              > attribute named tekst; hence the Attribute error.
              >
              > Move the previous line after the self.tekst.pack (...) line and
              > everything should be fine.
              >[color=green]
              >> # self.html.add_c ommand(label="p ", command=self.te kst_a)
              >> self.menubar.ad d_cascade(label ="html", menu=self.html)
              >> root.config(men u=self.menubar)
              >> self.tekst = Text()
              >> self.tekst.pack (fill=BOTH, expand=YES)
              >> def tekst_in(self, tag):
              >> tekst_tag={'p': '\t\t<p>\n\n\t\ t</p>\n', 'br': '<br />'}
              >> self.tekst.inse rt(INSERT, tekst_tag[tag])
              >>
              >> # This works
              >> #def tekst_a(self):
              >> # self.tekst.inse rt(INSERT, "<p> </p>")
              >>
              >> if __name__ == '__main__':
              >> root = Tk()
              >> app = App(root)
              >> root.mainloop()
              >>
              >>
              >> --------------------------------------------------
              >>
              >>
              >> The error is:
              >> -------------------------------
              >> Traceback (most recent call last):
              >> File "test.py", line 30, in ?
              >> app = App(root)
              >> File "test.py", line 10, in __init__
              >> self.html.add_c ommand(label="p ", command=self.te kst_in('p'))
              >> File "test.py", line 21, in tekst_in
              >> self.tekst.inse rt(INSERT, tekst_tag[tag])
              >> AttributeError: App instance has no attribute 'tekst'
              >> ------------------------------------------------------
              >> hope this is enough info.[/color]
              >
              >
              > HTH[/color]
              But now he execute te self.tekst_in without user input.

              Comment

              • Alex Martelli

                #8
                Re: how come .insert() don't work

                Eric Brunel <eric_brunel@de spammed.com> wrote:
                ...[color=blue][color=green]
                > > self.html = Menu(self.menub ar, tearoff=0)
                > > self.html.add_c ommand(label="p ", command=self.te kst_in('p'))[/color]
                >
                > You're using your tekst_in method before setting the attribute self.tekst, so
                > when the method code is executed, there is actully no attribute named tekst;
                > hence the Attribute error.[/color]

                Perfectly true.
                [color=blue]
                > Move the previous line after the self.tekst.pack (...) line and everything
                > should be fine.[/color]

                Nope. I guess it won't be, because I suspect the OP doesn't actually
                mean to insert a 'p' during the __init__ while adding a command of None.

                I guess what he means is that, when that menuentry is selected, then and
                only then does a 'p' get inserted. But what he's SAYING is to call the
                method right then and there, not set it as a callback as I guess he
                means to do.

                I think that, to make everything fine, what he needs to do is, rather,
                something like:

                ..., command=lambda: self.tekst_in(' p'))

                For the OP (as I think Eric knows this): 'command' must be set to a
                CALLABLE, something Tkinter WILL call without arguments later when
                needed; you're setting it to the RESULT of a call that you're doing
                yourself, right then and there (and that result is None). Prepending a
                'lambda:' (an unfortunately murky keyword) makes and binds to command a
                no-arguments callable, as needed.

                It is, of course, very unlikely that method 'self.tekst_in' only ever
                needs to be called with that one argument, 'p', or only ever needs to be
                bound that way. If you need to bind callables that will call 'p' with
                each of a range of arguments, as would usually be the case, you're
                better off forgetting lambda and using closures instead. Say that,
                besides 'p', you also want commands 'q', 'r', 's', 't'. Then, do:

                self.html = Menu(self.menub ar, tearoff=0)
                def make_command(x) :
                def callable(): self.tekst_in(x )
                return callable
                for x in 'pqrst':
                self.html.add_c ommand(label=x, command=make_ca llable(x))


                Alex

                Comment

                • Peter Otten

                  #9
                  Re: how come .insert() don't work

                  Bennie wrote:
                  [color=blue]
                  > self.html.add_c ommand(label="p ", command=self.te kst_in('p'))[/color]

                  Here you are setting the command parameter to the result of the
                  self.tekst_in() call which is always None. Change that to

                  self.html.add_c ommand(label="p ", command=self.in sert_para)

                  and add a method to your App class that takes only the self parameter:

                  def insert_para(sel f):
                  self.tekst_in(" p")

                  That way insert_para() will be invoked when you click the menu command.
                  Alternately you can use lambda to the same effect:

                  self.html.add_c ommand(label="p ", command=lambda: self.tekst_in(" p"))

                  but I think the approach outlined above is cleaner.

                  Peter





                  Comment

                  • Bennie

                    #10
                    Re: how come .insert() don't work

                    Peter Otten wrote:[color=blue]
                    > Bennie wrote:
                    >
                    >[color=green]
                    >>self.html.add _command(label= "p", command=self.te kst_in('p'))[/color]
                    >
                    >
                    > Here you are setting the command parameter to the result of the
                    > self.tekst_in() call which is always None. Change that to
                    >
                    > self.html.add_c ommand(label="p ", command=self.in sert_para)
                    >
                    > and add a method to your App class that takes only the self parameter:
                    >
                    > def insert_para(sel f):
                    > self.tekst_in(" p")
                    >
                    > That way insert_para() will be invoked when you click the menu command.
                    > Alternately you can use lambda to the same effect:
                    >
                    > self.html.add_c ommand(label="p ", command=lambda: self.tekst_in(" p"))
                    >
                    > but I think the approach outlined above is cleaner.
                    >
                    > Peter
                    >[/color]
                    Thanks all,
                    Whit lambda its is working fine.
                    I want to make a methode that replaces the code:

                    def p(self):
                    self.tekst.inse rt(INSERT, "\t\t<p>\n\n\t\ t</p>\n")
                    def pre(self):
                    self.tekst.inse rt(INSERT, "\t\t<pre>\n\n\ t\t</pre>\n")
                    def br(self):
                    self.tekst.inse rt(INSERT, "<br />")
                    etc.

                    Now I have to type les :-)

                    Bye all! and many thanks ;)
                    Bennie,

                    Comment

                    Working...