Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

app refactored as stand-alone widget #4

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions doc/ongoing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
=====================================
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this file?

Is it the seed for some documentation or is it a collection of personal development notes?

Notes on integration with ctarchiving
=====================================

To launch tpgarchiving:

python taurus_tangoarchiving/widget/tpgarchiving.py

Trend Widget API on ctarchiving
-------------------------------

.. code::

plot = TaurusPlot()
plot.setBackgroundBrush(Qt.QColor('white'))
axis = DateAxisItem(orientation='bottom')
plot_items = plot.getPlotItem()

axis.attachToPlotItem(plot_items)
# TODO (cleanup menu actions)
if plot_items.legend is not None:
plot_items.legend.hide()

pb = Qt.QProgressBar()
pb.setGeometry(0, 0, 300, 25)

def updateProgressBar(stop=True):
if stop is True:
final = 1
else:
final = 0
pb.setRange(0, final)

updateProgressBar()



###########################################################################
# Update t0 and t1 based on sigXRangeChanged
###########################################################################
def onUpdateXViewRange():
x, _ = plot.viewRange()
t0, t1 = x
t0s = str2localtime(t0)
t1s = str2localtime(t1)
msi.time_selector.ui.comboBox_begin.setItemText(5, t0s)
msi.time_selector.ui.comboBox_end.setItemText(7, t1s)
msi.time_selector.ui.comboBox_begin.setItemText(5, t0s)
msi.time_selector.ui.comboBox_end.setItemText(7, t1s)
msi.time_selector.ui.comboBox_begin.setCurrentIndex(5)
msi.time_selector.ui.comboBox_end.setCurrentIndex(7)

vb = plot.getPlotItem().getViewBox()
vb.sigXRangeChanged.connect(onUpdateXViewRange)



###########################################################################
# Legend
###########################################################################
gv = Qt.QGraphicsView(Qt.QGraphicsScene())
gv.setBackgroundBrush(Qt.QBrush(Qt.QColor('white')))
l = pg.LegendItem(None, offset=(0, 0))
gv.scene().addItem(l)

def updateExternalLegend():
for dataitem in plot_items.listDataItems():
l.removeItem(dataitem.name())

for dataitem in plot_items.listDataItems():
if dataitem.name():
l.addItem(dataitem, dataitem.name())

###########################################################################
# Connect CurvesAppearanceChooser to external legend
###########################################################################
from taurus_pyqtgraph.curveproperties import (CurvesAppearanceChooser,
CurveAppearanceProperties)

def onApply(self):
names = self.getSelectedCurveNames()
prop = self.getShownProperties()
# Update self.curvePropDict for selected properties
for n in names:
self.curvePropDict[n] = CurveAppearanceProperties.merge(
[self.curvePropDict[n], prop],
conflict=CurveAppearanceProperties.inConflict_update_a)
# emit a (PyQt) signal telling what properties (first argument) need to
# be applied to which curves (second argument)
# self.curveAppearanceChanged.emit(prop, names)
# return both values

self.curvePropAdapter.setCurveProperties(self.curvePropDict, names)
# Update legend
updateExternalLegend()

return prop, names

# Override CurvesAppearanceChooser.onApply
CurvesAppearanceChooser.onApply = onApply

###########################################################################
# Helper
###########################################################################
def updateAll(legend=True):
# Update legend
if legend is True:
updateExternalLegend()
# run plot auto range
time.sleep(0.2) # Wait till models are loading
plot_items.getViewBox().menu.autoRange()
# Stop progress bar
updateProgressBar()

###########################################################################
# onAddXYModel
###########################################################################

def onAddXYModel(models=None):
# Update progress bar
# updateProgressBar(False)
print('onAddXYModel(%s)'%models)
if not isSequenceType(models):
print('Overriding models ...')
models = msi.getSelectedModels()

c = msi.cursor()
msi.setCursor(Qt.Qt.WaitCursor)
current = plot._model_chooser_tool.getModelNames()
print('current: %s' % str(current))
models = [m for m in models if m not in current]
print('new models: %s' % str(models))
plot.addModels(models)
updateAll()
msi.setCursor(c)

# Connect button
msi.modelsAdded.connect(onAddXYModel)
###########################################################################
# Create tgarch tool bar
###########################################################################
def _onRefresh():
t0, t1 = msi.time_selector.getTimes()
# Validate models
v = TangoArchivingAttributeNameValidator()
query = "{0};t0={1};t1={2}"
for curve in plot.getPlotItem().listDataItems():

if isinstance(curve, TaurusPlotDataItem):
ymodel = curve.getModel()
# tgarch attr
if v.getUriGroups(ymodel).get('scheme') != 'tgarch':
continue
fullname, _, _ = v.getNames(ymodel)
bmodel, current_query = fullname.split('?')
db = current_query.split(';')[0]
q = query.format(db, t0, t1)
model = "{0}?{1}".format(bmodel, q)
xmodel = "{};ts".format(model)
curve.setModel(None)
curve.setXModel(None)
curve.setModel(model)
curve.setXModel(xmodel)
updateAll(legend=False)

