Discussion:
Dynamically Update Dataset?
Brian Clowers
2012-12-18 21:09:14 UTC
Permalink
First thank you for both spyder and guidata. I find them quite useful and
am trying to expand to a more complex application and am running into a
problem when I embed the datasets into a gui. Specifically, it seems
overly complex to have to click on each apply button to register changes to
the dataset. Granted there is the following thread
(https://groups.google.com/d/topic/guidata_guiqwt/9qk0TPGLMzk/discussion),
however, it is still not clear how to make sure the dataset is updated
using an external button.

I've attached an example in which there are a few parameters that I would
like to change and then move straight to the processing button. You'll
that the following example allows me to connect the button clicks to
events, however, I cannot seem to find a way to accept all changes to a
dataset without explicitly clicking on the "Apply" button. Am I emitting
the wrong SIGNAL?

Any help would be appreciated.

Cheers,

Brian




################
# -*- coding: utf-8 -*-
import os
import tempfile, atexit, shutil
import numpy as np


from guidata.dataset.datatypes import (DataSet, BeginTabGroup, EndTabGroup,
BeginGroup, EndGroup, ObjectItem)
from guidata.dataset.dataitems import (FloatItem, IntItem, BoolItem,
ChoiceItem,
MultipleChoiceItem, ImageChoiceItem,
FilesOpenItem,
StringItem, TextItem, ColorItem, FileSaveItem,
FileOpenItem, DirectoryItem, FloatArrayItem,
ButtonItem)


from guidata.configtools import get_icon
from guidata.qthelpers import create_action, add_actions, get_std_icon

from guidata.qt.QtGui import QMainWindow, QSplitter, QPushButton,
QGridLayout, QGroupBox
from guidata.qt.QtCore import SIGNAL, Qt

from guidata.dataset.qtwidgets import DataSetEditLayout, DataSetShowLayout,
DataSetShowGroupBox, DataSetEditGroupBox
from guidata.dataset.qtitemwidgets import DataSetWidget


def dummyCall(a = None, b = None, c = None, d = None):
print ""
#~ print a
#~ print b
#~ print c
#~ print d

class ProcessParams(DataSet):
'''
Note that the None for the callback MUST be replaced or ignored
'''
#This is position 1
floatArray = FloatArrayItem("Float array", default=np.ones( (5,5),
float),
format=" %.2e ").set_pos(col=0)
#This is position 2
processButton = ButtonItem("Process Data", dummyCall).set_pos(col = 1,
colspan = 1)

btnPos = 2

def __init__(self, title=None, comment=None, icon=''):
super(ProcessParams, self).__init__(title, comment, icon)
self.mainWindow = None

def setMainWindow(self, mainWindow):
self.mainWindow = mainWindow

class ExperimentParams(DataSet):
'''
Experimental Parameters
'''
analyteID = StringItem("Analyte ID", "Biotin").set_pos(col=0, colspan =
1)
analyteConc = FloatItem("Analyte Concentration (ppm)", default = 10.0,
min = 0.000005, max = 100000, step = 0.5).set_pos(col=1, colspan = 1)
humidity = FloatItem("Humidity (ppm)", default = 100.0, min = 1, max =
10000, step = 0.5).set_pos(col=0, colspan = 1)
waterBool = BoolItem("Water Spike?").set_pos(col=1, colspan=1)

def __init__(self, title=None, comment=None, icon=''):
super(ExperimentParams, self).__init__(title, comment, icon)
self.mainWindow = None

def setMainWindow(self, mainWindow):
self.mainWindow = mainWindow


class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowIcon(get_icon('python.png'))
self.setWindowTitle("Application example")

# Instantiate dataset-related widgets:


self.expBox = DataSetEditGroupBox("Experimental Parameters",
ExperimentParams, comment='')
self.expBox.dataset.setMainWindow(self)#link to MainWindow instance

self.processingBox = DataSetEditGroupBox("Processing Parameters",
ProcessParams, comment =
'')
self.processingBox.dataset.setMainWindow(self)#link to MainWindow
instance

self.groupList = []
self.groupList.append(self.expBox)

self.groupList.append(self.processingBox)


btnPos = self.processingBox.dataset.btnPos
self.processBtn = self.processingBox.children()[btnPos]
self.connect(self.processBtn, SIGNAL('clicked()'),
self.processingCallback)
vsplitter = QSplitter(Qt.Vertical, self)

vsplitter.addWidget(self.expBox)
vsplitter.addWidget(self.processingBox)
self.setCentralWidget(vsplitter)
self.setContentsMargins(10, 5, 10, 5)


self.connect(self.expBox, SIGNAL("apply_button_clicked()"),
self.updateExperimentBox)

def emitApply(self):
self.processingBox.emit(SIGNAL("apply_button_clicked()"))#This
updates the variables (you hope)
self.expBox.emit(SIGNAL("apply_button_clicked()"))

def updateExperimentBox(self, extra = None):
print "Exp Box Apply Clicked"
print self.expBox.dataset

def processingCallback(self):
print ""
print "Callback"
print self.emitApply()
print self.expBox.dataset
#~ print self.processingBox.dataset



if __name__ == "__main__":
from guidata.qt.QtGui import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Timo
2012-12-18 21:43:47 UTC
Permalink
Hello Brian,

I am no expert, but from my understanding you have to make the proper call
to .get() and .set() of the DataEditGroupBox.

So if you modify your processing Call back to

def processingCallback(self):

print ""

print "Callback"

self.expBox.set() # Update data item values from layout content

print self.expBox.dataset


it should do what you want.

The .get() does exactly the opposite: it updates the display of the widgets
in the layout with the values of the DataItems.


It took me quite a while to understand this behavior :-)


