I am trying to make a numpy image slider using chaco which is launched from PySide. Ive tried using matplotlib but it lacked the speed for updating so Ive been trying chaco instead. The script below starts by initializing a Pyside dialog, from here I am trying to open a chaco/traits window which is used to display different views of numpy arrays using a slider to scroll through the arrays like a movie. The script works but I get a warning message:
QCoreApplication::exec: The event loop is already running
I think I probably need to start the chaco window using its own thread or something but am not sure how to go about it. Any help much would be appreciated, the script is below:
import numpy as np
import sys
from PySide.QtCore import *
from PySide.QtGui import *
app = QApplication(sys.argv)
from traits.api import *
from traitsui.api import *
from enable.api import *
from enable.component_editor import *
from chaco.api import *
from chaco.tools.api import *
from chaco import *
class chacoWindow(HasTraits):
#Chaco popup window with slider
plot = Instance(HPlotContainer)
#Slider max value is set using Frame
Frame = Int
high = 100
traits_view = View(Group(
Item('plot',
editor=ComponentEditor(),
show_label=False),
Item( 'Frame',
editor = RangeEditor(
high_name = 'high',
format = '%d',
is_float = False))),
width=1000, height=600, resizable=True, title="Track viewer")
def __init__(self, dataDict, arg1):
self.high = arg1 - 1
self.dataDict = dataDict
self.data1 = self.dataDict['Movie1']
self.data2 = self.dataDict['Movie2']
#Left plot
self.plotdata1 = ArrayPlotData(image1 = self.data1['0'])
plotLeft = Plot(self.plotdata1)
plotLeft.img_plot("image1")
#Right plot
self.plotdata2 = ArrayPlotData(image2 = self.data2['0'])
plotRight = Plot(self.plotdata2)
plotRight.img_plot("image2")
#Add some zoom/pan tools
plotLeft.tools.append(PanTool(plotLeft))
plotLeft.tools.append(BetterZoom(plotLeft, zoom_factor=0.8, zoom_to_mouse = True))
plotLeft.tools.append(DragZoom(plotLeft, drag_button="right"))
plotRight.tools.append(PanTool(plotRight))
plotRight.tools.append(BetterZoom(plotRight))
plotRight.tools.append(DragZoom(plotRight, drag_button="right"))
#Axes shared
plotLeft.range2d = plotRight.range2d
container = HPlotContainer(plotLeft, plotRight)
self.plot = container
def _Frame_changed(self):
#Change frame when slider changes
self.plotdata1.set_data("image1", self.data1[str(self.Frame)])
self.plotdata2.set_data("image2", self.data2[str(self.Frame)])
class Form(QDialog):
#Basic form dialog using Pyside
def __init__(self, dataDict, parent=None):
super(Form, self).__init__(parent)
self.dataDict = dataDict
self.totalFrames = len(dataDict['Movie1'])
formatButton1 = QPushButton("Format 1")
buttonLayout = QHBoxLayout()
buttonLayout.addStretch()
buttonLayout.addWidget(formatButton1)
#Add VBox space for extra widgets
layout = QVBoxLayout()
layout.addLayout(buttonLayout)
self.setLayout(layout)
self.connect(formatButton1, SIGNAL("clicked()"), self.setChaco)
self.setWindowTitle('Master form')
def setChaco(self):
#Create chaco window instance
scatter = chacoWindow(dataDict, self.totalFrames)
scatter.configure_traits(self)
if __name__ == "__main__":
#make some demo data
ar0 = np.zeros((25,25))
ar0[10][10] = 1
ar1 = np.zeros((25,25))
ar1[12][12] = 1
#Dictionary of images
dataDict = {'Movie1': {'0': ar0, '1':ar1, '2':ar0},
'Movie2': {'0': ar1, '1':ar0, '2':ar1}}
form = Form(dataDict)
form.show()
app.exec_()
I managed to find the solution. Changing this function solves the problem:
def setChaco(self):
#Create chaco window instance
scatter = chacoWindow(dataDict, self.totalFrames)
#Change this line: scatter.configure_traits(self)
scatter.edit_traits()
This appears to let the PySide event loop handle everything.