From ccf7ceb0372c57cb5ca58c4e122ac37e815888c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Thu, 22 Nov 2012 17:49:57 +0100 Subject: [PATCH] delete and save solders are more robust now, added slope_marker issue workaround for numpy.log10 --- reflowctl/reflowctl_gui.py | 163 ++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 94 deletions(-) diff --git a/reflowctl/reflowctl_gui.py b/reflowctl/reflowctl_gui.py index 11135bf..2a5ef01 100755 --- a/reflowctl/reflowctl_gui.py +++ b/reflowctl/reflowctl_gui.py @@ -109,8 +109,9 @@ class Solder(QtCore.QObject): log_message = QtCore.pyqtSignal(str) - def __init__(self, name=str(), description=str(), parent=None): + def __init__(self, filename, name=str(), description=str(), parent=None): super(Solder, self).__init__(parent) + self.filename = filename self.name = name self.description = description self.temp_levels = list() @@ -221,81 +222,21 @@ class Solder(QtCore.QObject): elif len(rate_x) > 0: x.extend(rate_x) y.extend(rate_y) - else: - if temp_level not in used: - unused.append(temp_level) + elif temp_level not in used: + unused.append(temp_level) self.log.append("") map(self.log.append, ["* Missing Connection: %r" % tl.name for tl in unused]) self.log_message.emit("\n".join(self.log)) del self.log - return array(map(float, x)), array(map(float, y)), max(x), max(y), used, unused - - def calc_profile_old(self): - - x = list() - y = list() - duration_points = dict() - rate_points = dict() - self.time = 0 - used_temp_levels = set() - for ix, temp_level in enumerate(self.temp_levels): - if temp_level != self.temp_levels[0] and temp_level not in used_temp_levels: - ix = self.temp_levels.index(temp_level) - raise ValueError("TempLevel %r not connected to %r" % (self.temp_levels[ix-1].name, self.temp_levels[ix].name)) - - temp_levels = None - duration = None - for sts, dur in self.durations: - if sts and sts[0] == temp_level: - duration = dur - temp_levels = sts - break - - if temp_level not in used_temp_levels: - used_temp_levels.add(temp_level) - x.append(self.time) - y.append(temp_level.temp) - - if duration is not None: - if len(temp_levels) == 3: - used_temp_levels.add(temp_levels[1]) - used_temp_levels.add(temp_levels[2]) - - self.time += duration / 2 - x.append(self.time) - y.append(temp_levels[1].temp) - - self.time += duration / 2 - x.append(self.time) - y.append(temp_levels[2].temp) - - duration_points[ix] = (x[-3:], y[-3:]) - else: - y.append(temp_levels[1].temp) - used_temp_levels.add(temp_levels[1]) - self.time += duration - x.append(self.time) - duration_points[ix] = (x[-2:], y[-2:]) - else: - for ex, (sts, rate) in enumerate(self.rates): - if sts and sts[0] == temp_level: - used_temp_levels.add(sts[1]) - duration = (sts[1].temp - temp_level.temp) / rate - self.time += duration - x.append(self.time) - y.append(sts[1].temp) - rate_points[ex] = (x[-2:], y[-2:]) - - return array(map(float, x)), array(map(float, y)), max(x), max(y), duration_points, rate_points - + return array(map(float, x)), array(map(float, y)), min(x), max(x), min(y), max(y), used, unused @staticmethod def unpack(filename, parent): xmltree = etree.parse(filename) root = xmltree.getroot() solder_node = root[0] - s = Solder(solder_node.attrib["name"], solder_node.attrib["description"], parent) + s = Solder(filename, solder_node.attrib["name"], solder_node.attrib["description"], parent) env_count = 0 for temp_level in solder_node.findall("state"): tstr = temp_level.attrib["temperature"] @@ -324,7 +265,7 @@ class Solder(QtCore.QObject): return s - def save(self, filename): + def save(self): if self.changed: solder_node = etree.Element("solder_type", {"name" : self.name, "description" : self.description}) for temp_level in self.temp_levels: @@ -344,9 +285,13 @@ class Solder(QtCore.QObject): dirname = os.path.join(os.path.dirname(__file__), "solder_types") root = etree.Element("xml") root.append(solder_node) - etree.ElementTree(root).write(os.path.join(dirname, self.name + ".xml"), "UTF-8", True) + etree.ElementTree(root).write(self.filename, "UTF-8", True) self.changed = False + def setChanged(self): + print self.setChanged + self.changed = True + class SolderListModel(QtCore.QAbstractListModel): @@ -375,15 +320,16 @@ class SolderListModel(QtCore.QAbstractListModel): return QtCore.QVariant() def data(self, index, role): - if index.isValid() and role == QtCore.Qt.DisplayRole: - solder = self.listdata[index.row()] - if solder.changed: - return QtCore.QVariant(solder.name + " *") - else: - return QtCore.QVariant(solder.name) - else: + if not index.isValid(): return QtCore.QVariant() + solder = self.listdata[index.row()] + if role == QtCore.Qt.DisplayRole: + return QtCore.QVariant(solder.name) + + elif role == QtCore.Qt.DecorationRole and solder.changed: + return QtGui.QIcon.fromTheme("document-save") + def setData(self, index, variant, role): if index.isValid() and role == QtCore.Qt.EditRole: new_name = str(variant.toString()) @@ -458,6 +404,7 @@ class TempLevelModel(QtCore.QAbstractTableModel): self.temp_levels[index.row()].name = str(variant.toString()) elif col == 1: self.temp_levels[index.row()].temp = variant.toInt()[0] + print "emit solder_changed" self.solder_changed.emit() return True return False @@ -525,9 +472,10 @@ class Plotter(FigureCanvas): QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.update_figure) timer.start(1000) - self.updated = True + self.updated = False def update_figure(self): + self.fig.lines = lines = list() if self.updated: self.updated = False self.axes.patches = list() @@ -535,7 +483,16 @@ class Plotter(FigureCanvas): self.x = list() self.y = list() - self.x, self.y, self.xmax, self.ymax, self.used, self.unused = self.solder.calc_profile() + self.x, self.y, self.xmin, self.xmax, self.ymin, self.ymax, self.used, self.unused = self.solder.calc_profile() + + self.plot_data.set_xdata(self.x) + self.plot_data.set_ydata(self.y) + + self.axes.set_xbound(lower=self.xmin, upper=self.xmax + 20) + self.axes.set_ybound(lower=self.ymin, upper=self.ymax + 20) + + self.axes.set_yticks(self.y) + self.axes.set_xticks(self.x) for ix, (a, b) in enumerate(zip(self.x[:-1], self.y[:-1])): slope = (self.y[ix+1] - b) / (self.x[ix+1] - a) @@ -543,32 +500,19 @@ class Plotter(FigureCanvas): origin = (a + 10, b) annotation.slope_marker(origin, slope, ax=self.axes) - self.plot_data.set_xdata(self.x) - self.plot_data.set_ydata(self.y) + self.axes.legend(("Estimated profile",), loc=2) - self.axes.set_xbound(lower=0, upper=self.xmax + 20) - self.axes.set_ybound(lower=0, upper=self.ymax + 20) - - self.axes.set_yticks(self.y) - self.axes.set_xticks(self.x) - - #duration_widget = self.myapp.duration_widget - - #self.selection_data.set_xdata(array(da)) - #self.selection_data.set_ydata(array(db)) - - self.fig.lines = lines = list() for temp_level in self.solder.temp_levels: if not temp_level.is_env: line = Line2D([0, self.xmax + 20], [temp_level.temp, temp_level.temp], transform=self.axes.transData, figure=self.fig, color=str(temp_level.color.name()), label="name", zorder=1) lines.append(line) - self.axes.legend(("Estimated profile",), loc=2) self.draw() def solder_changed(self): - self.solder.changed = True + print self.solder_changed + self.solder.setChanged() self.updated = True def setData(self, solder): @@ -955,6 +899,7 @@ class TempLevelWidget(QtGui.QWidget): def __init__(self, parent, readonly=False): super(TempLevelWidget, self).__init__(parent) + self.readonly = readonly self.temp_level_model = TempLevelModel(self) self.temp_level_view = QtGui.QTableView() @@ -1003,6 +948,7 @@ class TempLevelWidget(QtGui.QWidget): self._solder_changed) def _solder_changed(self): + print self._solder_changed self.solder_changed.emit() @@ -1066,6 +1012,10 @@ class ApplicationWindow(QtGui.QMainWindow): QtCore.Qt.CTRL + QtCore.Qt.Key_C) self.file_menu.addAction('&Save solder', self.save_solder, QtCore.Qt.CTRL + QtCore.Qt.Key_S) + self.file_menu.addAction('&Reload solder', self.reload_solder, + QtCore.Qt.CTRL + QtCore.Qt.Key_R) + self.file_menu.addAction('&Delete solder', self.remove_solder, + QtCore.Qt.CTRL + QtCore.Qt.Key_D) self.file_menu.addAction('S&ave plot', self.save_plot, QtCore.Qt.CTRL + QtCore.Qt.Key_A) self.file_menu.addAction('&Quit', self.fileQuit, @@ -1113,7 +1063,7 @@ class ApplicationWindow(QtGui.QMainWindow): self.temp_level_widget = TempLevelWidget(self) self.duration_widget = DurationConstraintWidget(u"Duration (s)") self.rate_widget = RateConstraintWidget(u"Rate (°C/s)") - self.tab_widget.addTab(self.temp_level_widget, u"Temperature Levels") + self.tab_widget.addTab(self.temp_level_widget, u"Temperature Levels (°C)") self.tab_widget.addTab(self.duration_widget, u"Duration (s)") self.tab_widget.addTab(self.rate_widget, u"Rate (°C/s)") @@ -1210,6 +1160,16 @@ class ApplicationWindow(QtGui.QMainWindow): self.controls_widget.temp_level_widget.setData(solder) solder.log_message.connect(self.profile_log.setPlainText) + def remove_solder(self): + index = self.solder_widget.solder_view.currentIndex() + solder = self.solder_widget.solder_model.listdata[index.row()] + del self.solder_widget.solder_model.listdata[index.row()] + self.solder_widget.solder_model.reset() + new_index = self.solder_widget.solder_model.index(0) + self.solder_widget.solder_view.setCurrentIndex(new_index) + self.solder_selected(new_index) + os.remove(solder.filename) + def open_controls_view(self): self.controls_widget.show() self.settings_widget.hide() @@ -1225,9 +1185,18 @@ class ApplicationWindow(QtGui.QMainWindow): self.plotter.print_figure(str(filename), dpi=self.dpi) def save_solder(self): - self.plotter.solder.save("foo") + self.plotter.solder.save() self.solder_widget.solder_model.reload() + def reload_solder(self): + old_index = self.solder_widget.solder_view.currentIndex() + solder = Solder.unpack(self.plotter.solder.filename, self.solder_widget.solder_model) + self.solder_widget.solder_model.listdata[old_index.row()] = solder + self.solder_widget.solder_model.reset() + new_index = self.solder_widget.solder_model.index(old_index.row(), 0) + self.solder_widget.solder_view.setCurrentIndex(new_index) + self.solder_selected(new_index) + def fileQuit(self): self.close() @@ -1243,6 +1212,12 @@ class ApplicationWindow(QtGui.QMainWindow): def main(): + # numpy bug workaround + try: + numpy.log10(0.0) + except: + pass + qApp = QtGui.QApplication(sys.argv) aw = ApplicationWindow()