Using globals with classes

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

    #1

    Using globals with classes

    Hi

    I am relatively new to Python.

    I am using Qt Designer to create a UI for a measurement application that I
    use.

    Everything seems to be clear but the use of globals (defined in the module
    that is generated using pyuic, that contains the form class).

    I am using qwtplot to display a running plot :

    void Form3::runningp lot(n,plottitle ,xname,x,y1name ,y1,y2name,y2)
    {
    if n==1 :

    plotkey1=self.r unningqwtPlot.i nsertCurve(y1na me,self.running qwtPlot.xBottom ,self.runningqw tPlot.yLeft)

    plotkey2=self.r unningqwtPlot.i nsertCurve(y2na me,self.running qwtPlot.xBottom ,self.runningqw tPlot.yRight)
    self.runningqwt Plot.setTitle(p lottitle)
    self.runningqwt Plot.setXGrid(T rue)
    self.runningqwt Plot.setAxisAut oScale(self.run ningqwtPlot.yLe ft)
    self.runningqwt Plot.setAxisAut oScale(self.run ningqwtPlot.yRi ght)
    self.runningqwt Plot.setAxisAut oScale(self.run ningqwtPlot.xBo ttom)
    self.runningqwt Plot.setAxisTit le(self.running qwtPlot.yLeft,y 1name)
    self.runningqwt Plot.setAxisTit le(self.running qwtPlot.yRight, y2name)
    self.runningqwt Plot.setAxisTit le(self.running qwtPlot.xBottom ,xname)
    self.runningqwt Plot.setCurveDa ta(plotkey1,x,y 1,n)
    self.runningqwt Plot.setCurveDa ta(plotkey2,x,y 2,n)
    self.runningqwt Plot.replot()
    else :
    self.runningqwt Plot.setCurveDa ta(plotkey1,x,y 1,n)
    self.runningqwt Plot.setCurveDa ta(plotkey2,x,y 2,n)
    self.runningqwt Plot.replot()
    }

    where the above routine is called repeatedly to display real time data.
    Now, plotkey1 and plotkey2 need to remain unchanged between successive
    invocations of setCurveData() and replot() above. I have defined these as
    globals (in the Form settings comment field with Python: as usual).
    However, when I run it, I get an error indicating that plotkey1 and
    plotkey2 are unknown outside.

    I also have a global variable named "globaldebu g" that when set to True,
    shows some diagnostic information as different slots are called. That too
    fails with the same error :

    NameError: global name 'globaldebug' is not defined

    Is there a way to make a Python function "remember" the values of certain
    variables ? Or use fortran 95 like use module, only : varname, type of
    within a def ?
  • Diez B. Roggisch

    #2
    Re: Using globals with classes

    [color=blue]
    > Is there a way to make a Python function "remember" the values of certain
    > variables ? Or use fortran 95 like use module, only : varname, type of
    > within a def ?[/color]

    I'm not sure what you are trying to do here - but it seems to me that
    you are not properly designing your application. You really shouldn't
    use the Designers code-insertion features. The reason is simple: you
    the have two tools to write code in instead of one (your editor/IDE).
    And you don't make plotkey* global - use instance variables.

    So I'm going to describe how I dow work with PyQt:

    - I create a Widget in the designer
    - compile it using pyuic
    - _extend_ it
    - write my code in the extended version

    So I end up with something like this (I use modules to separate
    classes):

    ui/plot.ui
    ui/plot.py
    views/plot.py

    where views/plot.py looks like this:

    class Plot(ui.plot.Pl ot):
    def __init__(self, *args):
    ui.plot.Plot.__ init__(self, *args)
    self.plotkey1 = <whatever>

    def update(self):
    # access self.plotkey here



    HTH,

    DIez

    Comment

    • Diez B. Roggisch

      #3
      Re: Using globals with classes

      [color=blue]
      > Is there a way to make a Python function "remember" the values of certain
      > variables ? Or use fortran 95 like use module, only : varname, type of
      > within a def ?[/color]

      I'm not sure what you are trying to do here - but it seems to me that
      you are not properly designing your application. You really shouldn't
      use the Designers code-insertion features. The reason is simple: you
      the have two tools to write code in instead of one (your editor/IDE).
      And you don't make plotkey* global - use instance variables.

      So I'm going to describe how I dow work with PyQt:

      - I create a Widget in the designer
      - compile it using pyuic
      - _extend_ it
      - write my code in the extended version

      So I end up with something like this (I use modules to separate
      classes):

      ui/plot.ui
      ui/plot.py
      views/plot.py

      where views/plot.py looks like this:

      class Plot(ui.plot.Pl ot):
      def __init__(self, *args):
      ui.plot.Plot.__ init__(self, *args)
      self.plotkey1 = <whatever>

      def update(self):
      # access self.plotkey here



      HTH,

      DIez

      Comment

      • Scott David Daniels

        #4
        Re: Using globals with classes

        Madhusudan Singh wrote:[color=blue]
        > .... I am using qwtplot to display a running plot :
        >
        > void Form3::runningp lot(n,plottitle ,xname,x,y1name ,y1,y2name,y2)
        > {[/color]
        ^^ I presume this is just some untranslated stuff ^^[color=blue]
        > if n==1 :
        >
        > plotkey1=self.r unningqwtPlot.i nsertCurve(y1na me,self.running qwtPlot.xBottom ,self.runningqw tPlot.yLeft)
        >
        > plotkey2=self.r unningqwtPlot.i nsertCurve(y2na me,self.running qwtPlot.xBottom ,self.runningqw tPlot.yRight)
        > self.runningqwt Plot.setTitle(p lottitle)
        > self.runningqwt Plot.setXGrid(T rue)
        > self.runningqwt Plot.setAxisAut oScale(self.run ningqwtPlot.yLe ft)
        > self.runningqwt Plot.setAxisAut oScale(self.run ningqwtPlot.yRi ght)
        > self.runningqwt Plot.setAxisAut oScale(self.run ningqwtPlot.xBo ttom)
        > self.runningqwt Plot.setAxisTit le(self.running qwtPlot.yLeft,y 1name)
        > self.runningqwt Plot.setAxisTit le(self.running qwtPlot.yRight, y2name)
        > self.runningqwt Plot.setAxisTit le(self.running qwtPlot.xBottom ,xname)
        > self.runningqwt Plot.setCurveDa ta(plotkey1,x,y 1,n)
        > self.runningqwt Plot.setCurveDa ta(plotkey2,x,y 2,n)
        > self.runningqwt Plot.replot()
        > else :
        > self.runningqwt Plot.setCurveDa ta(plotkey1,x,y 1,n)
        > self.runningqwt Plot.setCurveDa ta(plotkey2,x,y 2,n)
        > self.runningqwt Plot.replot()
        > }[/color]

        The way I'd normally accomplish this is to separate the setup and use
        by defining a class:

        class CurvePlot(objec t):
        def __init__(self, plot, plottitle, xname, y1name, y2name,
        key1=None, key2=None):
        self.plot = plot
        if key1 is None:
        key1 = plot.insertCurv e(y1name, plot.xBottom, plot.yLeft)
        self.key1 = key1
        if key2 is None:
        key2 = plot.insertCurv e(y2name, plot.xBottom, plot.yRight)
        self.key2 = key2
        plot.setTitle(p lottitle)
        plot.setXGrid(T rue)
        plot.setAxisAut oScale(plot.yLe ft)
        plot.setAxisAut oScale(plot.yRi ght)
        plot.setAxisAut oScale(plot.xBo ttom)
        plot.setAxisTit le(plot.yLeft, y1name)
        plot.setAxisTit le(plot.yRight, y2name)
        plot.setAxisTit le(plot.xBottom , xname)

        def curve(self, x, y1, n)
        self.plot.setCu rveData(self.ke y1, x, y1, n)
        self.plot.setCu rveData(self.ke y2, x, y2, n)
        self.plot.replo t()

        And then calling it like:

        cplot = CurvePlot(self. runningqwtPlot, plottitle,
        xname, y1name, y2name)
        cplot.curve(n, x, y1, y2)
        [color=blue]
        > I also have a global variable named "globaldebu g" that when set to True,
        > shows some diagnostic information as different slots are called. That too
        > fails with the same error :
        >
        > NameError: global name 'globaldebug' is not defined[/color]
        What you probably don't understand is that "globals" are per-module, not
        program-wide. If you write a global from inside a function or method,
        you need to declare "global varname" inside the function or method in
        which you do the writing. Simply using (reading) a global in a module
        does not require the "global" declaration.

        --Scott David Daniels
        Scott.Daniels@A cm.Org

        Comment

        • Madhusudan Singh

          #5
          Re: Using globals with classes

          Many thanks for an excellent solution to the problem and clearing up my mind
          about globals.

          In some sense, Python globals seem to be a little like the COMMON statement
          in the old Fortran 77 standard.

          Comment

          • Madhusudan Singh

            #6
            Re: Using globals with classes

            Scott David Daniels wrote:
            [color=blue]
            > Madhusudan Singh wrote:[color=green]
            >> .... I am using qwtplot to display a running plot :
            >>[/color]
            > The way I'd normally accomplish this is to separate the setup and use
            > by defining a class:
            >[/color]

            How would one enable dynamic autoscaling of the axes ?

            I am using setAxisAutoScal e, and when the application ends, I do get
            correctly autoscaled axes, but not while the measurement is in progress.

            Comment

            • Dennis Lee Bieber

              #7
              Re: Using globals with classes

              On Fri, 12 Aug 2005 17:13:21 -0400, Madhusudan Singh
              <spammers-go-here@spam.inval id> declaimed the following in
              comp.lang.pytho n:
              [color=blue]
              >
              > In some sense, Python globals seem to be a little like the COMMON statement
              > in the old Fortran 77 standard.[/color]

              Not really. Fortran COMMON block were named pages of memory. The
              interpretation of that memory was dependent upon the variables declared
              to be /in/ the COMMON block. Prior to the capability to in "include"
              files, it was quite easy to make a mistake and misalign references to
              COMMON.

              program main

              double precision a_real
              integer int_array(5)
              float real_2
              common /some_common/ a_real, real_2, int_array

              -=-=-=-=-=-

              subroutine callme

              double precision my_real
              double precision really_2
              integer my_ints(5)
              common /some_common/ my_real, really_2, my_ints

              -=-=-=-=-=-

              a_real and my_real are okay -- same double precision
              real_2 and really_2 differ in size; so really_2 is accessing half
              its value from what is int_array(1).
              int_array array and my_ints are both five elements long... but the
              mismatch on really_2 means that my_ints (1..4) align with
              int_array(2..5)

              Python's "global" statement, when used inside a function/method
              basically says "modify the variable defined at the module (aka, file)
              level"


              --[color=blue]
              > =============== =============== =============== =============== == <
              > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
              > wulfraed@dm.net | Bestiaria Support Staff <
              > =============== =============== =============== =============== == <
              > Home Page: <http://www.dm.net/~wulfraed/> <
              > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

              Comment

              Working...