Best regards from the today not so sunny San Diego,


Timo
Post by Brian Clowers
First thank you for both spyder and guidata. I find them quite useful and
am trying to expand to a more complex application and am running into a
problem when I embed the datasets into a gui. Specifically, it seems
overly complex to have to click on each apply button to register changes to
the dataset. Granted there is the following thread (
https://groups.google.com/d/topic/guidata_guiqwt/9qk0TPGLMzk/discussion),
however, it is still not clear how to make sure the dataset is updated
using an external button.
I've attached an example in which there are a few parameters that I would
like to change and then move straight to the processing button. You'll
that the following example allows me to connect the button clicks to
events, however, I cannot seem to find a way to accept all changes to a
dataset without explicitly clicking on the "Apply" button. Am I emitting
the wrong SIGNAL?
Any help would be appreciated.
Cheers,
Brian
################
# -*- coding: utf-8 -*-
import os
import tempfile, atexit, shutil
import numpy as np
from guidata.dataset.datatypes import (DataSet, BeginTabGroup, EndTabGroup,
BeginGroup, EndGroup, ObjectItem)
from guidata.dataset.dataitems import (FloatItem, IntItem, BoolItem,
ChoiceItem,
MultipleChoiceItem, ImageChoiceItem,
FilesOpenItem,
StringItem, TextItem, ColorItem, FileSaveItem,
FileOpenItem, DirectoryItem, FloatArrayItem,
ButtonItem)
from guidata.configtools import get_icon
from guidata.qthelpers import create_action, add_actions, get_std_icon
from guidata.qt.QtGui import QMainWindow, QSplitter, QPushButton,
QGridLayout, QGroupBox
from guidata.qt.QtCore import SIGNAL, Qt
from guidata.dataset.qtwidgets import DataSetEditLayout,
DataSetShowLayout, DataSetShowGroupBox, DataSetEditGroupBox
from guidata.dataset.qtitemwidgets import DataSetWidget
print ""
#~ print a
#~ print b
#~ print c
#~ print d
'''
Note that the None for the callback MUST be replaced or ignored
'''
#This is position 1
floatArray = FloatArrayItem("Float array", default=np.ones( (5,5),
float),
format=" %.2e ").set_pos(col=0)
#This is position 2
processButton = ButtonItem("Process Data", dummyCall).set_pos(col = 1,
colspan = 1)
btnPos = 2
super(ProcessParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
'''
Experimental Parameters
'''
analyteID = StringItem("Analyte ID", "Biotin").set_pos(col=0, colspan
= 1)
analyteConc = FloatItem("Analyte Concentration (ppm)", default = 10.0,
min = 0.000005, max = 100000, step = 0.5).set_pos(col=1, colspan = 1)
humidity = FloatItem("Humidity (ppm)", default = 100.0, min = 1, max =
10000, step = 0.5).set_pos(col=0, colspan = 1)
waterBool = BoolItem("Water Spike?").set_pos(col=1, colspan=1)
super(ExperimentParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
super(MainWindow, self).__init__()
self.setWindowIcon(get_icon('python.png'))
self.setWindowTitle("Application example")
self.expBox = DataSetEditGroupBox("Experimental Parameters",
ExperimentParams, comment='')
self.expBox.dataset.setMainWindow(self)#link to MainWindow instance
self.processingBox = DataSetEditGroupBox("Processing Parameters",
ProcessParams, comment =
'')
self.processingBox.dataset.setMainWindow(self)#link to MainWindow
instance
self.groupList = []
self.groupList.append(self.expBox)
self.groupList.append(self.processingBox)
btnPos = self.processingBox.dataset.btnPos
self.processBtn = self.processingBox.children()[btnPos]
self.connect(self.processBtn, SIGNAL('clicked()'),
self.processingCallback)
vsplitter = QSplitter(Qt.Vertical, self)
vsplitter.addWidget(self.expBox)
vsplitter.addWidget(self.processingBox)
self.setCentralWidget(vsplitter)
self.setContentsMargins(10, 5, 10, 5)
self.connect(self.expBox, SIGNAL("apply_button_clicked()"),
self.updateExperimentBox)
self.processingBox.emit(SIGNAL("apply_button_clicked()"))#This
updates the variables (you hope)
self.expBox.emit(SIGNAL("apply_button_clicked()"))
print "Exp Box Apply Clicked"
print self.expBox.dataset
print ""
print "Callback"
print self.emitApply()
print self.expBox.dataset
#~ print self.processingBox.dataset
from guidata.qt.QtGui import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Brian Clowers
2012-12-18 22:21:22 UTC
Permalink
Timo,

Thanks a bunch. I can't believe I missed that and am glad it was so
simple. Any chance you know how to register a custom matplotlib instance
to work with guidata?

Cheers,

Brian

--Should we ever cross paths remember that I owe you a beer.
Post by Timo
Hello Brian,
I am no expert, but from my understanding you have to make the proper call
to .get() and .set() of the DataEditGroupBox.
So if you modify your processing Call back to
print ""
print "Callback"
self.expBox.set() # Update data item values from layout content
print self.expBox.dataset
it should do what you want.
The .get() does exactly the opposite: it updates the display of the
widgets in the layout with the values of the DataItems.
It took me quite a while to understand this behavior :-)
Best regards from the today not so sunny San Diego,
Timo
Post by Brian Clowers
First thank you for both spyder and guidata. I find them quite useful
and am trying to expand to a more complex application and am running into a
problem when I embed the datasets into a gui. Specifically, it seems
overly complex to have to click on each apply button to register changes to
the dataset. Granted there is the following thread (
https://groups.google.com/d/topic/guidata_guiqwt/9qk0TPGLMzk/discussion),
however, it is still not clear how to make sure the dataset is updated
using an external button.
I've attached an example in which there are a few parameters that I would
like to change and then move straight to the processing button. You'll
that the following example allows me to connect the button clicks to
events, however, I cannot seem to find a way to accept all changes to a
dataset without explicitly clicking on the "Apply" button. Am I emitting
the wrong SIGNAL?
Any help would be appreciated.
Cheers,
Brian
################
# -*- coding: utf-8 -*-
import os
import tempfile, atexit, shutil
import numpy as np
from guidata.dataset.datatypes import (DataSet, BeginTabGroup, EndTabGroup,
BeginGroup, EndGroup, ObjectItem)
from guidata.dataset.dataitems import (FloatItem, IntItem, BoolItem,
ChoiceItem,
MultipleChoiceItem, ImageChoiceItem,
FilesOpenItem,
StringItem, TextItem, ColorItem,
FileSaveItem,
FileOpenItem, DirectoryItem, FloatArrayItem,
ButtonItem)
from guidata.configtools import get_icon
from guidata.qthelpers import create_action, add_actions, get_std_icon
from guidata.qt.QtGui import QMainWindow, QSplitter, QPushButton,
QGridLayout, QGroupBox
from guidata.qt.QtCore import SIGNAL, Qt
from guidata.dataset.qtwidgets import DataSetEditLayout,
DataSetShowLayout, DataSetShowGroupBox, DataSetEditGroupBox
from guidata.dataset.qtitemwidgets import DataSetWidget
print ""
#~ print a
#~ print b
#~ print c
#~ print d
'''
Note that the None for the callback MUST be replaced or ignored
'''
#This is position 1
floatArray = FloatArrayItem("Float array", default=np.ones( (5,5),
float),
format=" %.2e ").set_pos(col=0)
#This is position 2
processButton = ButtonItem("Process Data", dummyCall).set_pos(col =
1, colspan = 1)
btnPos = 2
super(ProcessParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
'''
Experimental Parameters
'''
analyteID = StringItem("Analyte ID", "Biotin").set_pos(col=0, colspan
= 1)
analyteConc = FloatItem("Analyte Concentration (ppm)", default =
10.0, min = 0.000005, max = 100000, step = 0.5).set_pos(col=1, colspan = 1)
humidity = FloatItem("Humidity (ppm)", default = 100.0, min = 1, max
= 10000, step = 0.5).set_pos(col=0, colspan = 1)
waterBool = BoolItem("Water Spike?").set_pos(col=1, colspan=1)
super(ExperimentParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
super(MainWindow, self).__init__()
self.setWindowIcon(get_icon('python.png'))
self.setWindowTitle("Application example")
self.expBox = DataSetEditGroupBox("Experimental Parameters",
ExperimentParams, comment='')
self.expBox.dataset.setMainWindow(self)#link to MainWindow instance
self.processingBox = DataSetEditGroupBox("Processing Parameters",
ProcessParams, comment =
'')
self.processingBox.dataset.setMainWindow(self)#link to MainWindow
instance
self.groupList = []
self.groupList.append(self.expBox)
self.groupList.append(self.processingBox)
btnPos = self.processingBox.dataset.btnPos
self.processBtn = self.processingBox.children()[btnPos]
self.connect(self.processBtn, SIGNAL('clicked()'),
self.processingCallback)
vsplitter = QSplitter(Qt.Vertical, self)
vsplitter.addWidget(self.expBox)
vsplitter.addWidget(self.processingBox)
self.setCentralWidget(vsplitter)
self.setContentsMargins(10, 5, 10, 5)
self.connect(self.expBox, SIGNAL("apply_button_clicked()"),
self.updateExperimentBox)
self.processingBox.emit(SIGNAL("apply_button_clicked()"))#This
updates the variables (you hope)
self.expBox.emit(SIGNAL("apply_button_clicked()"))
print "Exp Box Apply Clicked"
print self.expBox.dataset
print ""
print "Callback"
print self.emitApply()
print self.expBox.dataset
#~ print self.processingBox.dataset
from guidata.qt.QtGui import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Timo
2012-12-19 01:07:35 UTC
Permalink
Hi Brian,

Your are welcome.
As I said I am not an expert and I still do not understand why changing the
values of a DatasetItem works in the examples (e.g. all_features.py of the
guidata.tests suite) without the need of a .get() or .set() call but not
in your or my code. In principle that is something one could look into and
than maybe file a bug report (or patch) but my python projects are
currently very low priority :-)

I am not sure what you mean by registering a custom matplotlib instance
with guidata. For my own application (mainly a tool to read and analyze the
mass-spec data from our thermal desorption setup) I simply use the guiqwt
plot components.

Timo

p.s. I can only join your thanks to the developers of spyder, guidata and
guiqwt as these tools simplify developing small gui programs considerably.
Post by Brian Clowers
Timo,
Thanks a bunch. I can't believe I missed that and am glad it was so
simple. Any chance you know how to register a custom matplotlib instance
to work with guidata?
Cheers,
Brian
--Should we ever cross paths remember that I owe you a beer.
Post by Timo
Hello Brian,
I am no expert, but from my understanding you have to make the proper
call to .get() and .set() of the DataEditGroupBox.
So if you modify your processing Call back to
print ""
print "Callback"
self.expBox.set() # Update data item values from layout content
print self.expBox.dataset
it should do what you want.
The .get() does exactly the opposite: it updates the display of the
widgets in the layout with the values of the DataItems.
It took me quite a while to understand this behavior :-)
Best regards from the today not so sunny San Diego,
Timo
Post by Brian Clowers
First thank you for both spyder and guidata. I find them quite useful
and am trying to expand to a more complex application and am running into a
problem when I embed the datasets into a gui. Specifically, it seems
overly complex to have to click on each apply button to register changes to
the dataset. Granted there is the following thread (
https://groups.google.com/d/topic/guidata_guiqwt/9qk0TPGLMzk/discussion),
however, it is still not clear how to make sure the dataset is updated
using an external button.
I've attached an example in which there are a few parameters that I
would like to change and then move straight to the processing button.
You'll that the following example allows me to connect the button clicks to
events, however, I cannot seem to find a way to accept all changes to a
dataset without explicitly clicking on the "Apply" button. Am I emitting
the wrong SIGNAL?
Any help would be appreciated.
Cheers,
Brian
################
# -*- coding: utf-8 -*-
import os
import tempfile, atexit, shutil
import numpy as np
from guidata.dataset.datatypes import (DataSet, BeginTabGroup, EndTabGroup,
BeginGroup, EndGroup, ObjectItem)
from guidata.dataset.dataitems import (FloatItem, IntItem, BoolItem,
ChoiceItem,
MultipleChoiceItem, ImageChoiceItem,
FilesOpenItem,
StringItem, TextItem, ColorItem, FileSaveItem,
FileOpenItem, DirectoryItem,
FloatArrayItem, ButtonItem)
from guidata.configtools import get_icon
from guidata.qthelpers import create_action, add_actions, get_std_icon
from guidata.qt.QtGui import QMainWindow, QSplitter, QPushButton,
QGridLayout, QGroupBox
from guidata.qt.QtCore import SIGNAL, Qt
from guidata.dataset.qtwidgets import DataSetEditLayout,
DataSetShowLayout, DataSetShowGroupBox, DataSetEditGroupBox
from guidata.dataset.qtitemwidgets import DataSetWidget
print ""
#~ print a
#~ print b
#~ print c
#~ print d
'''
Note that the None for the callback MUST be replaced or ignored
'''
#This is position 1
floatArray = FloatArrayItem("Float array", default=np.ones( (5,5),
float),
format=" %.2e ").set_pos(col=0)
#This is position 2
processButton = ButtonItem("Process Data", dummyCall).set_pos(col =
1, colspan = 1)
btnPos = 2
super(ProcessParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
'''
Experimental Parameters
'''
analyteID = StringItem("Analyte ID", "Biotin").set_pos(col=0,
colspan = 1)
analyteConc = FloatItem("Analyte Concentration (ppm)", default =
10.0, min = 0.000005, max = 100000, step = 0.5).set_pos(col=1, colspan = 1)
humidity = FloatItem("Humidity (ppm)", default = 100.0, min = 1, max
= 10000, step = 0.5).set_pos(col=0, colspan = 1)
waterBool = BoolItem("Water Spike?").set_pos(col=1, colspan=1)
super(ExperimentParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
super(MainWindow, self).__init__()
self.setWindowIcon(get_icon('python.png'))
self.setWindowTitle("Application example")
self.expBox = DataSetEditGroupBox("Experimental Parameters",
ExperimentParams, comment='')
self.expBox.dataset.setMainWindow(self)#link to MainWindow instance
self.processingBox = DataSetEditGroupBox("Processing
Parameters",
ProcessParams, comment
= '')
self.processingBox.dataset.setMainWindow(self)#link to
MainWindow instance
self.groupList = []
self.groupList.append(self.expBox)
self.groupList.append(self.processingBox)
btnPos = self.processingBox.dataset.btnPos
self.processBtn = self.processingBox.children()[btnPos]
self.connect(self.processBtn, SIGNAL('clicked()'),
self.processingCallback)
vsplitter = QSplitter(Qt.Vertical, self)
vsplitter.addWidget(self.expBox)
vsplitter.addWidget(self.processingBox)
self.setCentralWidget(vsplitter)
self.setContentsMargins(10, 5, 10, 5)
self.connect(self.expBox, SIGNAL("apply_button_clicked()"),
self.updateExperimentBox)
self.processingBox.emit(SIGNAL("apply_button_clicked()"))#This
updates the variables (you hope)
self.expBox.emit(SIGNAL("apply_button_clicked()"))
print "Exp Box Apply Clicked"
print self.expBox.dataset
print ""
print "Callback"
print self.emitApply()
print self.expBox.dataset
#~ print self.processingBox.dataset
from guidata.qt.QtGui import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Brian Clowers
2012-12-20 04:47:26 UTC
Permalink
I am just now looking at the quiqwt library and was simply hoping that a
matplotlib canvas could easily be adapted as a guidata widget. Seeing as I
am mostly familiar with matplotlib I went ahead and embedded a matplotlib
canvas as a QWidget, which seems to work just fine.

However, there is another problem that I keep running into regarding the
ability to make sure that when I call the "set_prop" function of a given
item that the new value actually is displayed in the gui. For example if I
create a new IntItem with a slider there is a time when I want to update
the maximum value. It appears as though when I update the "max" property I
have to close the edit dialog and reopen it before the change take effect.
Is there a way to do this on the fly and simply repaint the item?

Initial:

newIntSlider = IntItem("Scan Index", default=5, min=1, max=25, slider=True)

Later in the code:

newIntSlider.set_prop("display", max = 40)#this doesn't seem to work unless
you close/reopen the interface

###########

I'd also like to do this for a FloatArrayItem and am having an even bigger
problem there. It appears that even if I set the default to a new value
and close/reopen the dataset the new array is not applied. Any ideas?

floatArray = FloatArrayItem("Data Array", default=N.ones((5,10), float),
format=" %.2e ")

Later:

floatArray.set_prop("display", default = N.arange((5,50), float))

##########

Cheers,

Brian
Post by Timo
Hi Brian,
Your are welcome.
As I said I am not an expert and I still do not understand why changing
the values of a DatasetItem works in the examples (e.g. all_features.py of
the guidata.tests suite) without the need of a .get() or .set() call but
not in your or my code. In principle that is something one could look into
and than maybe file a bug report (or patch) but my python projects are
currently very low priority :-)
I am not sure what you mean by registering a custom matplotlib instance
with guidata. For my own application (mainly a tool to read and analyze the
mass-spec data from our thermal desorption setup) I simply use the guiqwt
plot components.
Timo
p.s. I can only join your thanks to the developers of spyder, guidata and
guiqwt as these tools simplify developing small gui programs considerably.
Post by Brian Clowers
Timo,
Thanks a bunch. I can't believe I missed that and am glad it was so
simple. Any chance you know how to register a custom matplotlib instance
to work with guidata?
Cheers,
Brian
--Should we ever cross paths remember that I owe you a beer.
Post by Timo
Hello Brian,
I am no expert, but from my understanding you have to make the proper
call to .get() and .set() of the DataEditGroupBox.
So if you modify your processing Call back to
print ""
print "Callback"
self.expBox.set() # Update data item values from layout content
print self.expBox.dataset
it should do what you want.
The .get() does exactly the opposite: it updates the display of the
widgets in the layout with the values of the DataItems.
It took me quite a while to understand this behavior :-)
Best regards from the today not so sunny San Diego,
Timo
Post by Brian Clowers
First thank you for both spyder and guidata. I find them quite useful
and am trying to expand to a more complex application and am running into a
problem when I embed the datasets into a gui. Specifically, it seems
overly complex to have to click on each apply button to register changes to
the dataset. Granted there is the following thread (
https://groups.google.com/d/topic/guidata_guiqwt/9qk0TPGLMzk/discussion),
however, it is still not clear how to make sure the dataset is updated
using an external button.
I've attached an example in which there are a few parameters that I
would like to change and then move straight to the processing button.
You'll that the following example allows me to connect the button clicks to
events, however, I cannot seem to find a way to accept all changes to a
dataset without explicitly clicking on the "Apply" button. Am I emitting
the wrong SIGNAL?
Any help would be appreciated.
Cheers,
Brian
################
# -*- coding: utf-8 -*-
import os
import tempfile, atexit, shutil
import numpy as np
from guidata.dataset.datatypes import (DataSet, BeginTabGroup, EndTabGroup,
BeginGroup, EndGroup, ObjectItem)
from guidata.dataset.dataitems import (FloatItem, IntItem, BoolItem,
ChoiceItem,
MultipleChoiceItem, ImageChoiceItem,
FilesOpenItem,
StringItem, TextItem, ColorItem, FileSaveItem,
FileOpenItem, DirectoryItem,
FloatArrayItem, ButtonItem)
from guidata.configtools import get_icon
from guidata.qthelpers import create_action, add_actions, get_std_icon
from guidata.qt.QtGui import QMainWindow, QSplitter, QPushButton,
QGridLayout, QGroupBox
from guidata.qt.QtCore import SIGNAL, Qt
from guidata.dataset.qtwidgets import DataSetEditLayout,
DataSetShowLayout, DataSetShowGroupBox, DataSetEditGroupBox
from guidata.dataset.qtitemwidgets import DataSetWidget
print ""
#~ print a
#~ print b
#~ print c
#~ print d
'''
Note that the None for the callback MUST be replaced or ignored
'''
#This is position 1
floatArray = FloatArrayItem("Float array", default=np.ones( (5,5),
float),
format=" %.2e ").set_pos(col=0)
#This is position 2
processButton = ButtonItem("Process Data", dummyCall).set_pos(col =
1, colspan = 1)
btnPos = 2
super(ProcessParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
'''
Experimental Parameters
'''
analyteID = StringItem("Analyte ID", "Biotin").set_pos(col=0,
colspan = 1)
analyteConc = FloatItem("Analyte Concentration (ppm)", default =
10.0, min = 0.000005, max = 100000, step = 0.5).set_pos(col=1, colspan = 1)
humidity = FloatItem("Humidity (ppm)", default = 100.0, min = 1,
max = 10000, step = 0.5).set_pos(col=0, colspan = 1)
waterBool = BoolItem("Water Spike?").set_pos(col=1, colspan=1)
super(ExperimentParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
super(MainWindow, self).__init__()
self.setWindowIcon(get_icon('python.png'))
self.setWindowTitle("Application example")
self.expBox = DataSetEditGroupBox("Experimental Parameters",
ExperimentParams, comment='')
self.expBox.dataset.setMainWindow(self)#link to MainWindow instance
self.processingBox = DataSetEditGroupBox("Processing Parameters",
ProcessParams, comment
= '')
self.processingBox.dataset.setMainWindow(self)#link to
MainWindow instance
self.groupList = []
self.groupList.append(self.expBox)
self.groupList.append(self.processingBox)
btnPos = self.processingBox.dataset.btnPos
self.processBtn = self.processingBox.children()[btnPos]
self.connect(self.processBtn, SIGNAL('clicked()'),
self.processingCallback)
vsplitter = QSplitter(Qt.Vertical, self)
vsplitter.addWidget(self.expBox)
vsplitter.addWidget(self.processingBox)
self.setCentralWidget(vsplitter)
self.setContentsMargins(10, 5, 10, 5)
self.connect(self.expBox, SIGNAL("apply_button_clicked()"),
self.updateExperimentBox)
self.processingBox.emit(SIGNAL("apply_button_clicked()"))#This
updates the variables (you hope)
self.expBox.emit(SIGNAL("apply_button_clicked()"))
print "Exp Box Apply Clicked"
print self.expBox.dataset
print ""
print "Callback"
print self.emitApply()
print self.expBox.dataset
#~ print self.processingBox.dataset
from guidata.qt.QtGui import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Neal Gordon
2014-09-28 04:30:11 UTC
Permalink
great post. thanks!
Post by Brian Clowers
I am just now looking at the quiqwt library and was simply hoping that a
matplotlib canvas could easily be adapted as a guidata widget. Seeing as I
am mostly familiar with matplotlib I went ahead and embedded a matplotlib
canvas as a QWidget, which seems to work just fine.
However, there is another problem that I keep running into regarding the
ability to make sure that when I call the "set_prop" function of a given
item that the new value actually is displayed in the gui. For example if I
create a new IntItem with a slider there is a time when I want to update
the maximum value. It appears as though when I update the "max" property I
have to close the edit dialog and reopen it before the change take effect.
Is there a way to do this on the fly and simply repaint the item?
newIntSlider = IntItem("Scan Index", default=5, min=1, max=25, slider=True)
newIntSlider.set_prop("display", max = 40)#this doesn't seem to work
unless you close/reopen the interface
###########
I'd also like to do this for a FloatArrayItem and am having an even bigger
problem there. It appears that even if I set the default to a new value
and close/reopen the dataset the new array is not applied. Any ideas?
floatArray = FloatArrayItem("Data Array", default=N.ones((5,10), float),
format=" %.2e ")
floatArray.set_prop("display", default = N.arange((5,50), float))
##########
Cheers,
Brian
Post by Timo
Hi Brian,
Your are welcome.
As I said I am not an expert and I still do not understand why changing
the values of a DatasetItem works in the examples (e.g. all_features.py of
the guidata.tests suite) without the need of a .get() or .set() call but
not in your or my code. In principle that is something one could look into
and than maybe file a bug report (or patch) but my python projects are
currently very low priority :-)
I am not sure what you mean by registering a custom matplotlib instance
with guidata. For my own application (mainly a tool to read and analyze the
mass-spec data from our thermal desorption setup) I simply use the guiqwt
plot components.
Timo
p.s. I can only join your thanks to the developers of spyder, guidata and
guiqwt as these tools simplify developing small gui programs considerably.
Post by Brian Clowers
Timo,
Thanks a bunch. I can't believe I missed that and am glad it was so
simple. Any chance you know how to register a custom matplotlib instance
to work with guidata?
Cheers,
Brian
--Should we ever cross paths remember that I owe you a beer.
Post by Timo
Hello Brian,
I am no expert, but from my understanding you have to make the proper
call to .get() and .set() of the DataEditGroupBox.
So if you modify your processing Call back to
print ""
print "Callback"
self.expBox.set() # Update data item values from layout content
print self.expBox.dataset
it should do what you want.
The .get() does exactly the opposite: it updates the display of the
widgets in the layout with the values of the DataItems.
It took me quite a while to understand this behavior :-)
Best regards from the today not so sunny San Diego,
Timo
Post by Brian Clowers
First thank you for both spyder and guidata. I find them quite useful
and am trying to expand to a more complex application and am running into a
problem when I embed the datasets into a gui. Specifically, it seems
overly complex to have to click on each apply button to register changes to
the dataset. Granted there is the following thread (
https://groups.google.com/d/topic/guidata_guiqwt/9qk0TPGLMzk/discussion),
however, it is still not clear how to make sure the dataset is updated
using an external button.
I've attached an example in which there are a few parameters that I
would like to change and then move straight to the processing button.
You'll that the following example allows me to connect the button clicks to
events, however, I cannot seem to find a way to accept all changes to a
dataset without explicitly clicking on the "Apply" button. Am I emitting
the wrong SIGNAL?
Any help would be appreciated.
Cheers,
Brian
################
# -*- coding: utf-8 -*-
import os
import tempfile, atexit, shutil
import numpy as np
from guidata.dataset.datatypes import (DataSet, BeginTabGroup, EndTabGroup,
BeginGroup, EndGroup, ObjectItem)
from guidata.dataset.dataitems import (FloatItem, IntItem, BoolItem,
ChoiceItem,
MultipleChoiceItem, ImageChoiceItem,
FilesOpenItem,
StringItem, TextItem, ColorItem, FileSaveItem,
FileOpenItem, DirectoryItem,
FloatArrayItem, ButtonItem)
from guidata.configtools import get_icon
from guidata.qthelpers import create_action, add_actions, get_std_icon
from guidata.qt.QtGui import QMainWindow, QSplitter, QPushButton,
QGridLayout, QGroupBox
from guidata.qt.QtCore import SIGNAL, Qt
from guidata.dataset.qtwidgets import DataSetEditLayout,
DataSetShowLayout, DataSetShowGroupBox, DataSetEditGroupBox
from guidata.dataset.qtitemwidgets import DataSetWidget
print ""
#~ print a
#~ print b
#~ print c
#~ print d
'''
Note that the None for the callback MUST be replaced or ignored
'''
#This is position 1
floatArray = FloatArrayItem("Float array", default=np.ones( (5,5),
float),
format=" %.2e ").set_pos(col=0)
#This is position 2
processButton = ButtonItem("Process Data", dummyCall).set_pos(col
= 1, colspan = 1)
btnPos = 2
super(ProcessParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
'''
Experimental Parameters
'''
analyteID = StringItem("Analyte ID", "Biotin").set_pos(col=0,
colspan = 1)
analyteConc = FloatItem("Analyte Concentration (ppm)", default =
10.0, min = 0.000005, max = 100000, step = 0.5).set_pos(col=1, colspan = 1)
humidity = FloatItem("Humidity (ppm)", default = 100.0, min = 1,
max = 10000, step = 0.5).set_pos(col=0, colspan = 1)
waterBool = BoolItem("Water Spike?").set_pos(col=1, colspan=1)
super(ExperimentParams, self).__init__(title, comment, icon)
self.mainWindow = None
self.mainWindow = mainWindow
super(MainWindow, self).__init__()
self.setWindowIcon(get_icon('python.png'))
self.setWindowTitle("Application example")
self.expBox = DataSetEditGroupBox("Experimental Parameters",
ExperimentParams, comment='')
self.expBox.dataset.setMainWindow(self)#link to MainWindow instance
self.processingBox = DataSetEditGroupBox("Processing Parameters",
ProcessParams,
comment = '')
self.processingBox.dataset.setMainWindow(self)#link to
MainWindow instance
self.groupList = []
self.groupList.append(self.expBox)
self.groupList.append(self.processingBox)
btnPos = self.processingBox.dataset.btnPos
self.processBtn = self.processingBox.children()[btnPos]
self.connect(self.processBtn, SIGNAL('clicked()'),
self.processingCallback)
vsplitter = QSplitter(Qt.Vertical, self)
vsplitter.addWidget(self.expBox)
vsplitter.addWidget(self.processingBox)
self.setCentralWidget(vsplitter)
self.setContentsMargins(10, 5, 10, 5)
self.connect(self.expBox, SIGNAL("apply_button_clicked()"),
self.updateExperimentBox)
self.processingBox.emit(SIGNAL("apply_button_clicked()"))#This
updates the variables (you hope)
self.expBox.emit(SIGNAL("apply_button_clicked()"))
print "Exp Box Apply Clicked"
print self.expBox.dataset
print ""
print "Callback"
print self.emitApply()
print self.expBox.dataset
#~ print self.processingBox.dataset
from guidata.qt.QtGui import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
--
You received this message because you are subscribed to the Google Groups "guidata/guiqwt" group.
To unsubscribe from this group and stop receiving emails from it, send an email to guidata_guiqwt+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/***@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
Loading...