Re: [PyKDE] Lambda function call in connect statement

2001-03-05 Thread Aaron J. Ginn

Phil Thompson wrote:
 
 
 Sorry - I should have noticed this right at the start...
 
 The problem is that you are not keeping a reference to the function
 object that lambda returns - so it is getting garbage collected
 immediately. The signal is them emitted to an object that no longer
 exists, hence the segfault. Change the code to be something like...
 
 self.lam = lambda s=self,x=num:s.changeTopStruct(x)
 self.connect( self.top_struct_button, SIGNAL( "clicked()" ),
   self.lam )
 
 QObject.connect does not keep a reference to the slot object to avoid
 (potential) hidden circurlar references - but it does mean that you have
 to manage them yourself.
 
 The weakreferences module in Python 2.1 looks interesting - it might
 offer a more programmer friendly solution.
 
 Phil

Great!  This works.  I had a feeling the problem was that I was using
lambda incorrectly.

-- 
Aaron J. GinnPhone: 480-814-4463
Motorola SemiCustom SolutionsPager: 877-586-2318
1300 N. Alma School Rd.  Fax  : 480-814-4463
Chandler, AZ 85226 M/D CH260 mailto:[EMAIL PROTECTED]

___
PyKDE mailing list[EMAIL PROTECTED]
http://mats.gmd.de/mailman/listinfo/pykde



Re: [PyKDE] Lambda function call in connect statement

2001-03-03 Thread Phil Thompson

"Aaron J. Ginn" wrote:
 
 Phil Thompson wrote:
 
  However, I don't like segfaults - send me a small but complete script
  that demonstrates the problem and I'll take a look.
 
  Phil
 
 I've attached a script that displays the core dump.  I also included the
 non-lambda version of the connect statement that shows how the pop-up is
 created prior to the construction of the main window.

Sorry - I should have noticed this right at the start...

The problem is that you are not keeping a reference to the function
object that lambda returns - so it is getting garbage collected
immediately. The signal is them emitted to an object that no longer
exists, hence the segfault. Change the code to be something like...

self.lam = lambda s=self,x=num:s.changeTopStruct(x)
self.connect( self.top_struct_button, SIGNAL( "clicked()" ),
  self.lam )

QObject.connect does not keep a reference to the slot object to avoid
(potential) hidden circurlar references - but it does mean that you have
to manage them yourself.

The weakreferences module in Python 2.1 looks interesting - it might
offer a more programmer friendly solution.

Phil

___
PyKDE mailing list[EMAIL PROTECTED]
http://mats.gmd.de/mailman/listinfo/pykde



Re: [PyKDE] Lambda function call in connect statement

2001-03-01 Thread Aaron J. Ginn

Phil Thompson wrote:

 As lambda functions are supposed to be "syntactic sugar for a normal
 function definition" I don't see how using it helps you. Your function
 wouldn't be executed until the button click anyway.

If I write the connect statement without a lambda as follows:

--
 self.connect( self.top_struct_button, SIGNAL( "clicked()" ),
  self.changeTopStruct(ver_obj))
--

where changeTopStruct is

--
def changeTopStruct(self, obj):
"""
Pops up an input dialog to prompt user for new top structure
name.
"""

ok_text_tuple = QInputDialog.getText( 'Change Top Structure',
  'Enter new Top Structure',
  None,None)

if ok_text_tuple[1] is 1 and ok_text_tuple[0] is not None:
obj.set_topstruct( ok_text_tuple[0] )
print obj.get_topstruct()
self.top_struct_value.setText( obj.get_topstruct() )
else:
return
--

The QInputDialog widget in the called function is created before my top
QMainWindow that calls the function.  As I recall from my work with
Tkinter, this is because the call from the connect statement is executed
immediately due to the parentheses in the self.changeTopStruct(ver_obj)
argument.  I thought the only way to get around this is to use a lambda
function such as

self.connect( self.top_struct_button, SIGNAL( "clicked()" ),
  lambda s=self,o=ver_obj:s.changeTopStruct(o))

This suppresses the creation of the QInputDialog box until the button is
pressed.  Is there a better way to do this instead of using a lambda?

 However, I don't like segfaults - send me a small but complete script
 that demonstrates the problem and I'll take a look.
 
 Phil

Will do, but it will take me a little time to put something together.

-- 
Aaron J. GinnPhone: 480-814-4463
Motorola SemiCustom SolutionsPager: 877-586-2318
1300 N. Alma School Rd.  Fax  : 480-814-4463
Chandler, AZ 85226 M/D CH260 mailto:[EMAIL PROTECTED]

___
PyKDE mailing list[EMAIL PROTECTED]
http://mats.gmd.de/mailman/listinfo/pykde



Re: [PyKDE] Lambda function call in connect statement

2001-03-01 Thread Aaron J. Ginn

Phil Thompson wrote:

 However, I don't like segfaults - send me a small but complete script
 that demonstrates the problem and I'll take a look.
 
 Phil

I've attached a script that displays the core dump.  I also included the
non-lambda version of the connect statement that shows how the pop-up is
created prior to the construction of the main window.

Aaron

-- 
Aaron J. GinnPhone: 480-814-4463
Motorola SemiCustom SolutionsPager: 877-586-2318
1300 N. Alma School Rd.  Fax  : 480-814-4463
Chandler, AZ 85226 M/D CH260 mailto:[EMAIL PROTECTED]

#!/usr/bin/env python
from qt import *
import os
import sys

class Lambda(QMainWindow):

def __init__(self):

num = 1

QMainWindow.__init__(self)

# Build the menubar.
mb = self.menuBar()

file_menu = QPopupMenu(self)
mb.insertItem('File',file_menu)

help_menu = QPopupMenu(self)
mb.insertItem('Help',help_menu)

# Build the middle VBox where widgets will go.
self.vb = QVBox( self )
self.setCentralWidget( self.vb )
self.vb.setFrameStyle(QFrame.StyledPanel|QFrame.Raised)
self.vb.setMargin(1)
self.vb.setLineWidth(2)

self.top_struct_hb = QHBox( self.vb )
self.top_struct_value = QLabel( 'Test', self.top_struct_hb)
self.top_struct_button = QPushButton('Click me',
 self.top_struct_hb)

# ---
# Uncomment these lines to see the effect without the lambda
# statement. The QInputDialog command will be created before
# the main window is created.
# ---

##self.connect( self.top_struct_button, SIGNAL( "clicked()" ),
##  self.changeTopStruct(num))
self.connect( self.top_struct_button, SIGNAL( "clicked()" ),
  lambda s=self,x=num:s.changeTopStruct(x))

  
# Build the status bar.
sb = self.statusBar()

return


def changeTopStruct(self, a_num):
"""
Pops up an input dialog to prompt user for new top structure name.
"""

text_tuple = QInputDialog.getText( 'Test', 'Test', None, None )

if text_tuple[1] is 1 and text_tuple[0] is not None:
print 'Ok'
else:
print 'Cancel'
return

# main()
a = QApplication( sys.argv )

a_lambda = Lambda()
a.setMainWidget( a_lambda )
a_lambda.show()

a.exec_loop()