def updateObjectFilter(self): # -- Add message filter rows -- # font = self.getFont() self.filterTabs.clear() self.filterTabs.addTab(self.filterTable, 'Information ID') # For each object in objectList, create a new Table and add it to the tabs. for keys, values in Globals.objectDict.items(): objectFilterTable = QTableWidget() objectFilterTable.setRowCount(0) objectFilterTable.setColumnCount(2) strSplit = keys + ';Enable' objectFilterTable.setHorizontalHeaderLabels(strSplit.split(';')) objectFilterTable.resizeColumnsToContents() filterTableHeader = objectFilterTable.horizontalHeader() filterTableHeader.setSectionResizeMode(0, QHeaderView.Stretch) filterTableHeader.setSectionResizeMode( 1, QHeaderView.ResizeToContents) checkBoxFilter = self.createCheckBox() objectFilterTable.itemChanged.connect( lambda *a, table=objectFilterTable: self.filterAllObjectIDs( *a, table=table)) objectTableIndex = 0 objectFilterTable.insertRow(objectTableIndex) objCat = QTableWidgetItem('FILTER ALL') objCat.setFont(font) objectFilterTable.setItem(objectTableIndex, 0, objCat) objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter) objectTableIndex = objectTableIndex + 1 for keys2, values2 in values.items(): objectFilterTable.insertRow(objectTableIndex) checkBoxFilter = self.createCheckBox() objectFilterTable.setItem( objectTableIndex, 0, QTableWidgetItem('ID: ' + str(keys2) + ' Name: ' + str(values2))) objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter) objectTableIndex = objectTableIndex + 1 # Add the newly create table to the tabs. self.filterTabs.addTab(objectFilterTable, keys) self.objectTabDict[keys] = objectFilterTable
class ModelGroupsTable(QWidget): EditableAttrs = [ attr for attr in PlotStyles.StyleAttributes if attr in PlotStyles.StyleAttributeOptions ] ColList = 3 ColPlot = 4 ColApply = 5 AttrByCol = dict([(i + 6, attr) for i, attr in enumerate(EditableAttrs)]) def __init__(self, parent, *args): QWidget.__init__(self, parent, *args) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) lo = QVBoxLayout(self) lo.setContentsMargins(0, 0, 0, 0) lo1 = QHBoxLayout() lo.addLayout(lo1) lo1.setContentsMargins(0, 0, 0, 0) lbl = QLabel(QString("<nobr><b>Source groupings:</b></nobr>"), self) lo1.addWidget(lbl, 0) lo1.addStretch(1) # add show/hide button self._showattrbtn = QPushButton(self) self._showattrbtn.setMinimumWidth(256) lo1.addWidget(self._showattrbtn, 0) lo1.addStretch() self._showattrbtn.clicked.connect(self._togglePlotControlsVisibility) # add table self.table = QTableWidget(self) lo.addWidget(self.table) self.table.cellChanged[int, int].connect(self._valueChanged) self.table.setSelectionMode(QTableWidget.NoSelection) # setup basic columns self.table.setColumnCount(6 + len(self.EditableAttrs)) for i, label in enumerate( ("grouping", "total", "selection", "list", "plot", "style")): self.table.setHorizontalHeaderItem(i, QTableWidgetItem(label)) self.table.horizontalHeader().setSectionHidden(self.ColApply, True) # setup columns for editable grouping attributes for i, attr in self.AttrByCol.items(): self.table.setHorizontalHeaderItem( i, QTableWidgetItem(PlotStyles.StyleAttributeLabels[attr])) self.table.horizontalHeader().setSectionHidden(i, True) self.table.verticalHeader().hide() # other internal init self._attrs_shown = False self._togglePlotControlsVisibility() self.model = None self._setting_model = False self._currier = PersistentCurrier() # row of 'selected' grouping self._irow_selgroup = 0 def clear(self): self.table.setRowCount(0) self.model = None # setup mappings from the group.show_plot attribute to check state ShowAttrToCheckState = { PlotStyles.ShowNot: Qt.Unchecked, PlotStyles.ShowDefault: Qt.PartiallyChecked, PlotStyles.ShowAlways: Qt.Checked } CheckStateToShowAttr = dict([(val, key) for key, val in ShowAttrToCheckState.items()]) def _makeCheckItem(self, name, group, attr): item = QTableWidgetItem(name) if group is self.model.defgroup: item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) item.setCheckState( Qt.Checked if getattr(group.style, attr) else Qt.Unchecked) else: item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsTristate) item.setCheckState(self.ShowAttrToCheckState[getattr( group.style, attr)]) return item def _updateModel(self, what=SkyModel.UpdateAll, origin=None): if origin is self or not what & (SkyModel.UpdateTags | SkyModel.UpdateGroupStyle): return model = self.model self._setting_model = True # to ignore cellChanged() signals (in valueChanged()) # _item_cb is a dict (with row,col keys) containing the widgets (CheckBoxes ComboBoxes) per each cell self._item_cb = {} # lists of "list" and "plot" checkboxes per each grouping (excepting the default grouping); each entry is an (row,col,item) tuple. # used as argument to self._showControls() self._list_controls = [] self._plot_controls = [] # list of selection callbacks (to which signals are connected) self._callbacks = [] # set requisite number of rows,and start filling self.table.setRowCount(len(model.groupings)) for irow, group in enumerate(model.groupings): self.table.setItem(irow, 0, QTableWidgetItem(group.name)) if group is model.selgroup: self._irow_selgroup = irow # total # source in group: skip for "current" if group is not model.curgroup: self.table.setItem(irow, 1, QTableWidgetItem(str(group.total))) # selection controls: skip for current and selection if group not in (model.curgroup, model.selgroup): btns = QWidget() lo = QHBoxLayout(btns) lo.setContentsMargins(0, 0, 0, 0) lo.setSpacing(0) # make selector buttons (depending on which group we're in) if group is model.defgroup: Buttons = (("+", lambda src, grp=group: True, "select all sources"), ("-", lambda src, grp=group: False, "unselect all sources")) else: Buttons = ( ("=", lambda src, grp=group: grp.func(src), "select only this grouping"), ("+", lambda src, grp=group: src.selected or grp.func(src), "add grouping to selection"), ("-", lambda src, grp=group: src.selected and not grp. func(src), "remove grouping from selection"), ("&&", lambda src, grp=group: src.selected and grp.func(src), "intersect selection with grouping")) lo.addStretch(1) for label, predicate, tooltip in Buttons: btn = QToolButton(btns) btn.setText(label) btn.setMinimumWidth(24) btn.setMaximumWidth(24) btn.setToolTip(tooltip) lo.addWidget(btn) # add callback btn.clicked.connect( self._currier.curry(self.selectSources, predicate)) lo.addStretch(1) self.table.setCellWidget(irow, 2, btns) # "list" checkbox (not for current and selected groupings: these are always listed) if group not in (model.curgroup, model.selgroup): item = self._makeCheckItem("", group, "show_list") self.table.setItem(irow, self.ColList, item) item.setToolTip( """<P>If checked, sources in this grouping will be listed in the source table. If un-checked, sources will be excluded from the table. If partially checked, then the default list/no list setting of "all sources" will be in effect. </P>""") # "plot" checkbox (not for the current grouping, since that's always plotted) if group is not model.curgroup: item = self._makeCheckItem("", group, "show_plot") self.table.setItem(irow, self.ColPlot, item) item.setToolTip( """<P>If checked, sources in this grouping will be included in the plot. If un-checked, sources will be excluded from the plot. If partially checked, then the default plot/no plot setting of "all sources" will be in effect. </P>""") # custom style control # for default, current and selected, this is just a text label if group is model.defgroup: item = QTableWidgetItem("default:") item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setToolTip( """<P>This is the default plot style used for all sources for which a custom grouping style is not selected.</P>""" ) self.table.setItem(irow, self.ColApply, item) elif group is model.curgroup: item = QTableWidgetItem("") item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setToolTip( """<P>This is the plot style used for the highlighted source, if any.</P>""" ) self.table.setItem(irow, self.ColApply, item) elif group is model.selgroup: item = QTableWidgetItem("") item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setToolTip( """<P>This is the plot style used for the currently selected sources.</P>""" ) self.table.setItem(irow, self.ColApply, item) # for the rest, a combobox with custom priorities else: cb = QComboBox() cb.addItems(["default"] + ["custom %d" % p for p in range(1, 10)]) index = max(0, min(group.style.apply, 9)) # dprint(0,group.name,"apply",index) cb.setCurrentIndex(index) cb.activated[int].connect( self._currier.xcurry(self._valueChanged, (irow, self.ColApply))) self.table.setCellWidget(irow, self.ColApply, cb) cb.setToolTip( """<P>This controls whether sources within this group are plotted with a customized plot style. Customized styles have numeric priority; if a source belongs to multiple groups, then the style with the lowest priority takes precedence.<P>""") # attribute comboboxes for icol, attr in self.AttrByCol.items(): # get list of options for this style attribute. If dealing with first grouping (i==0), which is # the "all sources" grouping, then remove the "default" option (which is always first in the list) options = PlotStyles.StyleAttributeOptions[attr] if irow == 0: options = options[1:] # make combobox cb = QComboBox() cb.addItems(list(map(str, options))) # the "label" option is also editable if attr == "label": cb.setEditable(True) try: index = options.index(getattr(group.style, attr)) cb.setCurrentIndex(index) except ValueError: cb.setEditText(str(getattr(group.style, attr))) slot = self._currier.xcurry(self._valueChanged, (irow, icol)) cb.activated[int].connect(slot) cb.editTextChanged['QString'].connect(slot) cb.setEnabled(group is model.defgroup or group.style.apply) self.table.setCellWidget(irow, icol, cb) label = attr if irow: cb.setToolTip( """<P>This is the %s used to plot sources in this group, when a "custom" style for the group is enabled via the style control.<P>""" % label) else: cb.setToolTip( "<P>This is the default %s used for all sources for which a custom style is not specified below.<P>" % label) self.table.resizeColumnsToContents() # re-enable processing of cellChanged() signals self._setting_model = False def setModel(self, model): self.model = model self.model.connect("updated", self._updateModel) self.model.connect("selected", self.updateModelSelection) self._updateModel(SkyModel.UpdateAll) def _valueChanged(self, row, col): """Called when a cell has been edited""" if self._setting_model: return group = self.model.groupings[row] item = self.table.item(row, col) if col == self.ColList: if group is not self.model.defgroup: # tri-state items go from unchecked to checked when user clicks them. Make them partially checked instead. if group.style.show_list == PlotStyles.ShowNot and item.checkState( ) == Qt.Checked: item.setCheckState(Qt.PartiallyChecked) group.style.show_list = self.CheckStateToShowAttr[ item.checkState()] self.model.emitChangeGroupingVisibility(group, origin=self) return elif col == self.ColPlot: if group is not self.model.defgroup: # tri-state items go from unchecked to checked by default. Make them partially checked instead. if group.style.show_plot == PlotStyles.ShowNot and item.checkState( ) == Qt.Checked: item.setCheckState(Qt.PartiallyChecked) group.style.show_plot = self.CheckStateToShowAttr[ item.checkState()] elif col == self.ColApply: group.style.apply = self.table.cellWidget(row, col).currentIndex() # enable/disable editable cells for j in list(self.AttrByCol.keys()): item1 = self.table.item(row, j) if item1: fl = item1.flags() & ~Qt.ItemIsEnabled if group.style.apply: fl |= Qt.ItemIsEnabled item1.setFlags(fl) cw = self.table.cellWidget(row, j) cw and cw.setEnabled(group.style.apply) elif col in self.AttrByCol: cb = self.table.cellWidget(row, col) txt = str(cb.currentText()) attr = self.AttrByCol[col] if txt == "default": setattr(group.style, attr, PlotStyles.DefaultValue) else: setattr(group.style, attr, PlotStyles.StyleAttributeTypes.get(attr, str)(txt)) # all other columns: return so we don't emit a signal else: return # in all cases emit a signal self.model.emitChangeGroupingStyle(group, origin=self) def selectSources(self, predicate, curry=False): """Selects sources according to predicate(src)""" busy = BusyIndicator() for src in self.model.sources: src.selected = predicate(src) self.model.emitSelection(origin=self) busy.reset_cursor() def updateModelSelection(self, nsel, origin=None): """This is called when some other widget changes the set of selected model sources""" self.table.clearSelection() if self.model: self.table.item(self._irow_selgroup, 1).setText(str(nsel)) def _togglePlotControlsVisibility(self): if self._attrs_shown: self._attrs_shown = False self.table.hideColumn(self.ColApply) for col in self.AttrByCol.keys(): self.table.hideColumn(col) self._showattrbtn.setText("Show plot styles >>") else: self._attrs_shown = True self.table.showColumn(self.ColApply) for col in self.AttrByCol.keys(): self.table.showColumn(col) self._showattrbtn.setText("<< Hide plot styles")
class Ui(QApplication): def __init__(self): super().__init__(argv) self.w = QMainWindow() self.w.setMinimumWidth(300) self.w.setMinimumHeight(300) # self.w.setWindowTitle(tr("Отправка запросов на ВС АУГО")) self.cw = QScrollArea() # self.__create_ui() self.__showed = False self.__wgts = {} self.cb = QComboBox() self.individuals = [] self.entities = [] self.documents = [] self.doc_files = [] self.__setupUi(self.w) self.w.showMaximized() def report_error(self, msg=None): if not msg: etype, value, tb = exc_info() trace = ''.join(format_exception(etype, value, tb)) delim_len = 40 msg = ("*" * delim_len + "\n%s\n" + "*" * delim_len) % trace error(msg) mb = QMessageBox(QMessageBox.Critical, tr('Ошибка'), str(exc_info()[1])) mb.setDetailedText(msg) mb.exec() def __create_ui(self): self.l = QGridLayout() self.t = QTableWidget(0, 3) self.t.setHorizontalHeaderLabels( ('№ дела (обращения)', 'Дата приёма', 'Дата отправки в СМЭВ')) self.t.resizeColumnsToContents() self.l.addWidget(self.t, 0, 0, 1, 2) w = QWidget() hl = QHBoxLayout(w) hl.setDirection(QHBoxLayout.LeftToRight) hl.addWidget(QWidget()) ok_b = QPushButton(tr('Добавить запрос')) ok_b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum) ok_b.clicked.connect(self.__show_form) hl.addWidget(ok_b) w.setLayout(hl) self.l.addWidget(w, 1, 0, 1, 2) w = QWidget() w.setLayout(self.l) self.cw.setWidget(w) # self.cw.setLayout(self.l) # self.w.setCentralWidget(self.cw) w = QWidget() l = QVBoxLayout() l.addWidget(self.cw) w.setLayout(l) self.w.setCentralWidget(w) def __setupUi(self, mainWindow): mainWindow.setObjectName("MainWindow") self.centralwidget = QWidget(mainWindow) self.centralwidget.setObjectName("centralwidget") self.horizontalLayout = QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName("horizontalLayout") self.scrollArea = QScrollArea(self.centralwidget) self.scrollArea.setWidgetResizable(True) self.scrollArea.setObjectName("scrollArea") self.scrollAreaWidgetContents = QWidget() self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.gridLayout = QGridLayout(self.scrollAreaWidgetContents) self.gridLayout.setObjectName("gridLayout") self.__show_form() self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.horizontalLayout.addWidget(self.scrollArea) mainWindow.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(mainWindow) self.menubar.setObjectName("menubar") self.menu = QMenu(self.menubar) self.menu.setObjectName("menu") mainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(mainWindow) self.statusbar.setObjectName("statusbar") mainWindow.setStatusBar(self.statusbar) self.action_1 = QAction(mainWindow) self.action_1.setObjectName("action") self.action_1.triggered.connect(self.send) self.action = QAction(mainWindow) self.action.setObjectName("action") self.action.triggered.connect(self.on_action_triggered) self.action_2 = QAction(mainWindow) self.action_2.setObjectName("action_2") self.action_3 = QAction(mainWindow) self.action_3.setObjectName("action_3") self.action_3.triggered.connect(self.get_response) self.menu.addAction(self.action) self.menubar.addAction(self.action_1) self.menubar.addAction(self.action_2) self.menubar.addAction(self.action_3) self.menubar.addAction(self.menu.menuAction()) self.__retranslateUi(mainWindow) QMetaObject.connectSlotsByName(mainWindow) @pyqtSlot(bool) def get_response(self): try: from dmsic import Integration i = Integration(self) res = i.get_response()[0] if res: QMessageBox.information(self.w, tr("Получен ответ"), str(res)) except: self.report_error() @pyqtSlot(bool) def send(self): try: from dmsic import Integration i = Integration(self) declar = {} for k, v in self.__wgts.items(): if k in ('object_address', 'AppliedDocument', 'legal_entity', 'person'): a = {} for key, val in v.items(): if val.metaObject().className() == 'QDateEdit': a[key] = datetime.strptime(val.text(), '%d.%m.%Y') else: a[key] = val.text() declar[k] = a else: if v.metaObject().className() == 'QDateEdit': declar[k] = datetime.strptime(v.text(), '%d.%m.%Y') else: declar[k] = v.text() a = declar[ 'AppliedDocument'] if 'AppliedDocument' in declar else [] for v in self.documents: d = {} for key, val in v.items(): if val.metaObject().className() == 'QDateEdit': d[key] = datetime.strptime(val.text(), '%d.%m.%Y') else: d[key] = val.text() if not self.doc_files: raise Exception('Добавте файл документа') d['file_name'] = self.doc_files[self.documents.index(v)] a.append(d) declar['AppliedDocument'] = a a = declar['person'] if 'person' in declar else [] for v in self.individuals: ind = {} for key, val in v.items(): if key in ('address', 'fact_address'): adr = {} for k, vl in val.items(): adr[k] = vl.text() ind[key] = adr else: if val.metaObject().className() == 'QDateEdit': ind[key] = datetime.strptime( val.text(), '%d.%m.%Y') else: ind[key] = val.text() a.append(ind) declar['person'] = a a = declar['legal_entity'] if 'legal_entity' in declar else [] for v in self.entities: ent = {} for key, val in v.items(): if key == 'address': adr = {} for k, vl in val.items(): adr[k] = vl.text() ent[key] = adr else: if val.metaObject().className() == 'QDateEdit': ent[key] = datetime.strptime( val.text(), '%d.%m.%Y') else: ent[key] = val.text() a.append(ent) declar['legal_entity'] = a i.send(declar) mb = QMessageBox(self.w) mb.information(self.w, tr('Готово'), tr('Запрос отправлен')) except: self.report_error() @pyqtSlot(bool) def on_action_triggered(self): a = Ui_Dialog() d = QDialog() a.setupUi(d) d.exec() def __retranslateUi(self, MainWindow): _translate = QCoreApplication.translate MainWindow.setWindowTitle( _translate("MainWindow", "Отправка запросов на ВС АУГО")) # self.pushButton.setText(_translate("MainWindow", "Добавить")) self.menu.setTitle(_translate("MainWindow", "Справка")) self.action_1.setText(_translate("MainWindow", "Отправить")) self.action_2.setText(_translate("MainWindow", "Настройка")) self.action.setText(_translate("MainWindow", "О программе")) self.action_3.setText(_translate("MainWindow", "Получить ответ")) @pyqtSlot(bool) def __show_form(self): if self.__showed: return self.gridLayout.addWidget( QLabel(tr('№ дела (обращения) <em style="color: red">*</em>'))) w = QLineEdit() self.gridLayout.addWidget(w) w.setFocus() self.__wgts['declar_number'] = w self.gridLayout.addWidget( QLabel( tr('Услуга (код или номер, или наименование)<em style="color: red">*</em>' ))) w = QLineEdit() self.gridLayout.addWidget(w) self.__wgts['service'] = w self.gridLayout.addWidget( QLabel( tr('Дата регистрации запроса <em style="color: red">*</em>'))) de = QDateEdit(QDate().currentDate()) de.setCalendarPopup(True) self.gridLayout.addWidget(de) self.__wgts['register_date'] = de self.gridLayout.addWidget( QLabel( tr('Плановый срок предоставления услуги <em style="color: red">*</em>' ))) de = QDateEdit() self.__wgts['register_date'].dateChanged.connect(de.setMinimumDate) de.setCalendarPopup(True) de.setMinimumDate(self.__wgts['register_date'].date()) self.gridLayout.addWidget(de) self.__wgts['end_date'] = de gb = QGroupBox(tr('Место нахождения объекта услуги')) gb_l = QGridLayout() self.__wgts['object_address'] = self.__add_address(gb_l) gb.setLayout(gb_l) self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2) doc = {} gb = QGroupBox(tr('Приложенный документ *')) gb_l = QGridLayout() gb_l.addWidget( QLabel(tr('Наименование документа <em style="color: red">*</em>'))) w = QLineEdit() w.setMaxLength(1024) gb_l.addWidget(w, 0, 1, 1, 1) doc['title'] = w gb_l.addWidget( QLabel(tr('Номер документа <em style="color: red">*</em>'))) w = QLineEdit() w.setMaxLength(50) gb_l.addWidget(w) doc['number'] = w gb_l.addWidget( QLabel(tr('Дата документа <em style="color: red">*</em>'))) w = QDateEdit() w.setCalendarPopup(True) gb_l.addWidget(w) doc['date'] = w gb_l.addWidget( QLabel( tr('Прямая ссылка на файл. Поддерживаются только пртоколы ' 'HTTP, FTP <em style="color: red">*</em>'))) w = QLineEdit() gb_l.addWidget(w) doc['url'] = w gb.setLayout(gb_l) self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2) self.documents.append(doc) gb = QGroupBox(tr('Заявители *')) self.dec_layout = QGridLayout() self.cb = QComboBox() self.cb.addItems(('Физическое лицо', 'Юридическое лицо/Индивидуальный предприниматель')) self.dec_layout.addWidget(self.cb) b = QPushButton(tr('Добавить')) b.clicked.connect(self.add_declarant) self.dec_layout.addWidget(b, 0, 1, 1, 1) gb.setLayout(self.dec_layout) self.gridLayout.addWidget(gb, self.gridLayout.rowCount() + 1, 0, 1, 2) b = QPushButton(tr('Добавить файл документа')) b.clicked.connect(self.__add_doc_file) self.gridLayout.addWidget(b) self.file_label = QLabel() self.gridLayout.addWidget(self.file_label) self.warn_label = QLabel(tr("Не удаляйте файл до отправки запроса")) self.warn_label.setStyleSheet('color: red') self.warn_label.setVisible(False) self.gridLayout.addWidget(self.warn_label, self.gridLayout.rowCount() + 1, 0, 1, 2) self.__showed = True @pyqtSlot(bool) def __add_doc_file(self): file_name = QFileDialog.getOpenFileName( caption=tr('Выбурите файл'), filter=tr('Файлы pdf (*.pdf);;Все файлы (*.*)'))[0] self.file_label.setText(file_name) if self.doc_files: self.doc_files = [] self.doc_files.append(file_name) self.warn_label.setVisible(True) def __add_address(self, gb_l): wgts = {} gb_l.addWidget(QLabel(tr('Почтовый индекс'))) w = QLineEdit() gb_l.addWidget(w, 0, 1, 1, 1) wgts['Postal_Code'] = w gb_l.addWidget(QLabel(tr('Регион'))) w = QLineEdit() gb_l.addWidget(w) wgts['Region'] = w gb_l.addWidget(QLabel(tr('Район'))) w = QLineEdit() gb_l.addWidget(w) wgts['District'] = w gb_l.addWidget(QLabel(tr('Муниципальное образование'))) w = QLineEdit() gb_l.addWidget(w) wgts['City'] = w gb_l.addWidget(QLabel(tr('Городской район'))) w = QLineEdit() gb_l.addWidget(w) wgts['Urban_District'] = w gb_l.addWidget(QLabel(tr('Сельсовет'))) w = QLineEdit() gb_l.addWidget(w) wgts['Soviet_Village'] = w gb_l.addWidget( QLabel(tr('Населенный пункт <em style="color: red">*</em>'))) w = QLineEdit() gb_l.addWidget(w) wgts['Locality'] = w cb = QComboBox() cb.addItems(('Вариант 1', 'Вариант 2')) gb_l.addWidget(cb) st = QStackedWidget() p1 = QWidget() l = QGridLayout() l.setSpacing(3) l.addWidget(QLabel(tr('Улица <em style="color: red">*</em>'))) w = QLineEdit() l.addWidget(w, 0, 1, 1, 1) wgts["Street"] = w l.addWidget(QLabel(tr('Дом <em style="color: red">*</em>'))) w = QLineEdit() l.addWidget(w) wgts["House"] = w p1.setLayout(l) st.addWidget(p1) p2 = QWidget() l = QGridLayout() l.setSpacing(3) l.addWidget(QLabel(tr('Ориентир'))) w = QLineEdit() l.addWidget(w, 0, 1, 1, 1) wgts["Reference_point"] = w p2.setLayout(l) st.addWidget(p2) gb_l.addWidget(st, 9, 0, 1, 2) cb.activated.connect(st.setCurrentIndex) gb_l.addWidget(QLabel(tr('Корпус'))) w = QLineEdit() gb_l.addWidget(w) wgts['Housing'] = w gb_l.addWidget(QLabel(tr('Строение'))) w = QLineEdit() gb_l.addWidget(w) wgts['Building'] = w gb_l.addWidget(QLabel(tr('Квартира'))) w = QLineEdit() gb_l.addWidget(w) wgts['Apartment'] = w return wgts @pyqtSlot(bool) def add_declarant(self, var=True, gl=None): if not gl: gl = self.dec_layout dc = {} gb_l = QGridLayout() if self.cb.currentIndex() == 0 or gl != self.dec_layout: # Add Individual gb = QGroupBox(tr('Физическое лицо *')) gb_l.addWidget(QLabel(tr('Фамилия <em style="color: red">*</em>'))) w = QLineEdit() gb_l.addWidget(w, 0, 1, 1, 1) dc['surname'] = w gb_l.addWidget(QLabel(tr('Имя <em style="color: red">*</em>'))) w = QLineEdit() gb_l.addWidget(w) dc['first_name'] = w gb_l.addWidget(QLabel(tr('Отчество'))) w = QLineEdit() gb_l.addWidget(w) dc['patronymic'] = w adr = QGroupBox(tr('Адрес регистрации *')) adr_l = QGridLayout() dc['address'] = self.__add_address(adr_l) adr.setLayout(adr_l) gb_l.addWidget(adr, gb_l.rowCount() + 1, 0, 1, 2) gb.setLayout(gb_l) gl.addWidget(gb, gl.rowCount() + 1, 0, 1, 2) self.individuals.append(dc) else: # Add LegalEntity gb = QGroupBox( tr('Юридическое лицо/Индивидуальный предприниматель *')) gb_l.addWidget( QLabel( tr('Краткое наименование ЮЛ <em style="color: red">*</em>') )) w = QLineEdit() gb_l.addWidget(w, 0, 1, 1, 1) dc['name'] = w adr = QGroupBox(tr('Юридический адрес *')) adr_l = QGridLayout() dc['address'] = self.__add_address(adr_l) adr.setLayout(adr_l) gb_l.addWidget(adr, gb_l.rowCount() + 1, 0, 1, 2) gb.setLayout(gb_l) gl.addWidget(gb, gl.rowCount() + 1, 0, 1, 2) self.entities.append(dc)
class TableTab(TraceDocks): ## The constructor # initialize the super-class, assign a name and first configItems def __init__(self,parent): super(TableTab, self).__init__(parent,'TableTab') self.tabName = 'TableTab' self.parent = parent self.logger.logEvent('Creating Tab now: '+ self.tabName) # Set a couple of default-values, in case the configParser does not work self.snifferConfig.configAutoClearCheck = 1 self.snifferConfig.configFilterState = 'Local' self.snifferConfig.configFilterList = self.snifferFilter.filteredIdList # By parsing the config now, we assure that we re-load everything # the way we left it self.snifferConfig.parseConfigFromFile() self.lastSearchedText = 'nullthiswillneverbefound' self.lastMatch = 'purge' self.lastIndex = 0 ## Create the visible UI def setTableTabLayout(self): # Create Table Tab --------------------### # Create Layouts self.Vlayout = QVBoxLayout() self.H1layout = QHBoxLayout() self.H11layout = QHBoxLayout() self.H12layout = QHBoxLayout() self.H21layout = QHBoxLayout() self.V11layout = QVBoxLayout() self.V21layout = QVBoxLayout() # Create Widgets for H1layout # First buttons self.clearTableButt = QPushButton('Clear Table') self.clearTableButt.clicked.connect(self.clearTable) self.autoClearCheck = QCheckBox('Auto Clear') self.autoClearCheck.stateChanged.connect(self.checkAutoClearChanged) self.searchInputField = QLineEdit() self.searchInputField.setPlaceholderText('Enter search term, then click search') self.searchButt = QPushButton('Search Table') self.searchButt.clicked.connect(lambda: self.searchInTable(self.searchInputField.text(),2)) self.showSummaryButt = QPushButton('Show Summary') self.showSummaryButt.clicked.connect(self.showSummary) self.filterGroup = QButtonGroup() self.localFilterRadio = QRadioButton('Local',self) self.globalFilterRadio = QRadioButton('Global', self) self.configureFilterButt = QPushButton('Configure Filter') self.configureFilterButt.clicked.connect(self.configureFilter) self.localFilterRadio.clicked.connect(self.localRadioSelected) self.globalFilterRadio.clicked.connect(self.globalRadioSelected) self.H21layout.addWidget(self.localFilterRadio) self.H21layout.addWidget(self.globalFilterRadio) self.H21layout.addWidget(self.showSummaryButt) self.V21layout.addLayout(self.H21layout) self.V21layout.addWidget(self.configureFilterButt) # Add Widgets to H11layout self.H11layout.addWidget(self.clearTableButt) self.H11layout.addWidget(self.autoClearCheck) # Add Widgets to H12layout self.H12layout.addWidget(self.searchInputField) self.H12layout.addWidget(self.searchButt) self.H12layout.addStretch() self.V11layout.addLayout(self.H11layout) self.V11layout.addLayout(self.H12layout) self.H1layout.addLayout(self.V11layout) self.H1layout.addLayout(self.V21layout) self.syncUiToConfig() #------------------------------------ # Create Table self.detailTableIndex = 0 self.detailTable = QTableWidget() self.detailTableItem = QTableWidgetItem() self.detailTable.setRowCount(0) self.detailTable.setColumnCount(6) self.detailTable.setHorizontalHeaderLabels('packID;Tick;Timer;Type;Message;Length'.split(';')) self.detailTable.resizeColumnsToContents() self.detailTableHeader = self.detailTable.horizontalHeader() self.detailTableHeader.setSectionResizeMode(0, QHeaderView.ResizeToContents) self.detailTableHeader.setSectionResizeMode(1, QHeaderView.ResizeToContents) self.detailTableHeader.setSectionResizeMode(2, QHeaderView.ResizeToContents) self.detailTableHeader.setSectionResizeMode(3, QHeaderView.ResizeToContents) self.detailTableHeader.setSectionResizeMode(4, QHeaderView.Stretch) self.detailTableHeader.setSectionResizeMode(5, QHeaderView.ResizeToContents) #------------------------------------ self.Vlayout.addLayout(self.H1layout) self.Vlayout.addWidget(self.detailTable) self.dockContents.setLayout(self.Vlayout) ## Fill the main table with the entries from the given list # @param fillTableList the list which is to be parsed into the table def fillTable(self,fillTableList): print('Filling Table with all items in PayloadList') self.detailTable.scrollToTop() # Scrolls to the top of the table self.configAutoClearCheck = True if self.configAutoClearCheck == True: self.detailTable.setRowCount(0) self.detailTableIndex = 0 Globals.dockDict['dockStart'].progressShotBar.setMaximum(len(Globals.payloadList)) for self.tablePayload in fillTableList: self.detailTable.insertRow(self.detailTableIndex) self.detailTable.setItem(self.detailTableIndex,0,QTableWidgetItem(str(self.tablePayload.payloadHead.packetID))) self.detailTable.setItem(self.detailTableIndex,1,QTableWidgetItem(str(self.tablePayload.payloadHead.tickCountHigh << 8 | self.tablePayload.payloadHead.tickCountLow))) self.detailTable.setItem(self.detailTableIndex,2,QTableWidgetItem(str(self.tablePayload.payloadHead.timerByteHigh << 8 | self.tablePayload.payloadHead.timerByteLow))) self.detailTable.setItem(self.detailTableIndex,3,QTableWidgetItem(Globals.tspDict[self.tablePayload.payloadHead.informationID][0])) testPayload = self.tablePayload.toDict() # This a little messy: We check whether an objectDict is available, and if it is # we check for the different DataTypes there might be, since the message section is unified. # Basically, we need to handle all the different cases there can be, payload0-payload3 and the actual objectType if Globals.objectDict: if getDataType(self.tablePayload) == 1: if getObjectType(self.tablePayload) == 5: try: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+': '+Globals.objectDict['TASK'][str(self.tablePayload.data1)])) except: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem('FAILED WITH KEYERROR - see printOutput')) print('KEYERROR DETAILS:') print(testPayload) elif getDataType(self.tablePayload) == 2: try: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+': '+Globals.objectDict[Globals.objectTypeDict[self.tablePayload.data1]][str(self.tablePayload.data2)])) except: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem('FAILED WITH KEYERROR - see printOutput')) print('KEYERROR DETAILS:') print(testPayload) # If the objectDict does not exist, we can just dump the raw information into the message-section -> no lookup will be happening # and it is up to the user to interpret the data else: if getDataType(self.tablePayload) == 1: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1))) elif getDataType(self.tablePayload) == 2: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+';'+str(self.tablePayload.data2))) elif getDataType(self.tablePayload) == 3: self.detailTable.setItem(self.detailTableIndex,4,QTableWidgetItem(str(self.tablePayload.data1)+';'+str(self.tablePayload.data2)+';'+str(self.tablePayload.data3))) self.detailTable.setItem(self.detailTableIndex,5,QTableWidgetItem('payload'+str(getDataType(self.tablePayload)))) self.detailTableIndex+=1 Globals.dockDict['dockStart'].progressShotBar.setValue(self.detailTableIndex) Globals.dockDict['dockStart'].progressShotBar.setValue(len(Globals.payloadList)) Globals.dockDict['dockStart'].displayStatusMessage('Table filled completely, check the tab') self.lastSearchedText = 'thisisAWorkAround' # No idea why this is there... # --- DOCK-SPECIFIC UI FUNCTIONS --- # # -----------------------------------# ## Disable all UI-buttons belonging to the tab. This is implementation specific def disableButtons(self): self.clearTableButt.setEnabled(False) self.autoClearCheck.setEnabled(False) print('Disable TabTable Buttons') ## CB: clearTableButton // Clear the main table def clearTable(self): self.logger.logEvent('clear Table clicked') self.detailTable.setRowCount(0) self.detailTableIndex = 0 ## CB: autoClearCheckbox // set the configAutoClearCheck state according to the checkbox def checkAutoClearChanged(self): self.snifferConfig.configAutoClearCheck ^= 1 self.logger.logEvent('changed Auto Clear Checkbox to - '+ str(self.snifferConfig.configAutoClearCheck)) ## CB: localRadioButt // set the configFilterState to 'Local' def localRadioSelected(self): self.snifferConfig.configFilterState = 'Local' self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState)) ## CB: globalRadioButt // set the configFilterState to 'Global' def globalRadioSelected(self): self.snifferConfig.configFilterState = 'Global' self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState)) ## CB: Show Stats // opens the Stat-Dialog to show misc. information about the measurement def showSummary(self): self.snifferStats.show() self.snifferStats.showStats() ## Searches the table for a string and scrolls to the found item. # @param textToSearch the string that needs to be found in the table # @param column the column where the search needs to take place def searchInTable(self, textToSearch, column): if textToSearch not in Globals.IDList: QMessageBox.about(self,'Not Found','SearchText not Found!') return if self.lastSearchedText == textToSearch: self.detailTable.setCurrentItem(self.lastFound[self.lastIndex]) self.detailTable.scrollToItem(self.lastFound[self.lastIndex]) self.lastIndex = self.lastIndex + 1 if self.lastIndex == len(self.lastFound): self.lastIndex = 0 else: foundItems = self.detailTable.findItems(textToSearch, Qt.MatchExactly) self.lastSearchedText = textToSearch if len(foundItems) != 0: self.lastFound = foundItems self.lastIndex = 1 self.detailTable.setCurrentItem(foundItems[0]) self.detailTable.scrollToItem(self.lastFound[self.lastIndex]) # --- MANDATORY UI FUNCTIONS --- # # -------------------------------# ## Read out all components of snifferConfig and set the UI elements according to # the saved values. def syncUiToConfig(self): self.autoClearCheck.setChecked(self.snifferConfig.configAutoClearCheck) if self.snifferConfig.configFilterState == 'Local': self.localFilterRadio.click() elif self.snifferConfig.configFilterState == 'Global': self.globalFilterRadio.click() else: print('Error, neither local nor global in config') ## Open the correct filter based on the radioButton. If the Global-filter is checked # we assign its calledby variable in order to execute the right callback after the filter is saved. def configureFilter(self): if self.localFilterRadio.isChecked(): self.snifferFilter.show() elif self.globalFilterRadio.isChecked(): Globals.globalFilter.show() Globals.globalFilter.calledBy = 'dockTable' else: print('neither radios checked. Error!') ## CB: // Updates the UI-contents with after filtering has taken place. # This function should not be called by the tab itself, but by the filter # @param filteredIDs the IDs that are to be kept in the payloadList (obsolete) # @param filteredPayloads the new payloadList, which only contains the payloads filtered by the SnifferFilter def filterUpdated(self, filteredIDs, filteredPayloads): print('we arrive from SnifferFilter') self.clearTable() self.fillTable(filteredPayloads)
class SnifferFilter(QDialog): ## The constructor. # Initialize lists to be filled with filtered payloads and # create the dialog. def __init__(self, parent): super(SnifferFilter, self).__init__() self.parent = parent self.setWindowTitle('SnifferFilter') self.filteredPayloadList = [] self.filteredIdList = [] self.layoutingComplete = False self.calledBy = 'NONE' # We store here which tab the filter belongs to, if there is no parent.(Like when the filter is global!) self.objectTabDict = {} self.filteredObjectDict = {} self.resize(670, 700) ## Filters the global payloadList by ID by iterating through it and # appending to a new list by filter-criteria # @param filterList a list of IDs that are to be transferred to the new list def filterPayloadsByID(self, filterList): for payload in Globals.payloadList: if hasattr(payload, 'payloadHead'): if Globals.tspDict[ payload.payloadHead.informationID][0] in filterList: self.filteredPayloadList.append(payload) else: #print('informationID is in filteredIdList, skipping packet') pass ## Filters the global payloadList by Message by iterating through it and # appending to a new list by filter-criteria # @param filterDict a dictionary of Key: ObjectType and Value: ObjectsToKeep as a template # of which items are to be kept in the filteredList def filterPayloadsByMessage(self, filterDict): localFilteredList = [] for payload in self.filteredPayloadList: print('payloadID:' + str(payload.payloadHead.informationID)) # If the ID has nothing to do with the object, we can safely add it. if payload.payloadHead.informationID is 23: x = 0 pass if isRelatedToObject(payload): for objType, messageID in filterDict.items(): print(Globals.objectTypeDict[getObjectType(payload)]) if Globals.objectTypeDict[getObjectType( payload )] == objType: # If the objectType matches the one in the dictionary if objType == 0: x = 0 pass if getDataType(payload) == 2: if payload.data2 not in messageID: # and the message does not match the dictionary print( 'Passing data with msgid: ' + str(payload.data2) ) # don't append, but print that we skipped this one else: localFilteredList.append( payload ) # the message does match the dictionary -> we want to keep it, so we add it to the list elif getDataType(payload) == 1: if payload.data1 not in messageID: print('Passing data with msgid: ' + str(payload.data1)) else: localFilteredList.append(payload) else: localFilteredList.append(payload) else: # If the ID has nothing to do with the object, we can safely add it. # Also, is the object is not even in the filterDict, we can add it too (this should not happen, but # it's there for safety purposes if getDataType(payload) == 0 or Globals.objectTypeDict[ getObjectType(payload)] not in filterDict: localFilteredList.append(payload) else: localFilteredList.append(payload) # In every other case, append it to the list, since we only want to filter out specific objects self.filteredPayloadList = list(localFilteredList) ## Create the visible UI # like the different tables, the searchbar etc. def setSnifferFilterUi(self): self.filterTabs = QTabWidget() self.H1layout = QHBoxLayout() self.Vlayout = QVBoxLayout() self.searchInputField = QLineEdit() self.searchInputField.setPlaceholderText( 'Enter search term, then click search') self.searchButt = QPushButton('Search Table') self.saveFilterButt = QPushButton('Save Filter') self.filterTable = QTableWidget() self.saveFilterButt.clicked.connect(self.saveFilterList) self.searchButt.clicked.connect( lambda: self.searchInTable(self.searchInputField.text(), 0)) # Create Table self.filterTableIndex = 0 self.filterTable = QTableWidget() self.filterTableItem = QTableWidgetItem() self.filterTable.setRowCount(0) self.filterTable.setColumnCount(2) self.filterTable.setHorizontalHeaderLabels( 'informationID;Enable'.split(';')) self.filterTable.resizeColumnsToContents() self.filterTableHeader = self.filterTable.horizontalHeader() self.filterTableHeader.setSectionResizeMode(0, QHeaderView.Stretch) self.filterTableHeader.setSectionResizeMode( 1, QHeaderView.ResizeToContents) font = self.getFont() self.checkBoxAllIds = self.createCheckBox() self.filterTable.itemChanged.connect(self.filterAllIDs) self.checkBoxAllMessages = self.createCheckBox() # -- Add first Row for all -- # self.filterTable.insertRow(self.filterTableIndex) idFilterItem = QTableWidgetItem('FILTER ALL IDs') idFilterItem.setFont(font) messageFilterItem = QTableWidgetItem('FILTER ALL Messages') messageFilterItem.setFont(font) self.filterTable.setItem(self.filterTableIndex, 0, idFilterItem) self.filterTable.setItem(self.filterTableIndex, 1, self.checkBoxAllIds) self.filterTableIndex = self.filterTableIndex + 1 # -- Add informationID filter rows -- # for keys, values in Globals.tspDict.items(): if values[0].startswith('ID'): checkBoxFilter = self.createCheckBox() self.filterTable.insertRow(self.filterTableIndex) self.filterTable.setItem(self.filterTableIndex, 0, QTableWidgetItem(values[0])) self.filterTable.setItem(self.filterTableIndex, 1, checkBoxFilter) self.filterTableIndex = self.filterTableIndex + 1 self.filterTabs.addTab(self.filterTable, 'Information ID') self.H1layout.addWidget(self.searchInputField) self.H1layout.addWidget(self.searchButt) self.Vlayout.addLayout(self.H1layout) self.Vlayout.addWidget(self.filterTabs) self.Vlayout.addWidget(self.saveFilterButt) #------------------------------------ self.setLayout(self.Vlayout) self.layoutingComplete = True ## Updates the visible filter UI to the new objectList # This function is called, when either a new measurement was executed or an old measurement was loaded. # Since the objects shown in the Filter need to be updated. def updateObjectFilter(self): # -- Add message filter rows -- # font = self.getFont() self.filterTabs.clear() self.filterTabs.addTab(self.filterTable, 'Information ID') # For each object in objectList, create a new Table and add it to the tabs. for keys, values in Globals.objectDict.items(): objectFilterTable = QTableWidget() objectFilterTable.setRowCount(0) objectFilterTable.setColumnCount(2) strSplit = keys + ';Enable' objectFilterTable.setHorizontalHeaderLabels(strSplit.split(';')) objectFilterTable.resizeColumnsToContents() filterTableHeader = objectFilterTable.horizontalHeader() filterTableHeader.setSectionResizeMode(0, QHeaderView.Stretch) filterTableHeader.setSectionResizeMode( 1, QHeaderView.ResizeToContents) checkBoxFilter = self.createCheckBox() objectFilterTable.itemChanged.connect( lambda *a, table=objectFilterTable: self.filterAllObjectIDs( *a, table=table)) objectTableIndex = 0 objectFilterTable.insertRow(objectTableIndex) objCat = QTableWidgetItem('FILTER ALL') objCat.setFont(font) objectFilterTable.setItem(objectTableIndex, 0, objCat) objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter) objectTableIndex = objectTableIndex + 1 for keys2, values2 in values.items(): objectFilterTable.insertRow(objectTableIndex) checkBoxFilter = self.createCheckBox() objectFilterTable.setItem( objectTableIndex, 0, QTableWidgetItem('ID: ' + str(keys2) + ' Name: ' + str(values2))) objectFilterTable.setItem(objectTableIndex, 1, checkBoxFilter) objectTableIndex = objectTableIndex + 1 # Add the newly create table to the tabs. self.filterTabs.addTab(objectFilterTable, keys) self.objectTabDict[keys] = objectFilterTable ## Searches the table for a string and scrolls to the found item. # @param textToSearch the string that needs to be found in the table # @param column the column where the search needs to take place def searchInTable(self, textToSearch, column): # Create a model of the table, so we can match a text tableModel = self.filterTable.model() start = tableModel.index(0, column) matches = tableModel.match(start, Qt.DisplayRole, textToSearch, 1, Qt.MatchContains) # If there are multiple matches, we take the first one, select it and scroll to it if matches: index = matches[0] self.filterTable.selectionModel().select( index, QItemSelectionModel.Select) self.filterTable.scrollToItem( self.filterTable.itemFromIndex(index)) ## CB: SaveFilterButton // Call the filterFunctions -> Filter the unfiltered list by ID and Object and call the update # function of the executing tab in order to update their UI. def saveFilterList(self): self.filteredPayloadList.clear() #--Save by ID--# rowCnt = self.filterTable.rowCount() self.filteredIdList.clear() for rows in range(0, rowCnt): if self.filterTable.item(rows, 1).checkState() == Qt.Checked: #print(self.filterTable.item(rows,0).text()) self.filteredIdList.append( self.filterTable.item(rows, 0).text()) self.filterPayloadsByID(self.filteredIdList) print(len(self.filteredPayloadList)) print(len(Globals.payloadList)) #--Save By Objects--# self.filteredObjectDict.clear() for objType, objectTable in self.objectTabDict.items(): rowCnt = objectTable.rowCount() objectsToFilter = [] for rows in range(0, rowCnt): if objectTable.item(rows, 1).checkState() == Qt.Checked: #print(objectTable.item(rows,0).text()) try: objectsToFilter.append( int( re.search('ID: (.*) Name:.*', objectTable.item( rows, 0).text()).group(1))) self.filteredObjectDict[objType] = objectsToFilter #print('Found Regex: '+re.search('ID: (.*) Name:.*',objectTable.item(rows,0).text()).group(1)) except: print('Error when parsing TableRegex...this is okay') self.filterPayloadsByMessage(self.filteredObjectDict) # We filtered the list, now we hide the windows and call the update-function # If the maintainer of the tab did not follow the implementation guide, there is no update-function to call. # We still save the filtered list, so we print a message to show where to find it. self.hide() try: self.parent.filterUpdated(self.filteredIdList, self.filteredPayloadList) except AttributeError: print( 'No corresponding callable function filterUpdated was found, you can access the most recent filteredList via self.snifferFilter.filteredIdList' ) try: Globals.dockDict[self.calledBy].filterUpdated( self.filteredIdList, self.filteredPayloadList) except: print('not global!') ## Check whether the first checkbox was checked and then update the entire ID table to either checked or unchecked state # @param checkBox a checkBox we perform the query on def filterAllIDs(self, checkBox): if self.layoutingComplete == True: if checkBox.column() == 1 and checkBox.row( ) == 0: # We clicked the toggle ID checkbox if checkBox.checkState() == Qt.Checked: rowCnt = self.filterTable.rowCount() for rows in range(0, rowCnt): try: self.filterTable.item(rows, 1).setCheckState(Qt.Checked) except AttributeError: print( 'no items after' + str(rows) + 'found...Maybe this column has less items than' + str(rowCnt) + '?') elif checkBox.checkState() == Qt.Unchecked: rowCnt = self.filterTable.rowCount() for rows in range(0, rowCnt): try: self.filterTable.item(rows, 1).setCheckState( Qt.Unchecked) except AttributeError: print( 'no items after' + str(rows) + 'found...Maybe this column has less items than' + str(rowCnt) + '?') else: print( 'neither checked nor unchecked...should never be here..' ) ## Check whether the first checkbox was checked and then update the entire ObjectIDtable to either checked or unchecked state # @param checkBox a checkBox we perform the query on # @param table the table that is to be updated def filterAllObjectIDs(self, checkBox, table): if (self.objectTabDict): if checkBox.column() == 1 and checkBox.row( ) == 0: # We clicked the toggle ID checkbox if checkBox.checkState() == Qt.Checked: rowCnt = table.rowCount() for rows in range(0, rowCnt): try: table.item(rows, 1).setCheckState(Qt.Checked) except AttributeError: print( 'no items after' + str(rows) + 'found...Maybe this column has less items than' + str(rowCnt) + '?') elif checkBox.checkState() == Qt.Unchecked: rowCnt = table.rowCount() for rows in range(0, rowCnt): try: table.item(rows, 1).setCheckState(Qt.Unchecked) except AttributeError: print( 'no items after' + str(rows) + 'found...Maybe this column has less items than' + str(rowCnt) + '?') else: print( 'neither checked nor unchecked...should never be here..' ) # --- HELPER FUNCTIONS --- # ## Create a defined checkbox within a tableWidgetItem to facilitate filling the table # @return the created checkbox def createCheckBox(self): myCheck = QTableWidgetItem() myCheck.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) myCheck.setCheckState(Qt.Checked) return myCheck ## Create a defined font (bold,underlined) to facilitate filling the table # @return the created font def getFont(self): font = QFont() font.setBold(True) font.setUnderline(True) return font
class SnifferStats(QDialog): ## The constructor. def __init__(self): super().__init__() print('Stating') self.iDList = [] self.packetCount = 0 self.counter = 0 self.statsTableIndex = 0 self.setWindowTitle('SnifferStats') self.snifferAPI = SnifferAPI() self.contentBox = QLabel() self.statsTable = QTableWidget() self.tabs = QTabWidget() self.tabBasic = QWidget() self.tabAdvanced = QWidget() self.layout = QVBoxLayout() self.tabs.addTab(self.tabBasic,"Basic") self.tabs.addTab(self.tabAdvanced,"Advanced") self.tabBasic.layout = QVBoxLayout() self.tabAdvanced.layout = QVBoxLayout() ## Shows the stats in Label and Table (Basic and Advanced Tab). def showStats(self): self.clearTableStats() self.clearLabelStats() #-Advanced Tab self.iDList = self.snifferAPI.getAllInfoIDs(Globals.payloadList) self.counter = self.snifferAPI.getCountedInfoIDs(self.iDList) self.fillStatTable(Globals.payloadList, self.counter, self.statsTable, self.statsTableIndex) #-Basic Tab self.setBasicCount(self.contentBox, Globals.payloadList) ## Counts identical informationIDs of the list given as the first parameter # and fills the StatTable in SnifferStats. # This function can be further used to modify SnifferStats table. # Note: This function requires access to the tspDict # @param rList payloadList or filteredList # @param counter as counted list # @param statsTable member # @param statsTableIndex variable def fillStatTable(self, rList, counter, statsTable, statsTableIndex): try: for iD,amount in counter.items(): statsTable.insertRow(statsTableIndex) statsTable.setItem(statsTableIndex, 0, QTableWidgetItem(Globals.tspDict[iD][0])) statsTable.setItem(statsTableIndex, 1, QTableWidgetItem(str(iD))) statsTable.setItem(statsTableIndex, 2,QTableWidgetItem(str(amount))) statsTableIndex = statsTableIndex + 1 tList = self.snifferAPI.getSizeOfObjects(rList) statsTableIndex = 0 for size in tList: statsTable.setItem(statsTableIndex, 3, QTableWidgetItem(str(size))) statsTableIndex = statsTableIndex + 1 except Exception as e: print("Exception occurred: "+str(e)) ## Writes the PacketCount using getAllPayloadCount() to the label # specified as parameter # @param cLabel content label # @param rList payloadList or filteredList def setBasicCount(self, cLabel, rList): try: tList = self.snifferAPI.getSizeOfObjects(Globals.payloadList) myString = ("Total Packet Count (without failed): "+ str(self.snifferAPI.getAllPayloadCountWithoutFailed(Globals.payloadList, Globals.tspDict))+"\n" +"\nTotal Packet Count (all): "+ str(self.snifferAPI.getAllPayloadCountWithFailed(Globals.payloadList))+"\n" + "\nTotal load size: "+ str(self.snifferAPI.getListSize(Globals.payloadList))+"\n" + "\nMinimal packet size: "+str(self.snifferAPI.getMinSizeOfList(Globals.payloadList))+"\n" + "\nMaximal packet size: "+str(self.snifferAPI.getMaxSizeOfList(Globals.payloadList))+"\n" + "\nInfoID of minimal packet size: "+str(self.snifferAPI.getInfoIdOfMinObj(Globals.payloadList, Globals.tspDict)[0]) +" ("+str(self.snifferAPI.getInfoIdOfMinObj(Globals.payloadList, Globals.tspDict)[1])+")\n" + "\nInfoID of maximal packet size: "+str(self.snifferAPI.getInfoIdOfMaxObj(Globals.payloadList, Globals.tspDict)[0]) +" ("+str(self.snifferAPI.getInfoIdOfMaxObj(Globals.payloadList, Globals.tspDict)[1])+")\n" +"\nOccurrence of ID_MOVED_TASK_TO_READY_STATE: "+str(self.snifferAPI.getInfoIdTickCount(Globals.payloadList, 11))+" ticks \n" #id is here fix, group evaluates which types are most relevant +"\nCount of all non task objects : "+str(self.snifferAPI.getCountNonTaskObj(Globals.objectDict))+"\n" +"\nCount of task objects : "+str(self.snifferAPI.getCountTaskObj(Globals.objectDict))+"\n" +"\nAll objects: "+str(self.snifferAPI.getObjTypesList(Globals.objectDict))+"\n" +"\nTime of Measurement : "+str(self.snifferAPI.getMeasurementTimeSingleShot(Globals.payloadList))+" sec\n" +"\nAverage data rate : "+str(self.snifferAPI.getDatarate(Globals.payloadList))+" kbit/sec\n") cLabel.setText(myString) except Exception as e: print("Exception occurred: "+str(e)) ## Sets the SnifferUI def setSnifferStatsUi(self): self.setAdvancedTab() self.setBasicTab() ## Sets the Advanced Tab def setAdvancedTab(self): self.statsTableItem = QTableWidgetItem() self.statsTable.setRowCount(0) self.statsTable.setColumnCount(4) self.statsTable.setHorizontalHeaderLabels('InformationID;NumericID;Occurrence;PacketSize'.split(';')) self.statsTable.resizeColumnsToContents() self.statsTableHeader = self.statsTable.horizontalHeader() self.statsTableHeader.setSectionResizeMode(0, QHeaderView.ResizeToContents) self.statsTableHeader.setSectionResizeMode(1, QHeaderView.ResizeToContents) self.statsTableHeader.setSectionResizeMode(2, QHeaderView.ResizeToContents) self.statsTableHeader.setSectionResizeMode(3, QHeaderView.ResizeToContents) self.closeButt = QPushButton('Clear') self.closeButt.clicked.connect(self.clearTableStats) self.tabAdvanced.layout.addWidget(self.statsTable) self.tabAdvanced.layout.addWidget(self.closeButt) self.tabAdvanced.setLayout(self.tabAdvanced.layout) #------------------------------------ self.layout.addWidget(self.tabs) self.setLayout(self.layout) ## Sets the Basic Tab def setBasicTab(self): self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.contentBox) self.contentBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.scrollArea.setWidgetResizable(True) self.closeButt = QPushButton('Clear') self.closeButt.clicked.connect(self.clearLabelStats) self.tabBasic.layout.addWidget(self.scrollArea) self.tabBasic.layout.addWidget(self.closeButt) self.tabBasic.setLayout(self.tabBasic.layout) ## Clears the SnifferStats by calling an API function def clearTableStats(self): self.deleteStats(self.iDList) ## Clears the SnifferStats by calling an API function def clearLabelStats(self): self.contentBox.clear() ## Clears the StatsView and resets according lists # @param list2 with all infoIDs (corresponding to second parameter in getAllInfoIDs() def deleteStats(self, list2): self.statsTable.setRowCount(0) self.statsTableIndex = 0 self.counter = 0 list2[:] = []