source: orange/orange/OrangeWidgets/Data/OWDataTable.py @ 9546:2b6cc6f397fe

Revision 9546:2b6cc6f397fe, 26.1 KB checked in by ales_erjavec <ales.erjavec@…>, 2 years ago (diff)

Renamed widget channel names in line with the new naming rules/convention.
Added backwards compatibility in orngDoc loadDocument to enable loading of schemas saved before the change.

Line 
1"""
2<name>Data Table</name>
3<description>Shows data in a spreadsheet.</description>
4<icon>icons/DataTable.png</icon>
5<priority>100</priority>
6<contact>Peter Juvan (peter.juvan@fri.uni-lj.si)</contact>
7"""
8
9# OWDataTable.py
10#
11# wishes:
12# ignore attributes, filter examples by attribute values, do
13# all sorts of preprocessing (including discretization) on the table,
14# output a new table and export it in variety of formats.
15
16from OWWidget import *
17import OWGUI
18import math
19from orngDataCaching import *
20import OWColorPalette
21
22##############################################################################
23
24def safe_call(func):
25    from functools import wraps
26    @wraps(func)
27    def wrapper(*args, **kwargs):
28        try:
29            return func(*args, **kwargs)
30        except Exception, ex:
31            print >> sys.stderr, func.__name__, "call error", ex
32            return QVariant()
33    return wrapper
34   
35
36class ExampleTableModel(QAbstractItemModel):
37    def __init__(self, examples, dist, *args):
38        QAbstractItemModel.__init__(self, *args)
39        self.examples = examples
40        self.dist = dist
41        self.attributes = list(self.examples.domain.attributes)
42        self.classVar = self.examples.domain.classVar
43        self.metas = self.examples.domain.getmetas().values()
44        self.all_attrs = self.attributes + ([self.classVar] if self.classVar else []) + self.metas
45        self.clsColor = QColor(160,160,160)
46        self.metaColor = QColor(220,220,200)
47        self.sorted_map = range(len(self.examples))
48       
49        self.attrLabels = sorted(reduce(set.union, [attr.attributes for attr in self.all_attrs], set()))
50        self._other_data = {}
51       
52    showAttrLabels = pyqtProperty("bool", 
53                                  fget=lambda self: getattr(self, "_showAttrLabels", False),
54                                  fset=lambda self, val: (self.emit(SIGNAL("layoutAboutToBeChanged()")),
55                                                          setattr(self, "_showAttrLabels", val),
56                                                          self.emit(SIGNAL("headerDataChanged(Qt::Orientation, int, int)"), Qt.Horizontal, 0, len(self.all_attrs)-1),
57                                                          self.emit(SIGNAL("layoutChanged()")),
58                                                          self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.index(0,0),
59                                                                    self.index(len(self.examples) - 1, len(self.all_attrs) - 1))
60                                                          ) or None
61                                  )
62   
63    @safe_call
64    def data(self, index, role):
65        row, col = self.sorted_map[index.row()], index.column()
66        example, attr = self.examples[row], self.all_attrs[col]
67        val = example[attr]
68        domain = self.examples.domain
69        if role == Qt.DisplayRole:
70                return QVariant(str(val))
71        elif role == Qt.BackgroundRole:
72            if attr == self.classVar and col == len(domain.attributes) and domain.classVar: #check if attr is actual class or a duplication in the meta attributes
73                return QVariant(self.clsColor)
74            elif attr in self.metas:
75                return QVariant(self.metaColor)
76        elif role == OWGUI.TableBarItem.BarRole and val.varType == orange.VarTypes.Continuous \
77                    and not val.isSpecial() and attr not in self.metas:
78            dist = self.dist[col]
79            return QVariant((float(val) - dist.min) / (dist.max - dist.min or 1))
80        elif role == OWGUI.TableValueRole: # The actual value
81            return QVariant(val)
82        elif role == OWGUI.TableClassValueRole: # The class value for the row's example
83            return QVariant(example.get_class())
84        elif role == OWGUI.TableVariable: # The variable descriptor for column
85            return QVariant(val.variable)
86       
87        return self._other_data.get((index.row(), index.column(), role), QVariant())
88       
89    def setData(self, index, variant, role):
90        self._other_data[index.row(), index.column(), role] = variant
91        self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), index, index)
92       
93    def index(self, row, col, parent=QModelIndex()):
94        return self.createIndex(row, col, 0)
95   
96    def parent(self, index):
97        return QModelIndex()
98   
99    def rowCount(self, parent=QModelIndex()):
100        if parent.isValid():
101            return 0
102        else:
103            return max([len(self.examples)] + [row for row, _, _ in self._other_data.keys()])
104       
105    def columnCount(self, index=QModelIndex()):
106        return max([len(self.all_attrs)] + [col for _, col, _ in self._other_data.keys()])
107   
108    @safe_call
109    def headerData(self, section, orientation, role):
110        if orientation == Qt.Horizontal:
111            attr = self.all_attrs[section]
112            if role ==Qt.DisplayRole:
113                values = [attr.name] + ([str(attr.attributes.get(label, "")) for label in self.attrLabels] if self.showAttrLabels else [])
114                return QVariant("\n".join(values))
115            if role == Qt.ToolTipRole:
116                pairs = [(key, str(attr.attributes[key])) for key in self.attrLabels if key in attr.attributes]
117                tip = "<b>%s</b>" % attr.name
118                tip = "<br>".join([tip] + ["%s = %s" % pair for pair in pairs])
119                return QVariant(tip) 
120        else:
121            if role == Qt.DisplayRole:
122                return QVariant(section + 1)
123        return QVariant()
124   
125    def sort(self, column, order=Qt.AscendingOrder):
126        self.emit(SIGNAL("layoutAboutToBeChanged()"))
127        attr = self.all_attrs[column] 
128        values = [(ex[attr], i) for i, ex in enumerate(self.examples)]
129        values = sorted(values, key=lambda t: t[0] if not t[0].isSpecial() else sys.maxint, reverse=(order!=Qt.AscendingOrder))
130        self.sorted_map = [v[1] for v in values]
131        self.emit(SIGNAL("layoutChanged()"))
132        self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.index(0,0),
133                  self.index(len(self.examples) - 1, len(self.all_attrs) - 1))
134           
135
136class OWDataTable(OWWidget):
137    settingsList = ["showDistributions", "showMeta", "distColorRgb", "showAttributeLabels", "autoCommit", "selectedSchemaIndex", "colorByClass"]
138
139    def __init__(self, parent=None, signalManager = None):
140        OWWidget.__init__(self, parent, signalManager, "Data Table")
141
142        self.inputs = [("Data", ExampleTable, self.dataset, Multiple + Default)]
143        self.outputs = [("Selected Data", ExampleTable, Default), ("Other Data", ExampleTable)]
144
145        self.data = {}          # key: id, value: ExampleTable
146        self.showMetas = {}     # key: id, value: (True/False, columnList)
147        self.showMeta = 1
148        self.showAttributeLabels = 1
149        self.showDistributions = 1
150        self.distColorRgb = (220,220,220, 255)
151        self.distColor = QColor(*self.distColorRgb)
152        self.locale = QLocale()
153        self.autoCommit = False
154        self.colorSettings = None
155        self.selectedSchemaIndex = 0
156        self.colorByClass = True
157       
158        self.loadSettings()
159
160        # info box
161        infoBox = OWGUI.widgetBox(self.controlArea, "Info")
162        self.infoEx = OWGUI.widgetLabel(infoBox, 'No data on input.')
163        self.infoMiss = OWGUI.widgetLabel(infoBox, ' ')
164        OWGUI.widgetLabel(infoBox, ' ')
165        self.infoAttr = OWGUI.widgetLabel(infoBox, ' ')
166        self.infoMeta = OWGUI.widgetLabel(infoBox, ' ')
167        OWGUI.widgetLabel(infoBox, ' ')
168        self.infoClass = OWGUI.widgetLabel(infoBox, ' ')
169        infoBox.setMinimumWidth(200)
170        OWGUI.separator(self.controlArea)
171
172        # settings box
173        boxSettings = OWGUI.widgetBox(self.controlArea, "Settings", addSpace=True)
174        self.cbShowMeta = OWGUI.checkBox(boxSettings, self, "showMeta", 'Show meta attributes', callback = self.cbShowMetaClicked)
175        self.cbShowMeta.setEnabled(False)
176        self.cbShowAttLbls = OWGUI.checkBox(boxSettings, self, "showAttributeLabels", 'Show attribute labels (if any)', callback = self.cbShowAttLabelsClicked)
177        self.cbShowAttLbls.setEnabled(True)
178
179        box = OWGUI.widgetBox(self.controlArea, "Colors")
180        OWGUI.checkBox(box, self, "showDistributions", 'Visualize continuous values', callback = self.cbShowDistributions)
181        OWGUI.checkBox(box, self, "colorByClass", 'Color by class value', callback = self.cbShowDistributions)
182        OWGUI.button(box, self, "Set colors", self.setColors, tooltip = "Set the canvas background color and color palette for coloring continuous variables", debuggingEnabled = 0)
183
184        resizeColsBox = OWGUI.widgetBox(boxSettings, 0, "horizontal", 0)
185        OWGUI.label(resizeColsBox, self, "Resize columns: ")
186        OWGUI.toolButton(resizeColsBox, self, "+", self.increaseColWidth, tooltip = "Increase the width of the columns", width=20, height=20)
187        OWGUI.toolButton(resizeColsBox, self, "-", self.decreaseColWidth, tooltip = "Decrease the width of the columns", width=20, height=20)
188        OWGUI.rubber(resizeColsBox)
189
190        self.btnResetSort = OWGUI.button(boxSettings, self, "Restore Order of Examples", callback = self.btnResetSortClicked, tooltip = "Show examples in the same order as they appear in the file")
191       
192        OWGUI.separator(self.controlArea)
193        selectionBox = OWGUI.widgetBox(self.controlArea, "Selection")
194        self.sendButton = OWGUI.button(selectionBox, self, "Send selections", self.commit, default=True)
195        cb = OWGUI.checkBox(selectionBox, self, "autoCommit", "Commit on any change", callback=self.commitIf)
196        OWGUI.setStopper(self, self.sendButton, cb, "selectionChangedFlag", self.commit)
197
198        OWGUI.rubber(self.controlArea)
199
200        dlg = self.createColorDialog()
201        self.discPalette = dlg.getDiscretePalette("discPalette")
202
203        # GUI with tabs
204        self.tabs = OWGUI.tabWidget(self.mainArea)
205        self.id2table = {}  # key: widget id, value: table
206        self.table2id = {}  # key: table, value: widget id
207        self.connect(self.tabs, SIGNAL("currentChanged(QWidget*)"), self.tabClicked)
208       
209        self.selectionChangedFlag = False
210       
211
212    def createColorDialog(self):
213        c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
214        c.createDiscretePalette("discPalette", "Discrete Palette")
215        box = c.createBox("otherColors", "Other Colors")
216        c.createColorButton(box, "Default", "Default color", QColor(Qt.white))
217        c.setColorSchemas(self.colorSettings, self.selectedSchemaIndex)
218        return c
219
220    def setColors(self):
221        dlg = self.createColorDialog()
222        if dlg.exec_():
223            self.colorSettings = dlg.getColorSchemas()
224            self.selectedSchemaIndex = dlg.selectedSchemaIndex
225            self.discPalette = dlg.getDiscretePalette("discPalette")
226            self.distColorRgb = dlg.getColor("Default")
227
228    def increaseColWidth(self):
229        table = self.tabs.currentWidget()
230        if table:
231            for col in range(table.model().columnCount(QModelIndex())):
232                w = table.columnWidth(col)
233                table.setColumnWidth(col, w + 10)
234
235    def decreaseColWidth(self):
236        table = self.tabs.currentWidget()
237        if table:
238            for col in range(table.model().columnCount(QModelIndex())):
239                w = table.columnWidth(col)
240                minW = table.sizeHintForColumn(col)
241                table.setColumnWidth(col, max(w - 10, minW))
242
243
244    def dataset(self, data, id=None):
245        """Generates a new table and adds it to a new tab when new data arrives;
246        or hides the table and removes a tab when data==None;
247        or replaces the table when new data arrives together with already existing id."""
248        if data != None:  # can be an empty table!
249            if self.data.has_key(id):
250                # remove existing table
251                self.data.pop(id)
252                self.showMetas.pop(id)
253                self.id2table[id].hide()
254                self.tabs.removeTab(self.tabs.indexOf(self.id2table[id]))
255                self.table2id.pop(self.id2table.pop(id))
256            self.data[id] = data
257            self.showMetas[id] = (True, [])
258
259            table = QTableView()
260            table.setSelectionBehavior(QAbstractItemView.SelectRows)
261            table.setSortingEnabled(True)
262            table.setHorizontalScrollMode(QTableWidget.ScrollPerPixel)
263            table.horizontalHeader().setMovable(True)
264            table.horizontalHeader().setClickable(True)
265            table.horizontalHeader().setSortIndicatorShown(False)
266           
267            option = table.viewOptions()
268            size = table.style().sizeFromContents(QStyle.CT_ItemViewItem, option, QSize(20, 20), table) #QSize(20, QFontMetrics(option.font).lineSpacing()), table)
269           
270            table.verticalHeader().setDefaultSectionSize(size.height() + 2) #int(size.height() * 1.25) + 2)
271
272            self.id2table[id] = table
273            self.table2id[table] = id
274            if data.name:
275                tabName = "%s " % data.name
276            else:
277                tabName = ""
278            tabName += "(" + str(id[1]) + ")"
279            if id[2] != None:
280                tabName += " [" + str(id[2]) + "]"
281            self.tabs.addTab(table, tabName)
282
283            self.progressBarInit()
284            self.setTable(table, data)
285            self.progressBarFinished()
286            self.tabs.setCurrentIndex(self.tabs.indexOf(table))
287            self.setInfo(data)
288            self.sendButton.setEnabled(not self.autoCommit)
289
290        elif self.data.has_key(id):
291            table = self.id2table[id]
292            self.data.pop(id)
293            self.showMetas.pop(id)
294            table.hide()
295            self.tabs.removeTab(self.tabs.indexOf(table))
296            self.table2id.pop(self.id2table.pop(id))
297            self.setInfo(self.data.get(self.table2id.get(self.tabs.currentWidget(),None),None))
298
299        if len(self.data) == 0:
300            self.sendButton.setEnabled(False)
301
302        self.setCbShowMeta()
303
304    def setCbShowMeta(self):
305        for ti in range(self.tabs.count()):
306            if len(self.tabs.widget(ti).model().metas)>0:
307                self.cbShowMeta.setEnabled(True)
308                break
309        else:
310            self.cbShowMeta.setEnabled(False)
311           
312    def sendReport(self):
313        qTableInstance = self.tabs.currentWidget()
314        id = self.table2id.get(qTableInstance, None)
315        data = self.data.get(id, None)
316        self.reportData(data)
317        table = self.id2table[id]
318        import OWReport
319        self.reportRaw(OWReport.reportTable(table))
320       
321       
322    # Writes data into table, adjusts the column width.
323    def setTable(self, table, data):
324        if data==None:
325            return
326        qApp.setOverrideCursor(Qt.WaitCursor)
327        vars = data.domain.variables
328        m = data.domain.getmetas(False)
329        ml = [(k, m[k]) for k in m]
330        ml.sort(lambda x,y: cmp(y[0], x[0]))
331        metas = [x[1] for x in ml]
332        metaKeys = [x[0] for x in ml]
333
334        mo = data.domain.getmetas(True).items()
335        if mo:
336            mo.sort(lambda x,y: cmp(x[1].name.lower(),y[1].name.lower()))
337            metas.append(None)
338            metaKeys.append(None)
339
340        varsMetas = vars + metas
341
342        numVars = len(data.domain.variables)
343        numMetas = len(metas)
344        numVarsMetas = numVars + numMetas
345        numEx = len(data)
346        numSpaces = int(math.log(max(numEx,1), 10))+1
347
348#        table.clear()
349        table.oldSortingIndex = -1
350        table.oldSortingOrder = 1
351#        table.setColumnCount(numVarsMetas)
352#        table.setRowCount(numEx)
353
354        dist = getCached(data, orange.DomainBasicAttrStat, (data,))
355       
356        datamodel = ExampleTableModel(data, dist, self)
357       
358#        proxy = QSortFilterProxyModel(self)
359#        proxy.setSourceModel(datamodel)
360       
361        color_schema = self.discPalette if self.colorByClass else None
362        table.setItemDelegate(OWGUI.TableBarItem(self, color=self.distColor, color_schema=color_schema) \
363                              if self.showDistributions else QStyledItemDelegate(self)) #TableItemDelegate(self, table))
364       
365        table.setModel(datamodel)
366        def p():
367            try:
368                table.updateGeometries()
369                table.viewport().update()
370            except RuntimeError:
371                pass
372       
373        size = table.verticalHeader().sectionSizeHint(0)
374        table.verticalHeader().setDefaultSectionSize(size)
375       
376        self.connect(datamodel, SIGNAL("layoutChanged()"), lambda *args: QTimer.singleShot(50, p))
377       
378        id = self.table2id.get(table, None)
379
380        # set the header (attribute names)
381
382        self.drawAttributeLabels(table)
383
384        self.showMetas[id][1].extend([i for i, attr in enumerate(table.model().all_attrs) if attr in table.model().metas])
385        self.connect(table.horizontalHeader(), SIGNAL("sectionClicked(int)"), self.sortByColumn)
386        self.connect(table.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.updateSelection)
387        #table.verticalHeader().setMovable(False)
388
389        qApp.restoreOverrideCursor() 
390
391    def setCornerText(self, table, text):
392        """
393        Set table corner text. As this is an ugly hack, do everything in
394        try - except blocks, as it may stop working in newer Qt.
395        """
396
397        if not hasattr(table, "btn") and not hasattr(table, "btnfailed"):
398            try:
399                btn = table.findChild(QAbstractButton)
400
401                class efc(QObject):
402                    def eventFilter(self, o, e):
403                        if (e.type() == QEvent.Paint):
404                            if isinstance(o, QAbstractButton):
405                                btn = o
406                                #paint by hand (borrowed from QTableCornerButton)
407                                opt = QStyleOptionHeader()
408                                opt.init(btn)
409                                state = QStyle.State_None;
410                                if (btn.isEnabled()):
411                                    state |= QStyle.State_Enabled;
412                                if (btn.isActiveWindow()):
413                                    state |= QStyle.State_Active;
414                                if (btn.isDown()):
415                                    state |= QStyle.State_Sunken;
416                                opt.state = state;
417                                opt.rect = btn.rect();
418                                opt.text = btn.text();
419                                opt.position = QStyleOptionHeader.OnlyOneSection;
420                                painter = QStylePainter(btn);
421                                painter.drawControl(QStyle.CE_Header, opt);
422                                return True # eat evebt
423                        return False
424               
425                table.efc = efc()
426                btn.installEventFilter(table.efc)
427                table.btn = btn
428            except:
429                table.btnfailed = True
430
431        if hasattr(table, "btn"):
432            try:
433                btn = table.btn
434                btn.setText(text)
435                opt = QStyleOptionHeader()
436                opt.text = btn.text()
437                s = btn.style().sizeFromContents(QStyle.CT_HeaderSection, opt, QSize(), btn).expandedTo(QApplication.globalStrut())
438                if s.isValid():
439                    table.verticalHeader().setMinimumWidth(s.width())
440                   
441            except:
442                pass
443
444    def sortByColumn(self, index):
445        table = self.tabs.currentWidget()
446        table.horizontalHeader().setSortIndicatorShown(1)
447        header = table.horizontalHeader()
448        if index == table.oldSortingIndex:
449            order = table.oldSortingOrder == Qt.AscendingOrder and Qt.DescendingOrder or Qt.AscendingOrder
450        else:
451            order = Qt.AscendingOrder
452        table.sortByColumn(index, order)
453        table.oldSortingIndex = index
454        table.oldSortingOrder = order
455        #header.setSortIndicator(index, order)
456
457    def tabClicked(self, qTableInstance):
458        """Updates the info box and showMetas checkbox when a tab is clicked.
459        """
460        id = self.table2id.get(qTableInstance,None)
461        self.setInfo(self.data.get(id,None))
462        show_col = self.showMetas.get(id,None)
463        if show_col:
464            self.cbShowMeta.setChecked(show_col[0])
465            self.cbShowMeta.setEnabled(len(show_col[1])>0)
466        self.updateSelection()
467
468    def cbShowMetaClicked(self):
469        table = self.tabs.currentWidget()
470        id = self.table2id.get(table, None)
471        if self.showMetas.has_key(id):
472            show,col = self.showMetas[id]
473            self.showMetas[id] = (not show,col)
474        if show:
475            for c in col:
476                table.hideColumn(c)
477        else:
478            for c in col:
479                table.showColumn(c)
480                table.resizeColumnToContents(c)
481
482    def drawAttributeLabels(self, table):
483#        table.setHorizontalHeaderLabels(table.variableNames)
484        table.model().showAttrLabels = bool(self.showAttributeLabels)
485        if self.showAttributeLabels:
486            labelnames = set()
487            for a in table.model().examples.domain:
488                labelnames.update(a.attributes.keys())
489            labelnames = sorted(list(labelnames))
490#            if len(labelnames):
491#                table.setHorizontalHeaderLabels([table.variableNames[i] + "\n" + "\n".join(["%s" % a.attributes.get(lab, "") for lab in labelnames]) for (i, a) in enumerate(table.data.domain.attributes)])
492            self.setCornerText(table, "\n".join([""] + labelnames))
493        else:
494            self.setCornerText(table, "")
495        table.repaint()
496
497    def cbShowAttLabelsClicked(self):
498        for table in self.table2id.keys():
499            self.drawAttributeLabels(table)
500
501    def cbShowDistributions(self):
502        for ti in range(self.tabs.count()):
503            color_schema = self.discPalette if self.colorByClass else None
504            delegate = OWGUI.TableBarItem(self, color=self.distColor,
505                                          color_schema=color_schema) \
506                       if self.showDistributions else QStyledItemDelegate(self)
507            self.tabs.widget(ti).setItemDelegate(delegate)
508        tab = self.tabs.currentWidget()
509        if tab:
510            tab.reset()
511
512    # show data in the default order
513    def btnResetSortClicked(self):
514        table = self.tabs.currentWidget()
515        if table:
516            id = self.table2id[table]
517            data = self.data[id]
518            table.horizontalHeader().setSortIndicatorShown(False)
519            self.progressBarInit()
520            self.setTable(table, data)
521            self.progressBarFinished()
522
523    def setInfo(self, data):
524        """Updates data info.
525        """
526        def sp(l, capitalize=False):
527            n = len(l)
528            if n == 0:
529                if capitalize:
530                    return "No", "s"
531                else:
532                    return "no", "s"
533            elif n == 1:
534                return str(n), ''
535            else:
536                return str(n), 's'
537
538        if data == None:
539            self.infoEx.setText('No data on input.')
540            self.infoMiss.setText('')
541            self.infoAttr.setText('')
542            self.infoMeta.setText('')
543            self.infoClass.setText('')
544        else:
545            self.infoEx.setText("%s example%s," % sp(data))
546            missData = orange.Preprocessor_takeMissing(data)
547            self.infoMiss.setText('%s (%.1f%s) with missing values.' % (len(missData), len(data) and 100.*len(missData)/len(data), "%"))
548            self.infoAttr.setText("%s attribute%s," % sp(data.domain.attributes,True))
549            self.infoMeta.setText("%s meta attribute%s." % sp(data.domain.getmetas()))
550            if data.domain.classVar:
551                if data.domain.classVar.varType == orange.VarTypes.Discrete:
552                    self.infoClass.setText('Discrete class with %s value%s.' % sp(data.domain.classVar.values))
553                elif data.domain.classVar.varType == orange.VarTypes.Continuous:
554                    self.infoClass.setText('Continuous class.')
555                else:
556                    self.infoClass.setText("Class is neither discrete nor continuous.")
557            else:
558                self.infoClass.setText('Classless domain.')
559
560    def updateSelection(self, *args):
561        self.sendButton.setEnabled(bool(self.getCurrentSelection()) and not self.autoCommit)
562        self.commitIf()
563           
564    def getCurrentSelection(self):
565        table = self.tabs.currentWidget()
566        if table and table.model():
567            model = table.model()
568            new = table.selectionModel().selectedIndexes()
569            return sorted(set([model.sorted_map[ind.row()] for ind in new]))
570       
571    def commitIf(self):
572        if self.autoCommit:
573            self.commit()
574        else:
575            self.selectionChangedFlag = True
576           
577    def commit(self):
578        table = self.tabs.currentWidget()
579        if table and table.model():
580            model = table.model()
581            selected = self.getCurrentSelection()
582            selection = [1 if i in selected else 0 for i in range(len(model.examples))]
583            data = model.examples.select(selection)
584            self.send("Selected Data", data if len(data) > 0 else None)
585            data = model.examples.select(selection, 0)
586            self.send("Other Data", data if len(data) > 0 else None)
587        else:
588            self.send("Selected Data", None)
589            self.send("Other Data", None)
590           
591        self.selectionChangedFlag = False
592           
593       
594
595if __name__=="__main__":
596    a = QApplication(sys.argv)
597    ow = OWDataTable()
598
599    #d1 = orange.ExampleTable(r'..\..\doc\datasets\auto-mpg')
600    #d2 = orange.ExampleTable('test-labels')
601    #d3 = orange.ExampleTable(r'..\..\doc\datasets\sponge.tab')
602    #d4 = orange.ExampleTable(r'..\..\doc\datasets\wpbc.csv')
603    d5 = orange.ExampleTable('../../doc/datasets/adult_sample.tab')
604    #d5 = orange.ExampleTable(r"E:\Development\Orange Datasets\UCI\wine.tab")
605#    d5 = orange.ExampleTable("adult_sample")
606#    d5 = orange.ExampleTable("/home/marko/tdw")
607    #d5 = orange.ExampleTable(r"e:\Development\Orange Datasets\Cancer\SRBCT.tab")
608    ow.show()
609    #ow.dataset(d1,"auto-mpg")
610    #ow.dataset(d2,"voting")
611    #ow.dataset(d4,"wpbc")
612    ow.dataset(d5,"adult_sample")
613    a.exec_()
614    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.