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