def onRefresh():
# Update progress bar
updateProgressBar(False)
t1 = threading.Thread(target=_onRefresh)
t1.start()

PyQtGraph API on tpgarchiving
-----------------------------

.. code::

from taurus.qt.qtgui.plot import TaurusTrend
from PyTangoArchiving.widget.trend import ArchivingTrend,ArchivingTrendWidget
self.trend = ArchivingTrendWidget() #TaurusArchivingTrend()
self.trend.setUseArchiving(True)
self.trend.showLegend(True)
7 changes: 3 additions & 4 deletions taurus_tangoarchiving/tangoarchivingattribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,10 @@ def read(self, cache=True):

def _read(self):
reader = self.parent.getReader()

data = reader.get_attribute_values(self._tg_attr_name,
self._start_date,
self._end_date,
decimate=True)
self._start_date,
self._end_date,
decimate=True)
t = TaurusTimeVal().now()
self.type = self.getType()
if len(data) > 0:
Expand Down
19 changes: 9 additions & 10 deletions taurus_tangoarchiving/tangoarchivingauthority.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
import taurus
import socket
import PyTango
from PyTangoArchiving import Schemas
from taurus.core.taurusauthority import TaurusAuthority
from taurus.core.taurusexception import TaurusException
from tangoarchivingvalidator import TangoArchivingAuthorityNameValidator


