class QtTrajectoryViewer(QMainWindow): """Bases: `PyQt4.QtGui.QMainWindow` Interface for viewing trajectory. It provides interface elements to play/pause and set the speed of the animation. **Example** To set up a QtTrajectoryViewer you have to add renderers to the scene, set the number of frames present in the animation by calling ;py:meth:`~chemlab.graphics.QtTrajectoryViewer.set_ticks` and define an update function. Below is an example taken from the function :py:func:`chemlab.graphics.display_trajectory`:: from chemlab.graphics.qt import QtTrajectoryViewer # sys = some System # coords_list = some list of atomic coordinates v = QtTrajectoryViewer() sr = v.add_renderer(AtomRenderer, sys.r_array, sys.type_array, backend='impostors') br = v.add_renderer(BoxRenderer, sys.box_vectors) v.set_ticks(len(coords_list)) @v.update_function def on_update(index): sr.update_positions(coords_list[index]) br.update(sys.box_vectors) v.set_text(format_time(times[index])) v.widget.repaint() v.run() .. warning:: Use with caution, the API for this element is not fully stabilized and may be subject to change. """ def __init__(self): super(QtTrajectoryViewer, self).__init__() self.controls = QDockWidget() # Eliminate the dock titlebar title_widget = QtGui.QWidget(self) self.controls.setTitleBarWidget(title_widget) traj_controls = TrajectoryControls(self) self.controls.setWidget(traj_controls) # Molecular viewer self.widget = QChemlabWidget(self) self.setCentralWidget(self.widget) self.addDockWidget(Qt.DockWidgetArea(Qt.BottomDockWidgetArea), self.controls) self.show() # Replace in this way traj_controls.frame_changed.connect(self.on_frame_changed) self.traj_controls = traj_controls def set_ticks(self, number): self.traj_controls.set_ticks(number) def set_text(self, text): '''Update the time indicator in the interface. ''' self.traj_controls.timelabel.setText(self.traj_controls._label_tmp.format(text)) def on_frame_changed(self, index): self._update_function(index) def on_pause(self): self._timer.stop() def on_slider_change(self, value): self.current_index = value self._update_function(self.current_index) def on_slider_down(self): self._timer.stop() self.play_stop.set_pause() def on_speed_changed(self, index): self.speed = self.speeds[index] if self._timer.isActive(): self._timer.stop() self._timer.start(self.speed) def add_renderer(self, klass, *args, **kwargs): '''The behaviour of this function is the same as :py:meth:`chemlab.graphics.QtViewer.add_renderer`. ''' renderer = klass(self.widget, *args, **kwargs) self.widget.renderers.append(renderer) return renderer def add_ui(self, klass, *args, **kwargs): '''Add an UI element for the current scene. The approach is the same as renderers. .. warning:: The UI api is not yet finalized ''' ui = klass(self.widget, *args, **kwargs) self.widget.uis.append(ui) return ui def add_post_processing(self, klass, *args, **kwargs): pp = klass(self.widget, *args, **kwargs) self.widget.post_processing.append(pp) return pp def run(self): app.exec_() def update_function(self, func, frames=None): '''Set the function to be called when it's time to display a frame. *func* should be a function that takes one integer argument that represents the frame that has to be played:: def func(index): # Update the renderers to match the # current animation index ''' # Back-compatibility if frames is not None: self.traj_controls.set_ticks(frames) self._update_function = func def _toggle_settings(self): self._settings_pan.setVisible(not self._settings_pan.isVisible())
class QtTrajectoryViewer(QMainWindow): """Bases: `PyQt4.QtGui.QMainWindow` Interface for viewing trajectory. It provides interface elements to play/pause and set the speed of the animation. **Example** To set up a QtTrajectoryViewer you have to add renderers to the scene, set the number of frames present in the animation by calling ;py:meth:`~chemlab.graphics.QtTrajectoryViewer.set_ticks` and define an update function. Below is an example taken from the function :py:func:`chemlab.graphics.display_trajectory`:: from chemlab.graphics.qt import QtTrajectoryViewer # sys = some System # coords_list = some list of atomic coordinates v = QtTrajectoryViewer() sr = v.add_renderer(AtomRenderer, sys.r_array, sys.type_array, backend='impostors') br = v.add_renderer(BoxRenderer, sys.box_vectors) v.set_ticks(len(coords_list)) @v.update_function def on_update(index): sr.update_positions(coords_list[index]) br.update(sys.box_vectors) v.set_text(format_time(times[index])) v.widget.repaint() v.run() .. warning:: Use with caution, the API for this element is not fully stabilized and may be subject to change. """ def __init__(self): super(QtTrajectoryViewer, self).__init__() self.controls = QDockWidget() # Eliminate the dock titlebar title_widget = QtGui.QWidget(self) self.controls.setTitleBarWidget(title_widget) traj_controls = TrajectoryControls(self) self.controls.setWidget(traj_controls) # Molecular viewer self.widget = QChemlabWidget(self) self.setCentralWidget(self.widget) self.addDockWidget(Qt.DockWidgetArea(Qt.BottomDockWidgetArea), self.controls) self.show() # Replace in this way traj_controls.frame_changed.connect(self.on_frame_changed) self.traj_controls = traj_controls def set_ticks(self, number): self.traj_controls.set_ticks(number) def set_text(self, text): '''Update the time indicator in the interface. ''' self.traj_controls.timelabel.setText( self.traj_controls._label_tmp.format(text)) def on_frame_changed(self, index): self._update_function(index) def on_pause(self): self._timer.stop() def on_slider_change(self, value): self.current_index = value self._update_function(self.current_index) def on_slider_down(self): self._timer.stop() self.play_stop.set_pause() def on_speed_changed(self, index): self.speed = self.speeds[index] if self._timer.isActive(): self._timer.stop() self._timer.start(self.speed) def add_renderer(self, klass, *args, **kwargs): '''The behaviour of this function is the same as :py:meth:`chemlab.graphics.QtViewer.add_renderer`. ''' renderer = klass(self.widget, *args, **kwargs) self.widget.renderers.append(renderer) return renderer def add_ui(self, klass, *args, **kwargs): '''Add an UI element for the current scene. The approach is the same as renderers. .. warning:: The UI api is not yet finalized ''' ui = klass(self.widget, *args, **kwargs) self.widget.uis.append(ui) return ui def add_post_processing(self, klass, *args, **kwargs): pp = klass(self.widget, *args, **kwargs) self.widget.post_processing.append(pp) return pp def run(self): app.exec_() def update_function(self, func, frames=None): '''Set the function to be called when it's time to display a frame. *func* should be a function that takes one integer argument that represents the frame that has to be played:: def func(index): # Update the renderers to match the # current animation index ''' # Back-compatibility if frames is not None: self.traj_controls.set_ticks(frames) self._update_function = func def _toggle_settings(self): self._settings_pan.setVisible(not self._settings_pan.isVisible())
class ViewerWnd( QMainWindow ): def __init__( self, app, dictOpts ): QMainWindow.__init__( self ) self.setWindowTitle( "PostGIS Layer Viewer - v.1.6.1" ) self.setTabPosition( Qt.BottomDockWidgetArea, QTabWidget.North ) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor( Qt.white ) self.canvas.useImageToRender( True ) self.canvas.enableAntiAliasing( True ) self.setCentralWidget( self.canvas ) actionZoomIn = QAction( QIcon( imgs_dir + "mActionZoomIn.png" ), QString( "Zoom in" ), self ) actionZoomOut = QAction( QIcon( imgs_dir + "mActionZoomOut.png" ), QString( "Zoom out" ), self ) actionPan = QAction( QIcon( imgs_dir + "mActionPan.png" ), QString( "Pan" ), self ) actionZoomFullExtent = QAction( QIcon( imgs_dir + "mActionZoomFullExtent.png" ), QString( "Zoom full" ), self ) actionZoomIn.setCheckable( True ) actionZoomOut.setCheckable( True ) actionPan.setCheckable( True ) self.connect(actionZoomIn, SIGNAL( "triggered()" ), self.zoomIn ) self.connect(actionZoomOut, SIGNAL( "triggered()" ), self.zoomOut ) self.connect(actionPan, SIGNAL( "triggered()" ), self.pan ) self.connect(actionZoomFullExtent, SIGNAL( "triggered()" ), self.zoomFullExtent ) self.actionGroup = QActionGroup( self ) self.actionGroup.addAction( actionPan ) self.actionGroup.addAction( actionZoomIn ) self.actionGroup.addAction( actionZoomOut ) # Create the toolbar self.toolbar = self.addToolBar( "Map tools" ) self.toolbar.addAction( actionPan ) self.toolbar.addAction( actionZoomIn ) self.toolbar.addAction( actionZoomOut ) self.toolbar.addAction( actionZoomFullExtent ) # Create the map tools self.toolPan = QgsMapToolPan( self.canvas ) self.toolPan.setAction( actionPan ) self.toolZoomIn = QgsMapToolZoom( self.canvas, False ) # false = in self.toolZoomIn.setAction( actionZoomIn ) self.toolZoomOut = QgsMapToolZoom( self.canvas, True ) # true = out self.toolZoomOut.setAction( actionZoomOut ) # Create the statusbar self.statusbar = QStatusBar( self ) self.statusbar.setObjectName( "statusbar" ) self.setStatusBar( self.statusbar ) self.lblXY = QLabel() self.lblXY.setFrameStyle( QFrame.Box ) self.lblXY.setMinimumWidth( 170 ) self.lblXY.setAlignment( Qt.AlignCenter ) self.statusbar.setSizeGripEnabled( False ) self.statusbar.addPermanentWidget( self.lblXY, 0 ) self.lblScale = QLabel() self.lblScale.setFrameStyle( QFrame.StyledPanel ) self.lblScale.setMinimumWidth( 140 ) self.statusbar.addPermanentWidget( self.lblScale, 0 ) self.createLegendWidget() # Create the legend widget self.connect( app, SIGNAL( "loadPgLayer" ), self.loadLayer ) self.connect( self.canvas, SIGNAL( "scaleChanged(double)" ), self.changeScale ) self.connect( self.canvas, SIGNAL( "xyCoordinates(const QgsPoint&)" ), self.updateXY ) self.pan() # Default self.plugins = Plugins( self, self.canvas, dictOpts['-h'], dictOpts['-p'], dictOpts['-d'], dictOpts['-U'], dictOpts['-W'] ) self.createAboutWidget() self.layerSRID = '-1' self.loadLayer( dictOpts ) def zoomIn( self ): self.canvas.setMapTool( self.toolZoomIn ) def zoomOut( self ): self.canvas.setMapTool( self.toolZoomOut ) def pan( self ): self.canvas.setMapTool( self.toolPan ) def zoomFullExtent( self ): self.canvas.zoomToFullExtent() def about( self ): pass def createLegendWidget( self ): """ Create the map legend widget and associate it to the canvas """ self.legend = Legend( self ) self.legend.setCanvas( self.canvas ) self.legend.setObjectName( "theMapLegend" ) self.LegendDock = QDockWidget( "Layers", self ) self.LegendDock.setObjectName( "legend" ) self.LegendDock.setTitleBarWidget( QWidget() ) self.LegendDock.setWidget( self.legend ) self.LegendDock.setContentsMargins ( 0, 0, 0, 0 ) self.addDockWidget( Qt.BottomDockWidgetArea, self.LegendDock ) def createAboutWidget( self ): self.AboutDock = QDockWidget( "About", self ) self.AboutDock.setObjectName( "about" ) self.AboutDock.setTitleBarWidget( QWidget() ) self.AboutDock.setContentsMargins( 0, 0, 0, 0 ) self.tabifyDockWidget( self.LegendDock, self.AboutDock ) self.LegendDock.raise_() # legendDock at the top from PyQt4.QtCore import QRect from PyQt4.QtGui import QSizePolicy, QGridLayout, QFont font = QFont() font.setFamily("Sans Serif") font.setPointSize(8.7) self.AboutWidget = QWidget() self.AboutWidget.setFont( font ) self.AboutWidget.setObjectName("AboutWidget") self.AboutDock.setWidget( self.AboutWidget ) self.labelAbout = QLabel( self.AboutWidget ) self.labelAbout.setAlignment(Qt.AlignCenter) self.labelAbout.setWordWrap(True) self.gridLayout = QGridLayout(self.AboutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.gridLayout.addWidget(self.labelAbout, 0, 1, 1, 1) self.labelAbout.setTextInteractionFlags(Qt.LinksAccessibleByMouse|Qt.LinksAccessibleByKeyboard|Qt.TextSelectableByKeyboard|Qt.TextSelectableByMouse) self.labelAbout.setOpenExternalLinks( True ) self.labelAbout.setText("<html><head/><body><a href=\"http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/293-consola-sql-para-plugin-pgadmin-postgis-viewer\">PostGIS Layer Viewer</a> v.1.6.1 (2015.02.24)<br \><br \>" \ "Copyright (c) 2010 Ivan Mincik,<br \>[email protected]<br \>" \ u"Copyright (c) 2011-2015 Germán Carrillo,<br \>[email protected]<br \><br \>" \ "<i>Licensed under the terms of GNU GPL v.2.0</i><br \><br \>" \ "Based on PyQGIS. Plugin Fast SQL Layer by Pablo T. Carreira.</body></html>" ) def loadLayer( self, dictOpts ): print 'I: Loading the layer...' self.layerSRID = dictOpts[ 'srid' ] # To access the SRID when querying layer properties if not self.isActiveWindow(): self.activateWindow() self.raise_() if dictOpts['type'] == 'vector': # QGIS connection uri = QgsDataSourceURI() uri.setConnection( dictOpts['-h'], dictOpts['-p'], dictOpts['-d'], dictOpts['-U'], dictOpts['-W'] ) uri.setDataSource( dictOpts['-s'], dictOpts['-t'], dictOpts['-g'] ) layer = QgsVectorLayer( uri.uri(), dictOpts['-s'] + '.' + dictOpts['-t'], "postgres" ) elif dictOpts['type'] == 'raster': connString = "PG: dbname=%s host=%s user=%s password=%s port=%s mode=2 " \ "schema=%s column=%s table=%s" % ( dictOpts['-d'], dictOpts['-h'], dictOpts['-U'], dictOpts['-W'], dictOpts['-p'], dictOpts['-s'], dictOpts['col'], dictOpts['-t'] ) layer = QgsRasterLayer( connString, dictOpts['-s'] + '.' + dictOpts['-t'] ) if layer.isValid(): layer.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum ) self.addLayer( layer, self.layerSRID ) def addLayer( self, layer, srid='-1' ): if layer.isValid(): # Only in case that srid != -1, read the layer SRS properties, otherwise don't since it will return 4326 if srid != '-1': self.layerSRID = layer.crs().description() + ' (' + str( layer.crs().postgisSrid() ) + ')' else: self.layerSRID = 'Unknown SRS (-1)' if self.canvas.layerCount() == 0: self.canvas.setExtent( layer.extent() ) if srid != '-1': print 'I: Map SRS (EPSG): %s' % self.layerSRID self.canvas.setMapUnits( layer.crs().mapUnits() ) else: print 'I: Unknown Reference System' self.canvas.setMapUnits( 0 ) # 0: QGis.Meters return QgsMapLayerRegistry.instance().addMapLayer( layer ) return False def activeLayer( self ): """ Returns the active layer in the layer list widget """ return self.legend.activeLayer() def getLayerProperties( self, l ): """ Create a layer-properties string (l:layer)""" print 'I: Generating layer properties...' if l.type() == 0: # Vector wkbType = ["WKBUnknown","WKBPoint","WKBLineString","WKBPolygon", "WKBMultiPoint","WKBMultiLineString","WKBMultiPolygon", "WKBNoGeometry","WKBPoint25D","WKBLineString25D","WKBPolygon25D", "WKBMultiPoint25D","WKBMultiLineString25D","WKBMultiPolygon25D"] properties = "Source: %s\n" \ "Geometry type: %s\n" \ "Number of features: %s\n" \ "Number of fields: %s\n" \ "SRS (EPSG): %s\n" \ "Extent: %s " \ % ( l.source(), wkbType[l.wkbType()], l.featureCount(), l.dataProvider().fields().count(), self.layerSRID, l.extent().toString() ) elif l.type() == 1: # Raster rType = [ "GrayOrUndefined (single band)", "Palette (single band)", "Multiband", "ColorLayer" ] properties = "Source: %s\n" \ "Raster type: %s\n" \ "Width-Height (pixels): %sx%s\n" \ "Bands: %s\n" \ "SRS (EPSG): %s\n" \ "Extent: %s" \ % ( l.source(), rType[l.rasterType()], l.width(), l.height(), l.bandCount(), self.layerSRID, l.extent().toString() ) self.layerSRID = '-1' # Initialize the srid return properties def changeScale( self, scale ): self.lblScale.setText( "Scale 1:" + formatNumber( scale ) ) def updateXY( self, p ): if self.canvas.mapUnits() == 2: # Degrees self.lblXY.setText( formatToDegrees( p.x() ) + " | " \ + formatToDegrees( p.y() ) ) else: # Unidad lineal self.lblXY.setText( formatNumber( p.x() ) + " | " \ + formatNumber( p.y() ) + "" )
class ViewerWnd(QMainWindow): def __init__(self, app, dictOpts): QMainWindow.__init__(self) self.setWindowTitle("PostGIS Layer Viewer - v.1.6.1") self.setTabPosition(Qt.BottomDockWidgetArea, QTabWidget.North) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) self.canvas.useImageToRender(True) self.canvas.enableAntiAliasing(True) self.setCentralWidget(self.canvas) actionZoomIn = QAction(QIcon(imgs_dir + "mActionZoomIn.png"), QString("Zoom in"), self) actionZoomOut = QAction(QIcon(imgs_dir + "mActionZoomOut.png"), QString("Zoom out"), self) actionPan = QAction(QIcon(imgs_dir + "mActionPan.png"), QString("Pan"), self) actionZoomFullExtent = QAction( QIcon(imgs_dir + "mActionZoomFullExtent.png"), QString("Zoom full"), self) actionZoomIn.setCheckable(True) actionZoomOut.setCheckable(True) actionPan.setCheckable(True) self.connect(actionZoomIn, SIGNAL("triggered()"), self.zoomIn) self.connect(actionZoomOut, SIGNAL("triggered()"), self.zoomOut) self.connect(actionPan, SIGNAL("triggered()"), self.pan) self.connect(actionZoomFullExtent, SIGNAL("triggered()"), self.zoomFullExtent) self.actionGroup = QActionGroup(self) self.actionGroup.addAction(actionPan) self.actionGroup.addAction(actionZoomIn) self.actionGroup.addAction(actionZoomOut) # Create the toolbar self.toolbar = self.addToolBar("Map tools") self.toolbar.addAction(actionPan) self.toolbar.addAction(actionZoomIn) self.toolbar.addAction(actionZoomOut) self.toolbar.addAction(actionZoomFullExtent) # Create the map tools self.toolPan = QgsMapToolPan(self.canvas) self.toolPan.setAction(actionPan) self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in self.toolZoomIn.setAction(actionZoomIn) self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out self.toolZoomOut.setAction(actionZoomOut) # Create the statusbar self.statusbar = QStatusBar(self) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.lblXY = QLabel() self.lblXY.setFrameStyle(QFrame.Box) self.lblXY.setMinimumWidth(170) self.lblXY.setAlignment(Qt.AlignCenter) self.statusbar.setSizeGripEnabled(False) self.statusbar.addPermanentWidget(self.lblXY, 0) self.lblScale = QLabel() self.lblScale.setFrameStyle(QFrame.StyledPanel) self.lblScale.setMinimumWidth(140) self.statusbar.addPermanentWidget(self.lblScale, 0) self.createLegendWidget() # Create the legend widget self.connect(app, SIGNAL("loadPgLayer"), self.loadLayer) self.connect(self.canvas, SIGNAL("scaleChanged(double)"), self.changeScale) self.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.updateXY) self.pan() # Default self.plugins = Plugins(self, self.canvas, dictOpts['-h'], dictOpts['-p'], dictOpts['-d'], dictOpts['-U'], dictOpts['-W']) self.createAboutWidget() self.layerSRID = '-1' self.loadLayer(dictOpts) def zoomIn(self): self.canvas.setMapTool(self.toolZoomIn) def zoomOut(self): self.canvas.setMapTool(self.toolZoomOut) def pan(self): self.canvas.setMapTool(self.toolPan) def zoomFullExtent(self): self.canvas.zoomToFullExtent() def about(self): pass def createLegendWidget(self): """ Create the map legend widget and associate it to the canvas """ self.legend = Legend(self) self.legend.setCanvas(self.canvas) self.legend.setObjectName("theMapLegend") self.LegendDock = QDockWidget("Layers", self) self.LegendDock.setObjectName("legend") self.LegendDock.setTitleBarWidget(QWidget()) self.LegendDock.setWidget(self.legend) self.LegendDock.setContentsMargins(0, 0, 0, 0) self.addDockWidget(Qt.BottomDockWidgetArea, self.LegendDock) def createAboutWidget(self): self.AboutDock = QDockWidget("About", self) self.AboutDock.setObjectName("about") self.AboutDock.setTitleBarWidget(QWidget()) self.AboutDock.setContentsMargins(0, 0, 0, 0) self.tabifyDockWidget(self.LegendDock, self.AboutDock) self.LegendDock.raise_() # legendDock at the top from PyQt4.QtCore import QRect from PyQt4.QtGui import QSizePolicy, QGridLayout, QFont font = QFont() font.setFamily("Sans Serif") font.setPointSize(8.7) self.AboutWidget = QWidget() self.AboutWidget.setFont(font) self.AboutWidget.setObjectName("AboutWidget") self.AboutDock.setWidget(self.AboutWidget) self.labelAbout = QLabel(self.AboutWidget) self.labelAbout.setAlignment(Qt.AlignCenter) self.labelAbout.setWordWrap(True) self.gridLayout = QGridLayout(self.AboutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.gridLayout.addWidget(self.labelAbout, 0, 1, 1, 1) self.labelAbout.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard | Qt.TextSelectableByKeyboard | Qt.TextSelectableByMouse) self.labelAbout.setOpenExternalLinks(True) self.labelAbout.setText("<html><head/><body><a href=\"http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/293-consola-sql-para-plugin-pgadmin-postgis-viewer\">PostGIS Layer Viewer</a> v.1.6.1 (2015.02.24)<br \><br \>" \ "Copyright (c) 2010 Ivan Mincik,<br \>[email protected]<br \>" \ u"Copyright (c) 2011-2015 Germán Carrillo,<br \>[email protected]<br \><br \>" \ "<i>Licensed under the terms of GNU GPL v.2.0</i><br \><br \>" \ "Based on PyQGIS. Plugin Fast SQL Layer by Pablo T. Carreira.</body></html>" ) def loadLayer(self, dictOpts): print 'I: Loading the layer...' self.layerSRID = dictOpts[ 'srid'] # To access the SRID when querying layer properties if not self.isActiveWindow(): self.activateWindow() self.raise_() if dictOpts['type'] == 'vector': # QGIS connection uri = QgsDataSourceURI() uri.setConnection(dictOpts['-h'], dictOpts['-p'], dictOpts['-d'], dictOpts['-U'], dictOpts['-W']) uri.setDataSource(dictOpts['-s'], dictOpts['-t'], dictOpts['-g']) layer = QgsVectorLayer(uri.uri(), dictOpts['-s'] + '.' + dictOpts['-t'], "postgres") elif dictOpts['type'] == 'raster': connString = "PG: dbname=%s host=%s user=%s password=%s port=%s mode=2 " \ "schema=%s column=%s table=%s" % ( dictOpts['-d'], dictOpts['-h'], dictOpts['-U'], dictOpts['-W'], dictOpts['-p'], dictOpts['-s'], dictOpts['col'], dictOpts['-t'] ) layer = QgsRasterLayer(connString, dictOpts['-s'] + '.' + dictOpts['-t']) if layer.isValid(): layer.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum) self.addLayer(layer, self.layerSRID) def addLayer(self, layer, srid='-1'): if layer.isValid(): # Only in case that srid != -1, read the layer SRS properties, otherwise don't since it will return 4326 if srid != '-1': self.layerSRID = layer.crs().description() + ' (' + str( layer.crs().postgisSrid()) + ')' else: self.layerSRID = 'Unknown SRS (-1)' if self.canvas.layerCount() == 0: self.canvas.setExtent(layer.extent()) if srid != '-1': print 'I: Map SRS (EPSG): %s' % self.layerSRID self.canvas.setMapUnits(layer.crs().mapUnits()) else: print 'I: Unknown Reference System' self.canvas.setMapUnits(0) # 0: QGis.Meters return QgsMapLayerRegistry.instance().addMapLayer(layer) return False def activeLayer(self): """ Returns the active layer in the layer list widget """ return self.legend.activeLayer() def getLayerProperties(self, l): """ Create a layer-properties string (l:layer)""" print 'I: Generating layer properties...' if l.type() == 0: # Vector wkbType = [ "WKBUnknown", "WKBPoint", "WKBLineString", "WKBPolygon", "WKBMultiPoint", "WKBMultiLineString", "WKBMultiPolygon", "WKBNoGeometry", "WKBPoint25D", "WKBLineString25D", "WKBPolygon25D", "WKBMultiPoint25D", "WKBMultiLineString25D", "WKBMultiPolygon25D" ] properties = "Source: %s\n" \ "Geometry type: %s\n" \ "Number of features: %s\n" \ "Number of fields: %s\n" \ "SRS (EPSG): %s\n" \ "Extent: %s " \ % ( l.source(), wkbType[l.wkbType()], l.featureCount(), l.dataProvider().fields().count(), self.layerSRID, l.extent().toString() ) elif l.type() == 1: # Raster rType = [ "GrayOrUndefined (single band)", "Palette (single band)", "Multiband", "ColorLayer" ] properties = "Source: %s\n" \ "Raster type: %s\n" \ "Width-Height (pixels): %sx%s\n" \ "Bands: %s\n" \ "SRS (EPSG): %s\n" \ "Extent: %s" \ % ( l.source(), rType[l.rasterType()], l.width(), l.height(), l.bandCount(), self.layerSRID, l.extent().toString() ) self.layerSRID = '-1' # Initialize the srid return properties def changeScale(self, scale): self.lblScale.setText("Scale 1:" + formatNumber(scale)) def updateXY(self, p): if self.canvas.mapUnits() == 2: # Degrees self.lblXY.setText( formatToDegrees( p.x() ) + " | " \ + formatToDegrees( p.y() ) ) else: # Unidad lineal self.lblXY.setText( formatNumber( p.x() ) + " | " \ + formatNumber( p.y() ) + "" )
class OneClockAddon: def __init__(self): self.db = TomatoDB("_TomatoClock.db") self.dlg = OneClock(mw) self.pb = None self._connect_slots() self._set_style_sheet(mw) self.tm = None self.dlg_rest = None self.pb_w = None self.replace_mw_overview() self.replace_mw_deckbrowser() def replace_mw_overview(self): mw.overview = anki_overview(self.dlg, self.db) def replace_mw_reviewer(self): mw.reviewer = anki_reviewer(self.dlg.mode, self.db) def replace_mw_deckbrowser(self): mw.deckBrowser = anki_deckbrowser(self.db) mw.deckBrowser.refresh() @staticmethod def _set_style_sheet(obj): with open(os.path.join(os.path.dirname(__file__), "ui", "designer", "style.css"), "r") as f: obj.setStyleSheet(f.read()) def _connect_slots(self): self.dlg.btn_start.clicked.connect(self.on_btn_start_clicked) def perform_hooks(self, func): func('reviewCleanup', self.on_review_cleanup) func('profileLoaded', self.on_profile_loaded) func('afterStateChange', self.after_anki_state_change) def on_profile_loaded(self): ProfileConfig.donate_alerted = False UserConfig.BREAK_MINUTES # just ensure json file is generated try: if UserConfig.LIVE_CODE_DOWNLOAD: thr = _live_chart_py_downloader() thr.start() except: pass def on_review_cleanup(self): mw.setWindowIcon(QIcon(":/icons/anki.png")) if self.tm and self.tm.isActive(): self.tm.stop() if self.pb: self.pb_w.hide() self.pb.reset() if self.dlg_rest: self.dlg_rest.hide() try: mw.reviewer.restore_layouts() except AttributeError: # just in case "replace_mw_reviewer" is not called pass def on_btn_start_clicked(self): self.replace_mw_reviewer() mw.setWindowIcon(QIcon(":/icon/tomato.png")) assert isinstance(mw, AnkiQt) self.setup_progressbar() self.pb.set_seconds(self.dlg.min * MIN_SECS) if not self.tm: self.tm = Timer(mw) self.tm.timeout.connect(self.on_timer) self.tm.start() # click study button mw.overview._linkHandler("study") self.db.start_session( self.dlg.min, UserConfig.ANSWER_TIMEOUT_SECONDS, self.dlg.mode ) def after_anki_state_change(self, state, oldState): if state == 'overview' and oldState == 'review': self.on_tomato(False) mw.overview.refresh() def on_tomato(self, from_timer=True): self.db.end_session() if self.tm: self.tm.stop() self.pb_w.hide() self.pb.reset() if from_timer: mw.moveToState("overview") if not self.dlg_rest: self.dlg_rest = RestDialog(mw) self._set_style_sheet(self.dlg_rest) self.dlg_rest.accepted.connect(self.on_dlg_rest_accepted) self.dlg_rest.rejected.connect(self.on_dlg_rest_rejected) if UserConfig.PLAY_SOUNDS["break"]: play(BREAK) self.dlg_rest.exec_(self.dlg.min) @staticmethod def on_dlg_rest_accepted(): mw.overview._linkHandler("tomato_clock") def on_dlg_rest_rejected(self): pass def on_timer(self): if self.pb: self.pb_w.show() self.pb.on_timer() self.db.commit() def setup_progressbar(self): dockArea = Qt.TopDockWidgetArea # dockArea = Qt.LeftDockWidgetArea # dockArea = Qt.BottomDockWidgetArea self.pb_w = QDockWidget(mw) self.pb_w.setObjectName("progress_dock") if not self.pb: self.pb = ClockProgress(mw, dockArea) self.pb.tomato.connect(self.on_tomato) else: self.pb.reset() self.pb.set_seconds(self.dlg.min * MIN_SECS) self.pb_w.setWidget(self.pb) w = QWidget(self.pb_w) w.setFixedHeight(self.pb.height()) self.pb_w.setTitleBarWidget(w) self.pb_w.setFeatures(QDockWidget.NoDockWidgetFeatures) # first check existing widgets existing_widgets = [widget for widget in mw.findChildren(QDockWidget) if mw.dockWidgetArea(widget) == dockArea] # then add ourselves mw.addDockWidget(dockArea, self.pb_w) # stack with any existing widgets if len(existing_widgets) > 0: mw.setDockNestingEnabled(True) if dockArea == Qt.TopDockWidgetArea or dockArea == Qt.BottomDockWidgetArea: stack_method = Qt.Vertical if dockArea == Qt.LeftDockWidgetArea or dockArea == Qt.RightDockWidgetArea: stack_method = Qt.Horizontal mw.splitDockWidget(existing_widgets[0], self.pb_w, stack_method) mw.web.setFocus() self._set_style_sheet(self.pb)