Difference between revisions of "Auto-generating-QObject-from-template-in-PySide"

From Qt Wiki
Jump to: navigation, search
 
Line 1: Line 1:
=Auto-generating QObject from template in PySide=
+
[[Category:LanguageBindings::PySide]]
 +
[[Category:Snippets]]
 +
[[Category:Developing_with_Qt::Qt Quick]]
 +
[[Category:Developing_with_Qt::Qt Quick::QML]]
 +
[[Category:Developing_with_Qt::Qt Quick::Tutorial]]
 +
[toc align_right="yes" depth="3"]
  
In the previous [[PySide]] tutorial, we have defined a QObject subclass “Car” with 4 properties which took about 36 lines of code. The code is repetitive, and it follows a scheme – every property has a getter, setter and notification method (in the case of the previous example, we shared the notification signal amongst all properties). For a very generic “entity” QObject, there is an easier way: Auto-generating the QObject from a template that specifies the names of the properties and the type of each property. Attributes, getters, setters and notification methods are automatically generated, and the object can be used as if it was a normal Python object.
+
= Auto-generating QObject from template in PySide =
  
==The Auto-Generator function==
+
In the previous [[PySide]] tutorial, we have defined a QObject subclass "Car" with 4 properties which took about 36 lines of code. The code is repetitive, and it follows a scheme - every property has a getter, setter and notification method (in the case of the previous example, we shared the notification signal amongst all properties). For a very generic "entity" QObject, there is an easier way: Auto-generating the QObject from a template that specifies the names of the properties and the type of each property. Attributes, getters, setters and notification methods are automatically generated, and the object can be used as if it was a normal Python object.
  
This function gets one or more '''class_def''' tuples (length: two) that specify the name and the type of objects (see below for an example). The only optional keyword at the moment is “name”, which specifies the name of the class for debugging purposes.
+
== The Auto-Generator function ==
  
==How to use the Auto-Generator==
+
This function gets one or more '''class_def''' tuples (length: two) that specify the name and the type of objects (see below for an example). The only optional keyword at the moment is "name", which specifies the name of the class for debugging purposes.
  
Taking the example of our previous tutorial, defining a “Car” object has become quite easy now:
+
<code>
 +
from PySide import QtCore
 +
 
 +
def AutoQObject('''class_def,kwargs):
 +
class Object(QtCore.QObject):
 +
def ''init''(self,'''*kwargs):
 +
QtCore.QObject.''init''(self)
 +
for key, val in class_def:
 +
