Showing posts with label PyQt4. Show all posts
Showing posts with label PyQt4. Show all posts

Thursday, July 8, 2010

QActionGroup and exclusive menu actions

Today I was working on exclusive menu action selection in PyQt4 and got stuck. After some struggling, I managed to find it out. Now I want to share it with you.

What is exclusive menu action? It's a menu item, when you select it, its friends are deselected. When one of its friends is selected, it gets deselected. It's like a radio button group in a menu.

We're going to use QMenu, QAction and QActionGroup for this purpose.
# assume we are in a QMainWindow method, constructing the menu.

menu = QMenu('Alignment', self.menuBar())
menuGroup = QActionGroup(menu)
menuGroup.setExclusive(True)

left = QAction('left', menuGroup)
center = QAction('center', menuGroup)
right = QAction('right', menuGroup)

actions = (left, center, right)
map(menu.addAction, actions)
map(lambda action: action.setCheckable(True), actions)

center.setChecked(True)
self.menuBar().addMenu(menu)


In this way, you are able to select either left or center or right for alignment submenu.

Tuesday, June 29, 2010

QGraphicsItem.itemChange event and ItemPositionChange in Qt 4.6

Recently, I had a bug in Robinviz that I could not figure out where it come from. I was drawing a graph and nodes could be moved. Whenever I moved the node, edges connected to it used to come with it to the new position. But after upgrading to Qt 4.6, I saw that edges were not moving.

After some investigation, I realized that QGraphicsItem.itemChange event did not produce QGraphicsItem.ItemPositionChange but only selected, deselected signals. Googling for it, I hardly found that the problem was with the update. Due to performance reasons, Qt developers decided to stop emitting geometrical signals and wanted us to switch it on by supplying a flag for the QGraphicsItem:


try:
# available only in Qt 4.6
self.setFlag( QGraphicsItem.ItemSendsGeometryChanges)
except:
# no need to do this in Qt 4.5
pass

You can do this flag option in your constructor. I used try/except because I didn't know what might happen in 4.5 as there was no flag called ItemSendsGeometryChanges. In some other websites, following flag was suggested but it did not work for me:

self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, True)


For those who might be interested how I used itemChanged, I'll provide a portion of my code:

def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionChange:
self.updateEdges()

return QVariant(value)