コード例 #1
0
ファイル: customtableview.py プロジェクト: gem/qt-experiments
class ExposureWidget(QtGui.QWidget):
    table_attrs = [
        {'addBtn': 0, 'delBtn': 0, 'viewclass': CustomTableView},
        {'addBtn': 1, 'delBtn': 1, 'viewclass': CustomTableView},
        {'addBtn': 1, 'delBtn': 1, 'viewclass': CustomTableView},
        {'addBtn': 1, 'delBtn': 1, 'viewclass': CustomTableView},
        {'addBtn': 1, 'delBtn': 1, 'viewclass': CustomTableView},
        {'addBtn': 1, 'delBtn': 1, 'viewclass': CustomTableView},
    ]

    def __init__(self, tableset, nrmlfile, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.tableset = tableset
        self.nrmlfile = nrmlfile
        self.message_bar = MessageBar(nrmlfile, self)
        self.tables = [tableset.tableExposure,
                       tableset.tableCostType,
                       tableset.tableLocation,
                       tableset.tableAsset,
                       tableset.tableCost,
                       tableset.tableOccupancy]
        self.tv = collections.OrderedDict()
        for table, attr in zip(self.tables, self.table_attrs):
            table.attr.update(attr)
            tv = attr['viewclass'](table, self.getdefault)
            if len(table) == 0:  # hide empty tables
                tv.hide()
            tv.tableModel.validationFailed.connect(
                lambda idx, err, tv=tv:
                self.show_validation_error(tv, idx, err))
            self.tv[table.name] = tv
        self.setupUi()

        self.tv['tableLocation'].tableView.clicked.connect(
            self.show_asset)
        self.tv['tableAsset'].tableView.clicked.connect(
            self.show_cost_occupancy)

    def setupUi(self):
        layout = QtGui.QVBoxLayout()
        hlayout1 = QtGui.QHBoxLayout()
        hlayout2 = QtGui.QHBoxLayout()
        layout.addWidget(self.message_bar)
        hlayout1.addWidget(self.tv['tableExposure'])
        hlayout1.addWidget(self.tv['tableCostType'])
        hlayout1.addWidget(self.tv['tableLocation'])
        layout.addLayout(hlayout1)
        hlayout2.addWidget(self.tv['tableAsset'])
        hlayout2.addWidget(self.tv['tableCost'])
        hlayout2.addWidget(self.tv['tableOccupancy'])
        layout.addLayout(hlayout2)
        self.setLayout(layout)
        self.setSizePolicy(
            QtGui.QSizePolicy.MinimumExpanding,
            QtGui.QSizePolicy.MinimumExpanding)

        self.tv['tableAsset'].tableView.hideColumn(0)
        self.tv['tableCost'].tableView.hideColumn(0)
        self.tv['tableOccupancy'].tableView.hideColumn(0)
        self.tv['tableLocation'].tableView.hideColumn(0)

        self.show_asset(index(0, 0))
        self.show_cost_occupancy(index(0, 0))

    @QtCore.pyqtSlot(QtCore.QModelIndex, Exception)
    def show_validation_error(self, table_view, index, error):
        record = table_view.tableModel.table[index.row()]
        fieldname = record.fields[index.column()].name
        message = '%s: %s' % (fieldname, error)
        self.message_bar.show_message(message)

    def show_asset(self, row):
        # show only the assets at the given location
        try:
            loc_id, = self.tv['tableLocation'].tableModel.primaryKey(row)
        except IndexError:  # empty table, nothing to show
            return
        self.tv['tableAsset'].showOnCondition(
            lambda rec: rec['location_id'] == loc_id)

        # reset Cost and Occupancy
        self.tv['tableCost'].showOnCondition(lambda rec: False)
        self.tv['tableOccupancy'].showOnCondition(lambda rec: False)

    def show_cost_occupancy(self, row):
        try:
            asset_ref, = self.tv['tableAsset'].tableModel.primaryKey(row)
        except IndexError:  # empty table, nothing to show
            return
        # show only the rows corresponding to asset_ref
        self.tv['tableCost'].showOnCondition(
            lambda rec: rec['asset_ref'] == asset_ref)
        # show only the rows corresponding to asset_ref
        self.tv['tableOccupancy'].showOnCondition(
            lambda rec: rec['asset_ref'] == asset_ref)

    def getdefault(self, table):
        if table.name == 'tableAsset':
            return self.tv['tableLocation'].current_record()[:1]
        elif table.name in ('tableCost', 'tableOccupancy'):
            return [self.tv['tableAsset'].current_record()[1]]
        else:
            return []
コード例 #2
0
ファイル: customtableview.py プロジェクト: gem/qt-experiments
class TripleTableWidget(QtGui.QWidget):
    table_attrs = [
        {'addBtn': 1, 'delBtn': 1},
        {'addBtn': 1, 'delBtn': 1},
        {'addBtn': 1, 'delBtn': 1},
    ]

    def __init__(self, tableset, nrmlfile, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.tableset = tableset
        self.nrmlfile = nrmlfile
        self.message_bar = MessageBar(nrmlfile, self)
        self.init_tv()  # this goes before setupUi
        self.setupUi()

    def init_tv(self):
        self.tv = collections.OrderedDict()
        n_attrs = len(self.table_attrs)
        n_tables = len(self.tableset.tables)
        if n_attrs != n_tables:
            raise RuntimeError('There are %d tables but %d table attributes!' %
                               (n_tables, n_attrs))
        for i, (attr, table) in enumerate(
                zip(self.table_attrs, self.tableset.tables)):
            table.attr.update(attr)
            self.tv[table.name] = CustomTableView(table, self.getdefault, self)
            self.tv[i] = self.tv[table.name]

        # signals
        self.tv[LEFT].tableView.clicked.connect(self.show_right)
        self.tv[RIGHT].tableView.clicked.connect(self.show_down)
        for tv in self.tv.values():
            tv.tableModel.validationFailed.connect(
                lambda idx, err, tv=tv:
                self.show_validation_error(tv, idx, err))

        # hide primary key columns
        self.tv[RIGHT].tableView.hideColumn(0)
        self.tv[DOWN].tableView.hideColumn(0)
        self.tv[DOWN].tableView.hideColumn(1)

    def getdefault(self, table):
        # return the primary key tuple partially filled, depending on
        # the currently selected rows
        ordinal = table.ordinal
        if not ordinal:  # top left table
            return []
        return self.tv[ordinal - 1].current_record()[:ordinal]

    def plot(self, records, x_field, y_field, label):
        can_plot = Figure and records
        if can_plot:
            xs = [rec[x_field] for rec in records]
            ys = [rec[y_field] for rec in records]
            self.axes.clear()
            self.axes.grid(True)
            self.axes.plot(xs, ys, label=label)
            self.axes.legend(loc='upper left')
            self.canvas.draw()

    def reset_plot(self):
        if Figure:
            self.axes.clear()
            self.axes.grid(True)
            self.canvas.draw()

    def setupUi(self):
        layout = QtGui.QVBoxLayout()
        hlayout1 = QtGui.QHBoxLayout()
        hlayout2 = QtGui.QHBoxLayout()
        layout.addWidget(self.message_bar)
        hlayout1.addWidget(self.tv[LEFT])
        hlayout1.addWidget(self.tv[RIGHT])
        layout.addLayout(hlayout1)
        hlayout2.addWidget(self.tv[DOWN])
        if Figure:  # matplotlib is available
            self.fig = Figure()
            self.axes = self.fig.add_subplot(111)
            self.canvas = FigureCanvasQTAgg(self.fig)
            self.canvas.setParent(self)
            hlayout2.addWidget(self.canvas)
        layout.addLayout(hlayout2)
        self.setLayout(layout)
        self.setSizePolicy(
            QtGui.QSizePolicy.MinimumExpanding,
            QtGui.QSizePolicy.MinimumExpanding)

        # display table 1 and table 2 as if rows 0 and 0 where selected
        self.show_right(index(0, 0))
        self.show_down(index(0, 0))

    @QtCore.pyqtSlot(QtCore.QModelIndex, Exception)
    def show_validation_error(self, table_view, index, error):
        record = table_view.tableModel.table[index.row()]
        fieldname = record.fields[index.column()].name
        message = '%s: %s' % (fieldname, error)
        self.message_bar.show_message(message)

    def show_right(self, index):
        try:
            k0, = self.tv[LEFT].tableModel.primaryKey(index)
        except IndexError:  # empty table, nothing to show
            return
        # show only the rows in table 1 corresponding to k0
        self.tv[RIGHT].showOnCondition(lambda rec: rec[0] == k0)
        # table 2 must disappear because no index in table 1 is selected
        self.tv[DOWN].showOnCondition(lambda rec: False)
        self.reset_plot()

    def show_down(self, index):
        # show only the rows in table 2 corresponding to k0 and k1
        try:
            k0, k1 = self.tv[RIGHT].tableModel.primaryKey(index)
        except IndexError:  # empty table, nothing to show
            return
        self.tv[DOWN].showOnCondition(
            lambda rec: rec[0] == k0 and rec[1] == k1)
        self.plot([rec for rec in self.tableset.tables[2]
                   if rec[0] == k0 and rec[1] == k1],
                  'IML', 'lossRatio', '%s-%s' % (k0, k1))