00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 from PyQt4.QtCore import *
00019 from PyQt4.QtGui import *
00020 
00021 
00022 
00023 
00024 
00025 
00026 class ArrowsEventFilter(QObject):
00027         
00028         def __init__(self, parent=None):
00029                 QObject.__init__(self, parent)
00030 
00031         
00032         def allWidgets(self, object):
00033                 if not object.isWidgetType():
00034                         return []
00035                 result = []
00036                 if object.isVisible() and object.focusPolicy() != Qt.NoFocus and object.isEnabled():
00037                         if object.inherits('QLineEdit'):
00038                                 if not object.isReadOnly():
00039                                         result += [ object ]
00040                         else:
00041                                 result += [ object ]
00042                 for child in object.children():
00043                         result += self.allWidgets( child )
00044                 return result
00045 
00046         def intersectVertically(self, rect1, rect2):
00047                 if rect1.left() <= rect2.right() and rect1.right() >= rect2.left():
00048                         return True
00049                 return False
00050 
00051         def intersectHorizontally(self, rect1, rect2):
00052                 if rect1.top() <= rect2.bottom() and rect1.bottom() >= rect2.top():
00053                         return True
00054                 return False
00055                 
00056         def eventFilter(self, obj, event):
00057                 if event.type() in (QEvent.KeyPress, QEvent.KeyRelease) and event.modifiers() & Qt.AltModifier and \
00058                         event.key() in (Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right, Qt.Key_Plus, Qt.Key_Minus): 
00059 
00060                         if event.type() == QEvent.KeyRelease:
00061                                 return True
00062 
00063                         mainWidget = QApplication.focusWidget()
00064                         
00065                         while not ( mainWidget.inherits( 'QDialog' ) or mainWidget.inherits( 'QMainWindow' ) ):
00066                                 mainWidget = mainWidget.parent()
00067                                 if not mainWidget:
00068                                         break
00069 
00070                         if not mainWidget:
00071                                 return True
00072 
00073                         currentWidget = QApplication.focusWidget()
00074                         currentRect = currentWidget.rect()
00075                         currentRect.moveTo( currentWidget.mapToGlobal( currentWidget.pos() ) )
00076 
00077                         nextWidget = None
00078                         nextArea = -1
00079                         nextRect = None
00080                         widgets = self.allWidgets(mainWidget)
00081                         if currentWidget in widgets:
00082                                 widgets.remove( currentWidget )
00083                         for widget in widgets:
00084                                 widgetRect = widget.rect()
00085                                 widgetRect.moveTo( widget.mapToGlobal( widget.pos() ) )
00086                                 widgetArea = widgetRect.width() * widgetRect.height()
00087 
00088                                 if event.key() == Qt.Key_Minus:
00089                                         if widgetRect.contains( currentRect ):
00090                                                 if nextArea < 0 or widgetArea < nextArea:
00091                                                         nextWidget = widget
00092                                                         nextArea = widgetArea
00093                                                         nextRect = widgetRect
00094                                 elif event.key() == Qt.Key_Plus:
00095                                         if currentRect.contains( widgetRect ):
00096                                                 if nextArea < 0 or widgetArea > nextArea:
00097                                                         nextWidget = widget
00098                                                         nextArea = widgetArea
00099                                                         nextRect = widgetRect
00100                                 elif event.key() == Qt.Key_Up:
00101                                         
00102                                         
00103                                         
00104                                         if self.intersectVertically( widgetRect, currentRect ) and \
00105                                                 widgetRect.top() < currentRect.bottom() and \
00106                                                 not widgetRect.intersects( currentRect ):
00107                                                 
00108                                                 if (not nextRect) or widgetRect.top() > nextRect.top():
00109                                                         nextWidget = widget
00110                                                         nextArea = widgetArea
00111                                                         nextRect = widgetRect
00112                                 elif event.key() == Qt.Key_Down:        
00113                                         
00114                                         
00115                                         
00116                                         if self.intersectVertically( widgetRect, currentRect ) and \
00117                                                 widgetRect.bottom() > currentRect.top() and \
00118                                                 not widgetRect.intersects( currentRect ):
00119                                                 
00120                                                 if (not nextRect) or widgetRect.bottom() < nextRect.bottom():
00121                                                         nextWidget = widget
00122                                                         nextArea = widgetArea
00123                                                         nextRect = widgetRect
00124                                 elif event.key() == Qt.Key_Left:
00125                                         if self.intersectHorizontally( widgetRect, currentRect ) and \
00126                                                 widgetRect.right() < currentRect.left():
00127                                                 
00128                                                 if (not nextRect) or widgetRect.right() > nextRect.right():
00129                                                         nextWidget = widget
00130                                                         nextArea = widgetArea
00131                                                         nextRect = widgetRect
00132                                 elif event.key() == Qt.Key_Right:
00133                                         if self.intersectHorizontally( widgetRect, currentRect ) and \
00134                                                 widgetRect.left() > currentRect.right():
00135                                                 
00136                                                 if (not nextRect) or widgetRect.left() < nextRect.left():
00137                                                         nextWidget = widget
00138                                                         nextArea = widgetArea
00139                                                         nextRect = widgetRect
00140 
00141                         if nextWidget:
00142                                 nextWidget.setFocus()
00143                                 return True
00144                 return QObject.eventFilter( self, obj, event )  
00145