class TangoArchivingAuthority(TaurusAuthority):
'''
TangoArchiving authority class for Archiving
Expand Down Expand Up @@ -65,18 +65,17 @@ def __init__(self, name=None, parent=None):
except PyTango.DevFailed:
raise TaurusException('Can not connect to the tango database')

def getArchivingProperties(self):
def getArchivingProperties(self, schema = None):
# The archiving database configuration is defined in the tango database
# as free property.
props = self._tangodb.get_property('PyTangoArchiving', ['DbConfig'])
return props
# as free property, and parsed by the PyTangoArchiving.Schemas api.
if schema is None:
schema = Schemas.keys()[0]
return Schemas.getSchema(schema)

def getSchemas(self):
""" Returns a list of configured archiving schemas"""
# The archiving database configuration is defined in the tango database
# as free property.
props = self._tangodb.get_property('PyTangoArchiving', ['Schemas'])
schemas = props.get('Schemas', [])
if len(schemas) != 0:
schemas.append('*')
# as free property, and parsed by the PyTangoArchiving.Schemas api.
schemas = list(Schemas.keys())
schemas.insert(0,'*')
return schemas
41 changes: 37 additions & 4 deletions taurus_tangoarchiving/widget/tangoarchivingmodelchooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
import taurus
from taurus.core.tango.tangodatabase import TangoAuthority
from taurus.external.qt import Qt
from taurus.qt.qtgui.panel import TaurusModelSelectorItem
from taurus.qt.qtgui.panel import TaurusModelSelectorItem, TaurusForm
from taurus.qt.qtgui.util.ui import UILoadable
from taurus_tangoarchiving.widget.tangoarchivingtools import TangoArchivingTimeSelector
from taurus_tangoarchiving.widget.tangoarchivingtools import (
TangoArchivingTimeSelector, clmatch, clsearch)


class ListModel(Qt.QStandardItemModel):
Expand Down Expand Up @@ -79,11 +80,43 @@ def __init__(self, parent=None):
self.onAddSelectedXY)
self.ui.verticalLayout_4.addWidget(self._toolbar)
self.ui.verticalLayout_4.setAlignment(Qt.Qt.AlignTop)

# TODO support drag and drop from listView
# self.ui.listView.installEventFilter(self)
self.ui.lineEdit.textChanged.connect(self.filter)
self.time_selector = TangoArchivingTimeSelector(self)
self.ui.horizontalLayout_4.addWidget(self.time_selector)

import types
def override_mousePressEvent(widget, button, callback):
old_hook = widget.mousePressEvent
def mousePressEvent(obj, event):
if event.button() == button:
callback(obj, event)
old_hook(event)
widget.mousePressEvent = types.MethodType(mousePressEvent, widget)

override_mousePressEvent(self.ui.listView,
Qt.Qt.RightButton, self.onContextMenu)
Comment on lines +91 to +100
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part looks like quite a hack... I would try to avoid intercepting mouse press events (and events in general) and use higher level Qt APIs instead.
...and if working with events is absolutely mandatory, I would consider using an event filter


def onShowCurrentValues(self):
models = self.getSelectedModels()
print(list(map(str,models)))
form = TaurusForm()
form.addModels(models)
form.show()

def onContextMenu(self, widget, event):
if not hasattr(self,'_contextMenu'):
self._contextMenu = Qt.QMenu()
self._contextMenu.addAction(Qt.QIcon(), #.fromTheme("list-add"),
"Add XY selected", self.onAddSelectedXY)
self._contextMenu.addAction(Qt.QIcon(),
"Show Current Values", self.onShowCurrentValues)

if len(self.getSelectedModels()):
point = event.pos()
self._contextMenu.exec_(widget.mapToGlobal(point))

def onAddSelected(self):
self.modelsAdded.emit(self.getSelectedModels())
Expand Down Expand Up @@ -116,10 +149,10 @@ def onSelectSchemeComboBox(self):
self.listmodel.addItems(attrs)

def filter(self):
filter_text = ".*" + str(self.ui.lineEdit.text()).lower() + ".*"
filter_text = str(self.ui.lineEdit.text()).lower()
for row, attr in enumerate(self.listmodel.models):
try:
match = re.match(filter_text, attr)
match = clsearch(filter_text, attr)
except Exception as e:
print(e)
return
Expand Down
2 changes: 1 addition & 1 deletion taurus_tangoarchiving/widget/tangoarchivingtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import time
from taurus.external.qt import Qt
from taurus.qt.qtgui.util.ui import UILoadable
from fandango.functional import str2time
from fandango.functional import str2time, clmatch, clsearch
from taurus_tangoarchiving.tangoarchivingvalidator import str2localtime

@UILoadable(with_ui='ui')
Expand Down
42 changes: 38 additions & 4 deletions taurus_tangoarchiving/widget/tpgarchiving.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
from taurus_tangoarchiving.widget.tangoarchivingmodelchooser import TangoArchivingModelSelectorItem
from taurus.core.taurushelper import getValidatorFromName

import fandango
import fandango.qt
from operator import isSequenceType

try:
from taurus.qt.qtgui.tpg import (TaurusPlot,
DateAxisItem,
Expand All @@ -56,8 +60,28 @@ def run():

app = TaurusApplication(app_name='tpgArchiving')
gui = TaurusGui()
gui.setWindowTitle('Taurus Archiving Plot')
plot = TaurusPlot()


#class MyPlot(TaurusPlot):
#pass

##def dropEvent(self, event):
##print('In dropEvent(%s)' % str(dir(event)))
##def dragMoveEvent(self,event):
##print('Dragging ...')
##event.acceptProposedAction()
##def dragEnterEvent(self,event):
##print('Entering ...')
##event.acceptProposedAction()

#plot = MyPlot()
#plot.setAcceptDrops(True)
#plot = fandango.qt.Dropable(TaurusPlot)()
#plot.setDropLogger(fandango.printf)
#plot.setSupportedMimeTypes(fandango.qt.MIMETYPES)

plot.setBackgroundBrush(Qt.QColor('white'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, we should keep visual consistency among the various taurus* "oficial" projects (at least those under the taurus-org umbrella).

In that sense, I think that we should not be changing the background of the plots here, but intead do it either in taurus_pyqtgraph in general, or in a final application outside tango-archiving.

If we want to do it in general, we need to consider things with some care (that is why it hasn't been done yet)... but I think this is a time as good as any other to start the discussion, so I created this issue in taurus_pyqtgraph

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same comment is obviously valid for the other usages of setBackgroundBrush()

axis = DateAxisItem(orientation='bottom')
plot_items = plot.getPlotItem()

Expand Down Expand Up @@ -106,7 +130,7 @@ def onUpdateXViewRange():
# Legend
###########################################################################
gv = Qt.QGraphicsView(Qt.QGraphicsScene())
gv.setBackgroundBrush(Qt.QBrush(Qt.QColor('black')))
gv.setBackgroundBrush(Qt.QBrush(Qt.QColor('white')))
l = pg.LegendItem(None, offset=(0, 0))
gv.scene().addItem(l)

Expand Down Expand Up @@ -164,18 +188,28 @@ def updateAll(legend=True):
# onAddXYModel
###########################################################################

def onAddXYModel(models):
def onAddXYModel(models=None):
# Update progress bar
# updateProgressBar(False)
print('onAddXYModel(%s)'%models)
if not isSequenceType(models):
print('Overriding models ...')
models = msi.getSelectedModels()

c = msi.cursor()
msi.setCursor(Qt.Qt.WaitCursor)

current = plot._model_chooser_tool.getModelNames()
print('current: %s' % str(current))
models = [m for m in models if m not in current]
print('new models: %s' % str(models))
plot.addModels(models)
updateAll()
msi.setCursor(c)

# Connect button
msi.modelsAdded.connect(onAddXYModel)

#plot.setDropEventCallback(onAddXYModel)

###########################################################################
# Override TaurusGui close event
Expand Down
Loading