self.''dict''[''''+key] = kwargs.get(key, val())
 +
 
 +
defrepr<span class="self">:
 +
values = ('%s=r' (key, self.</span>dict[''''+key])  for key, value in class_def)
 +
return '<%s (s)>' (kwargs.get('name', 'QObject'), ', '.join(values))
 +
 
 +
for key, value in class_def:
 +
nfy = locals()['''nfy'''+key] = QtCore.Signal()
 +
 
 +
def ''get(key):
 +
def f(self):
 +
return self.dict[''''+key]
 +
return f
 +
 
 +
def ''set(key):
 +
def f(self, value):
 +
self.dict[''''+key] = value
 +
self.''dict''['''nfy'''+key].emit()
 +
return f
 +
 
 +
set = locals()['''set'''+key] = _set(key)
 +
get = locals()['''get'''+key] = ''get(key)
 +
 
 +
locals()[key] = QtCore.Property(value, get, set, notify=nfy)
 +
 
 +
return Object
 +
</code>
 +
 
 +
h2. How to use the Auto-Generator
 +
 
 +
Taking the example of our previous tutorial, defining a "Car" object has become quite easy now:
 +
 
 +
<code>
 +
Car = AutoQObject(
 +
('model', str),
 +
('brand', str),
 +
('year', int),
 +
('inStock', bool),
 +
name='Car'
 +
)
 +
</code>
  
 
The amount of lines has decreased from 36 to 7 (if you ignore the fact that AutoQObject does also take some lines). The definition is more straightforward, and it saves you a lot of typing and errors compared to if you were to do it manually.
 
The amount of lines has decreased from 36 to 7 (if you ignore the fact that AutoQObject does also take some lines). The definition is more straightforward, and it saves you a lot of typing and errors compared to if you were to do it manually.
  
==Example usage of our generated class==
+
h2. Example usage of our generated class
  
 
We could simply drop this code into the previous tutorial example and see that it still works. We just do some basic instantiation and reading of the values to see if it works:
 
We could simply drop this code into the previous tutorial example and see that it still works. We just do some basic instantiation and reading of the values to see if it works:
  
==The expected output==
+
<code>
 +
print Car
  
If everything works as planned, this is what you should get as output when running the example code:
+
c = Car(model='Fiesta', brand='Ford', year=1337)
 +
print c.model, c.brand, c.year, c.inStock
 +
print c
 +
 
 +
c.inStock = True
  
===Categories:===
+
print c.model, c.brand, c.year, c.inStock
 +
print c
 +
</code>
  
* [[:Category:Developing with Qt|Developing_with_Qt]]
+
h2. The expected output
** [[:Category:Developing with Qt::Qt-Quick|Qt Quick]]
 
* [[:Category:Developing with Qt::Qt-Quick::QML|QML]]
 
  
* [[:Category:Developing with Qt::Qt-Quick::Tutorial|Tutorial]]
+
If everything works as planned, this is what you should get as output when running the example code:
  
* [[:Category:LanguageBindings|LanguageBindings]]
+
<code>
** [[:Category:LanguageBindings::PySide|PySide]]
+
<class 'main''_.Object'>
* [[:Category:snippets|snippets]]
+
Fiesta Ford 1337 False
 +
<Car (model='Fiesta', brand='Ford', year=1337, inStock=False)>
 +
Fiesta Ford 1337 True
 +
<Car (model='Fiesta', brand='Ford', year=1337, inStock=True)>

Revision as of 09:54, 25 February 2015

[toc align_right="yes" depth="3"]

Auto-generating QObject from template in PySide

In the previous PySide tutorial, we have defined a QObject subclass "Car" with 4 properties which took about 36 lines of code. The code is repetitive, and it follows a scheme - every property has a getter, setter and notification method (in the case of the previous example, we shared the notification signal amongst all properties). For a very generic "entity" QObject, there is an easier way: Auto-generating the QObject from a template that specifies the names of the properties and the type of each property. Attributes, getters, setters and notification methods are automatically generated, and the object can be used as if it was a normal Python object.

The Auto-Generator function

This function gets one or more class_def tuples (length: two) that specify the name and the type of objects (see below for an example). The only optional keyword at the moment is "name", which specifies the name of the class for debugging purposes.

from PySide import QtCore

def AutoQObject('''class_def,kwargs):
 class Object(QtCore.QObject):
 def ''init''(self,'''*kwargs):
 QtCore.QObject.''init''(self)
 for key, val in class_def:
 self.''dict''[''''+key] = kwargs.get(key, val())

 defrepr<span class="self">:
 values = ('%s=r' (key, self.</span>dict[''''+key])  for key, value in class_def)
 return '<%s (s)>' (kwargs.get('name', 'QObject'), ', '.join(values))

for key, value in class_def:
 nfy = locals()['''nfy'''+key] = QtCore.Signal()

def ''get(key):
 def f(self):
 return self.dict[''''+key]
 return f

def ''set(key):
 def f(self, value):
 self.dict[''''+key] = value
 self.''dict''['''nfy'''+key].emit()
 return f

set = locals()['''set'''+key] = _set(key)
 get = locals()['''get'''+key] = ''get(key)

 locals()[key] = QtCore.Property(value, get, set, notify=nfy)

 return Object

h2. How to use the Auto-Generator

Taking the example of our previous tutorial, defining a "Car" object has become quite easy now:

Car = AutoQObject(
 ('model', str),
 ('brand', str),
 ('year', int),
 ('inStock', bool),
 name='Car'
)

The amount of lines has decreased from 36 to 7 (if you ignore the fact that AutoQObject does also take some lines). The definition is more straightforward, and it saves you a lot of typing and errors compared to if you were to do it manually.

h2. Example usage of our generated class

We could simply drop this code into the previous tutorial example and see that it still works. We just do some basic instantiation and reading of the values to see if it works:

print Car

c = Car(model='Fiesta', brand='Ford', year=1337)
print c.model, c.brand, c.year, c.inStock
print c

c.inStock = True

print c.model, c.brand, c.year, c.inStock
print c

h2. The expected output

If everything works as planned, this is what you should get as output when running the example code:

<class 'main_.Object'> Fiesta Ford 1337 False <Car (model='Fiesta', brand='Ford', year=1337, inStock=False)> Fiesta Ford 1337 True <Car (model='Fiesta', brand='Ford', year=1337, inStock=True)>