def addTable(self, value): row = len(value) col = len(value[0]) self.comboBoxList = list() table = QTableWidget() table.setRowCount(row) table.setColumnCount(col) table.setHorizontalHeaderLabels(value[0]) table.horizontalHeader().setEnabled(False) table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) table.horizontalHeader().setDefaultAlignment(Qt.AlignCenter) table.verticalHeader().hide() for i, row in enumerate(value[1:]): for j, cell in enumerate(row): if isinstance(cell, dict): if not cell.get('select', False): newItem = QTableWidgetItem(cell.get('value', '')) newItem.setTextAlignment(Qt.AlignHCenter) newItem.setTextAlignment(Qt.AlignCenter) table.setItem(i, j, newItem) elif not cell.get('corresponding', False): newItem = QComboBox() newItem.setAcceptDrops(True) newItem.setStyleSheet( 'margin:0;padding:0;border:0.5pxbackground-color:white;text-align:center;vertical-align:middle;' ) newItem.setSizeAdjustPolicy(QComboBox.AdjustToContents) newItem.addItem(cell.get('value', '')) for sender in self.senderwindow.senderList[1:]: newItem.addItem(str(sender[0])) table.setCellWidget(i, j, newItem) table.cellWidget(i, j).currentTextChanged.connect( self.tableComboBoxChange) self.comboBoxList.append(newItem) else: newItem = QLineEdit() newItem.setStyleSheet( 'margin:0;padding:0;border:0.5px;text-align:center;background-color:white;vertical-align:middle;' ) newItem.setText(cell.get('value', '')) table.setCellWidget(i, j, newItem) elif isinstance(cell, str): newItem = QTableWidgetItem(cell) newItem.setTextAlignment(Qt.AlignHCenter) newItem.setTextAlignment(Qt.AlignCenter) table.setItem(i, j, newItem) QApplication.processEvents() table.setEnabled(False) self.tableWidget = table self.gridLayout.addWidget(self.tableWidget)
def _time_changed(self, tableWidget: QtWidgets.QTableWidget, row: int): self.tableWidget.setCurrentCell(row, self.tableWidget.currentColumn()) spinBegin = tableWidget.cellWidget(row, 1) spinEnd = tableWidget.cellWidget(row, 2) beginQ: QtCore.QTime = spinBegin.time() endQ = spinEnd.time() begin = datetime.strptime(beginQ.toString('hh:mm'), '%H:%M') end = datetime.strptime(endQ.toString('hh:mm'), '%H:%M') dt = (end - begin).seconds if dt < 0: dt += 24 * 3600 dt /= 60 tableWidget.item(row, 3).setText('%2d:%02d' % (int(dt / 60), dt % 60))
def _time_changed(self,tableWidget:QtWidgets.QTableWidget,row:int): self.tableWidget.setCurrentCell(row,self.tableWidget.currentColumn()) spinBegin = tableWidget.cellWidget(row,1) spinEnd = tableWidget.cellWidget(row,2) beginQ:QtCore.QTime = spinBegin.time() endQ = spinEnd.time() begin = datetime(1900,1,1,beginQ.hour(),beginQ.minute()) end = datetime(1900,1,1,endQ.hour(),endQ.minute()) dt = (end-begin).seconds if dt<0: dt+=24*3600 dt /= 60 tableWidget.item(row,3).setText('%2d:%02d'%(int(dt/60),dt%60))
def _ruler_interval_changed(self, now_line: int, tableWidget: QtWidgets.QTableWidget, mile: float): if self.updating: return # 重新计算均速 spinMin = tableWidget.cellWidget(now_line, 1) spinSec = tableWidget.cellWidget(now_line, 2) seconds = spinMin.value() * 60 + spinSec.value() speed_s = Line.speedStr(mile,seconds) tableWidget.item(now_line, 6).setText(speed_s) if not seconds: color = QtGui.QColor(Qt.red) color.setAlpha(150) tableWidget.item(now_line, 0).setBackground(QtGui.QBrush(color)) else: tableWidget.item(now_line, 0).setBackground(QtGui.QBrush(Qt.transparent)) if not seconds: # 这一行标红 color = QtGui.QColor(Qt.red) color.setAlpha(150) for col in range(tableWidget.columnCount()): try: tableWidget.item(now_line, col).setBackground(QtGui.QBrush(color)) except: pass else: for col in range(tableWidget.columnCount()): try: tableWidget.item(now_line, col).setBackground(QtGui.QBrush(Qt.transparent)) except: pass
def save_property(self, table: QTableWidget, stackwidget: QStackedWidget, listwidget: QListWidget, keyword: str = '') -> None: """ Saves the currently selected Property template to the config file. """ # Set None Item to prevent loss of the currently edited item: # The current item is closed and thus saved. table.setCurrentItem(None) selected_template_text = listwidget.currentIndex().data() table_data = [] ncolumns = table.rowCount() for rownum in range(ncolumns): try: # only one column! value = table.cellWidget(rownum, 0).getText() except AttributeError: value = '' if value: table_data.append(value) # make sure to have always a blank item first: table_data.insert(0, '') if keyword: # save as dictionary for properties to have "_cif_key : itemlist" # for a table item as dropdown menu in the main table. table_data = [keyword, table_data] self.settings.save_template_list('property/' + selected_template_text, table_data) stackwidget.setCurrentIndex(0) print('saved')
def __getFltrWidgets__(self, source: QtWidgets.QTableWidget) -> dict: """collects text from first row widgets in cat or trans table """ fltr = {} msg = '' for col_i in range(source.columnCount()): widget = source.cellWidget(0, col_i) widget_name = source.horizontalHeaderItem(col_i).text() if isinstance(widget, QtWidgets.QComboBox): widget_txt = widget.currentText() elif isinstance(widget, QtWidgets.QLineEdit): if widget.hasAcceptableInput() or widget.text() == '': widget_txt = widget.text() else: widget_txt = '' msg = ( f'shall have value between {widget.validator().bottom()} ' + f'and {widget.validator().top()} ' + f'with maximum {widget.validator().decimals()} decimals' ) msgBox = QtWidgets.QMessageBox() msgBox.setText(f'<b>column {widget_name}</b> ' + msg) msgBox.exec() return {} else: widget_txt = '' fltr[widget_name] = widget_txt return fltr
def update_replay_table_row(table: QTableWidget, row: int, game_data: GameData): checkbox: QCheckBox = table.cellWidget(row, 0).findChild(QCheckBox) checkbox.setChecked(game_data[2]) path = game_data[1] filename_item = create_replay_table_widget_item(path.name, tooltip=str(path)) table.setItem(row, table.columnCount() - 1, filename_item)
class ResultsWindow(QWidget): def __init__(self, raw_data: pandas.DataFrame): super().__init__() self.initUI(raw_data) def initUI(self, raw_data: pandas.DataFrame): start = time.process_time() norm_data = normalization(raw_data) self.roc_data = roc_analyze(norm_data["Class"], norm_data.iloc[:, 11:]) print(time.process_time() - start) layout = QGridLayout() self.table = QTableWidget() layout.addWidget(self.table) self.setLayout(layout) self.table.setColumnCount(3) self.table.setRowCount(len(self.roc_data)) value: ROC_curve_data for i, (key, value) in enumerate( sorted(self.roc_data.items(), key=lambda pair: pair[1].auc, reverse=True)): c = QCheckBox() self.table.setItem(i, 0, QTableWidgetItem(key)) self.table.setItem(i, 1, QTableWidgetItem(str(value.auc))) self.table.setCellWidget(i, 2, c) self.table.resizeColumnsToContents() draw_button = QPushButton("Построить график") draw_button.clicked.connect(self.draw_graph) layout.addWidget(draw_button) def draw_graph(self): picked_values = [] for i in range(self.table.rowCount()): if self.table.cellWidget(i, 2).isChecked(): picked_values.append(self.table.item(i, 0).text()) self.draw_roc_curve(self.roc_data, picked_values) @staticmethod def draw_roc_curve(roc_data: Dict[str, ROC_curve_data], miRNA_names): fig = plt.figure() for name in miRNA_names: plt.plot(roc_data[name].fpr, roc_data[name].tpr, label="{0}; auc={1:0.2f}".format(name, roc_data[name].auc)) plt.plot([0, 1], [0, 1], 'k--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC curve') plt.legend(loc="lower left", bbox_to_anchor=(1.05, 0)) plt.subplots_adjust(right=0.6) fig.set_size_inches(10, 5) plt.show()
class CtrlDialog(QDialog): def __init__(self, driverArr): super().__init__() self.driverArr = driverArr self.setWindowTitle('Assign Controller') self.vlayout = QVBoxLayout(self) self.table = QTableWidget(6, 2) self.table.verticalHeader().hide() self.vlayout.addWidget(self.table) self.table.setHorizontalHeaderLabels(['Driver', 'Controller']) for idx, driverObj in enumerate(driverArr): if idx < 6: ctrlCombobox = QComboBox() for ctrlItem in range(1, 7): ctrlCombobox.addItem(str(ctrlItem)) self.table.setItem(idx, 0, QTableWidgetItem(driverObj.name)) ctrlCombobox.setCurrentIndex(idx) self.table.setCellWidget(idx, 1, ctrlCombobox) self.setCtrlBtn = QPushButton('Set Controllers') self.closeBtn = QPushButton('Cancel') self.hlayout = QHBoxLayout() self.vlayout.addLayout(self.hlayout) self.hlayout.addWidget(self.setCtrlBtn) self.hlayout.addWidget(self.closeBtn) self.setCtrlBtn.clicked.connect(self.setNewCtrl) self.closeBtn.clicked.connect(self.reject) def setNewCtrl(self): self.newDriverArr = [None] * 8 for cellNum in range(0, 8): if cellNum < 6: self.newDriverArr[ int(self.table.cellWidget(cellNum, 1).currentText()) - 1] = self.driverArr[cellNum] self.driverArr[cellNum].setCtrlNum( int(self.table.cellWidget(cellNum, 1).currentText())) else: self.newDriverArr[cellNum] = self.driverArr[cellNum] self.accept()
class SelectActivities(QDialog, sweattrails.qt.imports.DownloadManager): select = pyqtSignal() def __init__(self, parent=None): super(SelectActivities, self).__init__(None) layout = QVBoxLayout(self) self.table = QTableWidget(None) self.table.setColumnCount(3) self.table.setHorizontalHeaderLabels(["", "Date", "Size"]) self.table.setColumnWidth(0, 25) self.table.setColumnWidth(1, 100) self.table.setColumnWidth(3, 80) layout.addWidget(self.table) self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonbox.accepted.connect(self.accept) self.buttonbox.rejected.connect(self.reject) self.select.connect(self._select) layout.addWidget(self.buttonbox) self.setMinimumSize(320, 200) self.before_download.connect(parent.before_download) self.after_download.connect(parent.after_download) self.ant_files = None def selectActivities(self, antfiles): logger.debug("SelectActivities.selectActivities") self.ant_files = antfiles self.select.emit() return self._selected def _select(self): logger.debug("SelectActivities._select") self.table.clear() self.table.setRowCount(len(self.ant_files)) for row in range(len(self.ant_files)): f = self.ant_files[row] self.table.setCellWidget(row, 0, QCheckBox(self)) self.table.setItem( row, 1, QTableWidgetItem(f.get_date().strftime("%d %b %Y %H:%M"))) self.table.setItem(row, 2, QTableWidgetItem("{:d}".format(f.get_size()))) result = self.exec_() self._selected = [] if result == QDialog.Accepted: for i in range(len(self.ant_files)): f = self.ant_files[i] cb = self.table.cellWidget(i, 0) if cb.isChecked(): self._selected.append(f)
def _updateTableRowData(tableWidget:QtWidgets.QTableWidget,row:int,info,mile,blocker,start,end): """ 已知这一行存在且各数据有效,使用info中的数据更新这一行的数据。 """ if info is None: info = {} item:QtWidgets.QTableWidgetItem = tableWidget.item(row,0) item.setText(f"{start}{blocker}{end}") item.setData(-1,[start,end]) int_sec = info.get("interval",0) tableWidget.cellWidget(row,1).setValue(int(int_sec/60)) tableWidget.cellWidget(row,2).setValue(int_sec%60) tableWidget.cellWidget(row,3).setValue(info.get("start",0)) tableWidget.cellWidget(row,4).setValue(info.get("stop",0)) tableWidget.item(row,5).setText(f"{mile:.3f}")
def _ruler_interval_changed(self, now_line: int, tableWidget: QtWidgets.QTableWidget, mile: float): if self.updating: return # 重新计算均速 spinMin = tableWidget.cellWidget(now_line, 1) spinSec = tableWidget.cellWidget(now_line, 2) seconds = spinMin.value() * 60 + spinSec.value() try: speed = 1000 * mile / (seconds) * 3.6 except ZeroDivisionError: speed = 0.0 color = QtGui.QColor(Qt.red) color.setAlpha(150) tableWidget.item(now_line, 0).setBackground(QtGui.QBrush(color)) else: tableWidget.item(now_line, 0).setBackground(QtGui.QBrush(Qt.transparent)) tableWidget.item(now_line, 6).setText("%.2f" % speed) if not seconds: # 这一行标红 color = QtGui.QColor(Qt.red) color.setAlpha(150) for col in range(tableWidget.columnCount()): try: tableWidget.item(now_line, col).setBackground(QtGui.QBrush(color)) except: pass else: for col in range(tableWidget.columnCount()): try: tableWidget.item(now_line, col).setBackground( QtGui.QBrush(Qt.transparent)) except: pass
class IP_list(QDialog): def __init__(self, root): super().__init__(root) self.main = root self.setWindowTitle('Список IP') self.setFixedWidth(504) self.layout_tw = QVBoxLayout(self) self.layout_b = QHBoxLayout() self.layout_b.addItem(QSpacerItem(150, 10, QSizePolicy.Expanding, QSizePolicy.Minimum)) self.tableWidget = QTableWidget(self) self.tableWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.tableWidget.setGeometry(QRect(20, 20, 464, 81)) self.tableWidget.setColumnCount(4) hor_header = self.tableWidget.horizontalHeader() hor_header.setSectionResizeMode(0, QHeaderView.Stretch) hor_header.setSectionResizeMode(1, QHeaderView.ResizeToContents) hor_header.setSectionResizeMode(2, QHeaderView.ResizeToContents) hor_header.setSectionResizeMode(3, QHeaderView.ResizeToContents) self.layout_tw.addWidget(self.tableWidget) self.layout_tw.addLayout(self.layout_b) self.pb_cle = QPushButton(self) self.pb_cle.setGeometry(QRect(0, 490, 21, 20)) self.pb_cle.setToolTip('Очистить таблицу') self.pb_cle.setIcon(QIcon('допочки\_broom.png')) self.pb_cle.clicked.connect(self.del_all) self.layout_b.addWidget(self.pb_cle) self.pb_row_add = QPushButton(self) self.pb_row_add.setGeometry(QRect(20, 490, 21, 20)) self.pb_row_add.setToolTip('Добавить строчку') self.pb_row_add.setIcon(QIcon('допочки\_+.png')) self.pb_row_add.clicked.connect(self.row_add) self.layout_b.addWidget(self.pb_row_add) self.pb_row_rem = QPushButton(self) self.pb_row_rem.setGeometry(QRect(50, 490, 21, 20)) self.pb_row_rem.setToolTip('Убрать строчку') self.pb_row_rem.setIcon(QIcon('допочки\_-.png')) self.pb_row_rem.clicked.connect(self.row_rem) self.layout_b.addWidget(self.pb_row_rem) self.pb_ip = QPushButton(self) self.pb_ip.setGeometry(QRect(430, 490, 21, 20)) self.pb_ip.setToolTip('Загрузить из файла') self.pb_ip.setIcon(QIcon('допочки\_ip.png')) self.pb_ip.clicked.connect(self.get_IPs) self.layout_b.addWidget(self.pb_ip) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(0, item) item.setText("IP адрес") item_2 = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(1, item_2) item_2.setText("Порт") item_3 = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(2, item_3) item_3.setText("Относится к") item_4 = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(3, item_4) item_4.setText("Проверка") self.tableWidget.cellChanged.connect(self.onCellChanged) def del_all(self): self.tableWidget.setRowCount(0) def row_add(self): i = self.tableWidget.rowCount() self.tableWidget.insertRow(i) vheader = self.tableWidget.verticalHeader() vheader.setSectionResizeMode(i, QHeaderView.ResizeToContents) combobox = QComboBox() combobox.addItem("Any") combobox.addItem("Source") combobox.addItem("Destination") self.tableWidget.setCellWidget(i, 2, combobox) item = QTableWidgetItem() brush = QBrush(QColor(0, 0, 0)) brush.setStyle(Qt.Dense4Pattern) self.tableWidget.setItem(i, 3, item) item.setFlags(Qt.ItemIsEnabled) item.setBackground(brush) def row_rem(self): cell = self.tableWidget.currentRow() self.tableWidget.removeRow(cell) def get_IPs(self): result, bullshit = QFileDialog.getOpenFileName(self, "Выберите txt/csv-файл", getcwd(), "files (*.txt; *.csv)") # нельзя нажимать на крест with open(str(result), "r") as fileInput: x = self.tableWidget.rowCount() for row in fileInput: if result.endswith("txt"): if ":" not in row: (ip, port) = (row.rstrip(), '') else: (ip, port) = row.split(":") port = port.rstrip() elif result.endswith("csv"): if ";" not in row: (ip, port) = (row.rstrip(), '') else: (ip, port) = row.split(";") port = port.rstrip() self.tableWidget.insertRow(x) vheader = self.tableWidget.verticalHeader() vheader.setSectionResizeMode(x, QHeaderView.ResizeToContents) self.tableWidget.setItem(x, 0, QTableWidgetItem(ip)) self.tableWidget.setItem(x, 1, QTableWidgetItem(port)) combobox = QComboBox() combobox.addItem("Any") combobox.addItem("Source") combobox.addItem("Destination") self.tableWidget.setCellWidget(x, 2, combobox) x += 1 def closeEvent(self, event): self.main.pt_addr.clear() for i in range(self.tableWidget.rowCount()): item = self.tableWidget.item(i, 3) if item is not None and item.background().color().name() == '#00ff00': self.main.pt_addr.appendPlainText("") for y in range(2): if self.tableWidget.item(i, y) is not None: self.main.pt_addr.insertPlainText(self.tableWidget.item(i, y).text()) else: self.main.pt_addr.insertPlainText("") if y < 2: self.main.pt_addr.insertPlainText(":") if self.tableWidget.cellWidget(i, 2).currentText() == "Any": self.main.pt_addr.insertPlainText("A") elif self.tableWidget.cellWidget(i, 2).currentText() == "Source": self.main.pt_addr.insertPlainText("S") else: self.main.pt_addr.insertPlainText("D") self.close() def onCellChanged(self, row, column): if column in (0, 1): item1 = self.tableWidget.item(row, 0) if item1 is not None: item1 = item1.text().replace(' ', '') try: ipaddress.ip_address(item1) except ValueError: if item1 == '': col0 = 2 else: col0 = 0 else: col0 = 1 else: col0 = 2 item2 = self.tableWidget.item(row, 1) if item2 is not None: item2 = item2.text().replace(' ', '') if item2.isnumeric() and int(item2) <= 65535: col1 = 1 elif item2 == '': col1 = 2 else: col1 = 0 else: col1 = 2 if (col0 == 0 and col1 == 0)\ or (col0 == 2 and col1 == 2): backgr = QTableWidgetItem() brush = QBrush(QColor(255, 0, 0)) brush.setStyle(Qt.SolidPattern) backgr.setBackground(brush) item = QTableWidgetItem() self.tableWidget.setItem(row, 3, item) item.setFlags(Qt.ItemIsEnabled) item.setBackground(brush) if (col0 == 0 and (col1 == 1 or col1 == 2))\ or (col1 == 0 and (col0 == 1 or col0 == 2)): backgr = QTableWidgetItem() brush = QBrush(QColor(255, 127, 0)) brush.setStyle(Qt.SolidPattern) backgr.setBackground(brush) item = QTableWidgetItem() self.tableWidget.setItem(row, 3, item) item.setFlags(Qt.ItemIsEnabled) item.setBackground(brush) if (col0 == 1 and (col1 == 1 or col1 == 2))\ or (col1 == 1 and (col0 == 1 or col0 == 2)): backgr = QTableWidgetItem() brush = QBrush(QColor(0, 255, 0)) brush.setStyle(Qt.SolidPattern) backgr.setBackground(brush) item = QTableWidgetItem() self.tableWidget.setItem(row, 3, item) item.setFlags(Qt.ItemIsEnabled) item.setBackground(brush) else: pass
class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__() self.setWindowTitle('Sign PDF GUI') self.author = kwargs['author'] self.version = kwargs['version'] self.cliApp = kwargs['cliApp'] self.title = 'Sign PDF GUI' cliAppBasename = os.path.splitext(self.cliApp)[0] scriptDir = os.path.dirname(os.path.realpath(__file__)) iconPath = os.path.sep.join([scriptDir, 'icon', cliAppBasename]) self.setWindowIcon(QIcon(iconPath)) self.listPdf = [] # List of pdfs self.listImage = [] # List of images if 'pdflist' in kwargs.keys() and len(kwargs['pdflist']) > 0: n = len(kwargs['pdflist']) for i in range(0, n): self.listPdf.append(os.path.realpath(kwargs['pdflist'][i])) self.left = 10 self.top = 10 self.width = 700 self.height = 480 self.setGeometry(self.left, self.top, self.width, self.height) self.btnWidth = 100 self.btnHeight = 30 self.selectAllWidth = 70 widget = QWidget() self.setCentralWidget(widget) self.vbox = QVBoxLayout() widget.setLayout(self.vbox) multiple = False threshold = 0.9 mask = "254,255,254,255,254,255" self.otherConfigs = { 'multiple': multiple, 'threshold': threshold, 'mask': mask } self.createPdfBox() self.createPdfTable() self.createImageBox() self.createImageTable() self.createButtonBox() self.createStatusBar() self.updatePdfTable() def createPdfBox(self): hbox = QHBoxLayout() self.vbox.addLayout(hbox) self.vbox.setAlignment(Qt.AlignTop) addPdfBtn = QPushButton("Add PDF", self) addPdfBtn.setFixedSize(self.btnWidth, self.btnHeight) addPdfBtn.clicked.connect(self.addPdfFiles) hbox.addWidget(addPdfBtn) delPdfBtn = QPushButton("Remove PDF", self) delPdfBtn.setFixedSize(self.btnWidth, self.btnHeight) delPdfBtn.clicked.connect(self.delPdfFiles) hbox.addWidget(delPdfBtn) hbox.addStretch(1) self.showGrid = QCheckBox("Show grid") self.showGrid.stateChanged.connect(self.showGridState) hbox.addWidget(self.showGrid) self.printCmd = QCheckBox("Print cmd") self.printCmd.stateChanged.connect(self.printCmdState) hbox.addWidget(self.printCmd) otherBtn = QPushButton("Others") otherBtn.setFixedSize(self.btnWidth, self.btnHeight) otherBtn.clicked.connect(self.otherBtn_clicked) hbox.addWidget(otherBtn) def createPdfTable(self): npdf = len(self.listPdf) self.pdfTable = QTableWidget() self.pdfTable.setRowCount(npdf) self.pdfTable.setColumnCount(2) self.pdfTable.setHorizontalHeaderLabels( "Select All;PDF Filename".split(";")) header = self.pdfTable.horizontalHeader() header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) header.resizeSection(0, self.selectAllWidth) self.vbox.setAlignment(Qt.AlignTop) # self.pdfTable.setMaximumHeight(self.tableMaxHeight) self.vbox.addWidget(self.pdfTable) # If header is clicked self.selectAllPdf = False header.sectionClicked.connect(self.onPdfTableHeaderClicked) def onPdfTableHeaderClicked(self, logicalIndex): n = len(self.listPdf) if logicalIndex == 0: # If the first row is clicked if not self.selectAllPdf: # If self.selectAllPdf is False self.selectAllPdf = True for r in range(0, n): self.pdfTable.cellWidget(r, 0).findChild(type( QCheckBox())).setChecked(True) else: self.selectAllPdf = False for r in range(0, n): self.pdfTable.cellWidget(r, 0).findChild(type( QCheckBox())).setChecked(False) def createImageBox(self): hbox = QHBoxLayout() self.vbox.addLayout(hbox) addImageBtn = QPushButton("Add Image") addImageBtn.setFixedSize(self.btnWidth, self.btnHeight) addImageBtn.clicked.connect(lambda x: self.addEditImage(False)) hbox.addWidget(addImageBtn) delImageBtn = QPushButton("Remove Image") delImageBtn.setFixedSize(self.btnWidth, self.btnHeight) delImageBtn.clicked.connect(self.delImageFiles) hbox.addWidget(delImageBtn) hbox.addStretch(1) def delImageFiles(self): # Clear the status message self.statusBar.clearMessage() self.selectAllImage = False n = len(self.listImage) for r in range(0, n): if self.imageTable.cellWidget(r, 0).findChild(type( QCheckBox())).isChecked(): # Remove the element from the list del self.listImage[r] # Insert blank in the list so that the number of # elements remain the same. self.listImage.insert(r, "") # Remove the blanks that had been inserted while ("" in self.listImage): self.listImage.remove("") # Update the table self.updateImageTable() return def createImageTable(self): n = len(self.listImage) self.imageTable = QTableWidget() self.imageTable.setRowCount(n) self.imageTable.setColumnCount(9) self.imageTable.setHorizontalHeaderLabels( "Select All;Edit;Image;Template;XValue;YValue;Scale;Page;Rotation". split(";")) header = self.imageTable.horizontalHeader() # header.setSectionResizeMode(1,QtWidgets.QHeaderView.Stretch) header.resizeSection(0, self.selectAllWidth) header.resizeSection(1, 46) self.vbox.setAlignment(Qt.AlignTop) # self.imageTable.setMaximumHeight(self.tableMaxHeight) self.vbox.addWidget(self.imageTable) # If header is clicked self.selectAllImage = False header.sectionClicked.connect(self.onImageTableHeaderClicked) self.imageTable.itemChanged.connect(self.itemChangedText) return # If cell value have changed, then update them on the dictionary def itemChangedText(self, item): row = item.row() col = item.column() # Get the 'key' = column header key = self.imageTable.horizontalHeaderItem(col).text().lower() # Get the 'value' = cell value from the table value = str(self.imageTable.item(row, col).text()) # Update the dictionary self.listImage[row].update_info(key, value) return # If image header has been clicked def onImageTableHeaderClicked(self, logicalIndex): n = len(self.listImage) if logicalIndex == 0: # If the first row is clicked if not self.selectAllImage: # If self.selectAllImage is False self.selectAllImage = True for r in range(0, n): self.imageTable.cellWidget(r, 0).findChild( type(QCheckBox())).setChecked(True) else: self.selectAllImage = False for r in range(0, n): self.imageTable.cellWidget(r, 0).findChild( type(QCheckBox())).setChecked(False) def updateImageTable(self): n = len(self.listImage) # Block the signals so that any editing doesn't call any signal self.imageTable.blockSignals(True) # Clears the table self.imageTable.setRowCount(0) # Create an empty list of 'Edit' buttons self.editImageBtn = [] for row in range(0, n): # Insert a new row self.imageTable.insertRow(row) # Insert a checkbox in the first column (col = 0) qw = QWidget() self.checkbox = QCheckBox() self.checkbox.setCheckState(Qt.Unchecked) tabhlayout = QHBoxLayout(qw) tabhlayout.addWidget(self.checkbox) tabhlayout.setAlignment(Qt.AlignCenter) tabhlayout.setContentsMargins(0, 0, 0, 0) self.imageTable.setCellWidget(row, 0, qw) # Insert a checkbox in the second column (col = 1) # Append to the list of 'Edit' buttons self.editImageBtn.append(QPushButton('Edit')) self.editImageBtn[row].setStyleSheet('margin:3px') self.imageTable.setCellWidget(row, 1, self.editImageBtn[row]) self.editImageBtn[row].clicked.connect( lambda x: self.addEditImage(True)) for col in range(2, 9): # Get the column header in lowercase colheader = self.imageTable.horizontalHeaderItem( col).text().lower() if colheader == 'image' or colheader == 'template': # If the column header is 'image' or 'template', then # get the file basename and also make the cells read-only itemString = os.path.basename( str(self.listImage[row].info[colheader])) item = QTableWidgetItem(itemString) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) else: # Just get the value from the dictionary itemString = str(self.listImage[row].info[colheader]) item = QTableWidgetItem(itemString) # Align and insert the value in the cell item.setTextAlignment(Qt.AlignCenter) self.imageTable.setItem(row, col, item) self.imageTable.blockSignals(False) # Add or edit the image info def addEditImage(self, editBool): # Clear the status message self.statusBar.clearMessage() dlg = ImageOptionsDialog(self) # If edit then if editBool: # Get the row number 'r' buttonClicked = self.sender() index = self.imageTable.indexAt(buttonClicked.pos()) r = index.row() # Get the r-th row dictionary imageInfo = self.listImage[r].get_dict() # Insert the image info in the dialog dlg.editInfoDialog(imageInfo) if dlg.exec_() == ImageOptionsDialog.Accepted: data = dlg.get_output() if editBool: # If edit, the replace the original content with # the new content self.listImage[r] = data['image'] self.listImage[r] = ImageOptions(data) else: # If not editing old info, then add it to the end self.listImage.append(data['image']) k = len(self.listImage) self.listImage[k - 1] = ImageOptions(data) # Update the image table self.updateImageTable() return def createButtonBox(self): hbox = QHBoxLayout() self.vbox.addLayout(hbox) aboutBtn = QPushButton("About") aboutBtn.setFixedSize(self.btnWidth, self.btnHeight) aboutBtn.clicked.connect(self.aboutBtn_clicked) hbox.addWidget(aboutBtn, alignment=Qt.AlignLeft) self.helpBtn = QPushButton("Help") self.helpBtn.setFixedSize(self.btnWidth, self.btnHeight) self.helpBtn.clicked.connect(self.helpBtn_clicked) hbox.addWidget(self.helpBtn) hbox.addStretch(1) self.applyBtn = QPushButton("Apply") self.applyBtn.setFixedSize(self.btnWidth, self.btnHeight) self.applyBtn.clicked.connect(self.applyBtn_clicked) hbox.addWidget(self.applyBtn) quitBtn = QPushButton("Quit") quitBtn.setFixedSize(self.btnWidth, self.btnHeight) quitBtn.clicked.connect(self.close) hbox.addWidget(quitBtn) return def aboutBtn_clicked(self): # Clear the status message self.statusBar.clearMessage() infoMsg = ('Version: ' + self.version + '\n' + 'Author: ' + self.author) dlg = MessageDialog(title=self.title + ': About', text='Sign PDF GUI', informativeText=infoMsg, icon=QStyle.SP_MessageBoxInformation) dlg.setMinimumWidth(300) dlg.exec_() return def helpBtn_clicked(self): cmd = self.cliApp + ' --help' self.proc = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE) stdout, stderr = self.proc.communicate() rtn = self.proc.returncode if rtn != 0: print("Problem getting help text.") return rtn msg = self.cliApp + ' --help' detailedMsg = stdout.decode("utf-8") dlg = MessageDialog( title=self.title + ': Help', icon=QStyle.SP_MessageBoxInformation, text=msg, detailedText=detailedMsg, ) dlg.setMinimumSize(550, 400) dlg.exec_() return def applyBtn_clicked(self): n = len(self.listPdf) if n == 0: dlg = MessageDialog(title=self.title + ': Error', text='Warning: No pdf file supplied.', icon=QStyle.SP_MessageBoxCritical) dlg.exec_() return self.pd = ProgressDialog() self.pd.setMinimum(0) self.pd.setMaximum(n) self.pd.setFormat("%v/%m") self.work = Worker(self) self.thread = Thread(target=self.work.run) self.thread.start() if self.pd.exec_() == ProgressDialog.Rejected: self.work.terminate() def createStatusBar(self): self.statusBar = QStatusBar() self.setStatusBar(self.statusBar) return def addPdfFiles(self): # Clear the status message self.statusBar.clearMessage() options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog files, _ = (QFileDialog.getOpenFileNames( self, "QFileDialog.getOpenFileNames()", "", "PDF Files (*.pdf)", options=options)) if files: self.listPdf.extend(files) self.updatePdfTable() def updatePdfTable(self): n = len(self.listPdf) self.pdfTable.setRowCount(0) # Clear the table for r in range(0, n): self.pdfTable.insertRow(r) qw = QWidget() self.checkbox = QCheckBox() self.checkbox.setCheckState(Qt.Unchecked) tabhlayout = QHBoxLayout(qw) tabhlayout.addWidget(self.checkbox) tabhlayout.setAlignment(Qt.AlignCenter) tabhlayout.setContentsMargins(0, 0, 0, 0) self.pdfTable.setCellWidget(r, 0, qw) item = QTableWidgetItem(self.listPdf[r]) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self.pdfTable.setItem(r, 1, item) def showGridState(self): self.statusBar.clearMessage() return def printCmdState(self): self.statusBar.clearMessage() return def delPdfFiles(self): # Clear the status message self.statusBar.clearMessage() self.selectAllPdf = False n = len(self.listPdf) for r in range(0, n): if self.pdfTable.cellWidget(r, 0).findChild(type( QCheckBox())).isChecked(): # Remove the element from the list del self.listPdf[r] # Insert blank in the list so that the number of # elements remain the same. self.listPdf.insert(r, "") # Remove the blanks that had been inserted while ("" in self.listPdf): self.listPdf.remove("") # Update the table self.updatePdfTable() return def otherBtn_clicked(self): dlg = OtherDialog(self.otherConfigs) if dlg.exec_() == OtherDialog.Accepted: self.otherConfigs = dlg.get_output() return
class NetProt_list(QDialog): def __init__(self, root): super().__init__(root) self.main = root self.setWindowTitle('Список протоколов Сетевого уровня') self.resize(900, 900) self.layout_tw = QVBoxLayout(self) self.layout_b = QHBoxLayout() self.tableWidget = QTableWidget() self.tableWidget.setGeometry(QRect(20, 20, 450, 81)) self.tableWidget.setColumnCount(4) hor_header = self.tableWidget.horizontalHeader() hor_header.setSectionResizeMode(0, QHeaderView.ResizeToContents) hor_header.setSectionResizeMode(1, QHeaderView.ResizeToContents) hor_header.setSectionResizeMode(2, QHeaderView.ResizeToContents) hor_header.setSectionResizeMode(3, QHeaderView.ResizeToContents) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableWidget.setRowCount(1) self.layout_tw.addWidget(self.tableWidget) self.layout_tw.addLayout(self.layout_b) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(0, item) item.setText("Выбрать") item_2 = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(1, item_2) item_2.setText("Hex Код") item_3 = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(2, item_3) item_3.setText("Dec Код") item_4 = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(3, item_4) item_4.setText("Наименование") self.tableWidget.verticalHeader().setVisible(False) self.tableWidget.horizontalHeader().setFont(QFont('Arial', weight=QFont.UltraExpanded)) cell_widget = QWidget() cb = QCheckBox() lay_out = QHBoxLayout(cell_widget) lay_out.addWidget(cb) lay_out.setAlignment(Qt.AlignCenter) lay_out.setContentsMargins(0, 0, 0, 0) cell_widget.setLayout(lay_out) self.tableWidget.setCellWidget(0, 0, cell_widget) ProtFile = open('допочки\PrNmNetCatalog.txt') x = 0 for row in ProtFile: net_hcod, net_dcod, net_pr = row.split("\t") vheader = self.tableWidget.verticalHeader() vheader.setSectionResizeMode(x, QHeaderView.ResizeToContents) self.tableWidget.setItem(x, 1, QTableWidgetItem(net_hcod)) self.tableWidget.setItem(x, 2, QTableWidgetItem(net_dcod)) self.tableWidget.setItem(x, 3, QTableWidgetItem(net_pr)) x += 1 if x == 53: continue else: self.tableWidget.insertRow(x) cell_widget = QWidget() cb = QCheckBox() lay_out = QHBoxLayout(cell_widget) lay_out.addWidget(cb) lay_out.setAlignment(Qt.AlignCenter) lay_out.setContentsMargins(0, 0, 0, 0) cell_widget.setLayout(lay_out) self.tableWidget.setCellWidget(x, 0, cell_widget) self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) def closeEvent(self, event): cnt = 0 self.main.netprot_mass = [] self.main.pt_netpr.clear() for i in range(self.tableWidget.rowCount()): if self.tableWidget.cellWidget(i, 0).findChild(type(QCheckBox())).checkState() == 2: if cnt == 1: self.main.pt_netpr.insertPlainText(", ") self.main.pt_netpr.insertPlainText(self.tableWidget.item(i, 3).text().rstrip()) self.main.pt_netpr.insertPlainText(" ") cnt = 1 self.main.netprot_mass.append(int(self.tableWidget.item(i, 2).text())) self.close()
def enable_all_checkboxes(table: QTableWidget): rows = table.rowCount() for row in range(rows): cell_widget = table.cellWidget(row, 0) cell_widget.findChild(QCheckBox).setDisabled(False)
class addTileDialog(QDialog): output = None ready = False def __init__(self): super().__init__() self.tilename = QComboBox() for tile in tilelist.tilelist: self.tilename.addItem(tile.__name__, tile) self.tilename.currentIndexChanged.connect(self.setTable) okbtn = QPushButton('Ok') okbtn.clicked.connect(self.onOk) clbtn = QPushButton('Cancel') clbtn.clicked.connect(self.onCancel) self.table = QTableWidget(2, 2) self.setTable(self.tilename.currentIndex()) hbox = QHBoxLayout() hbox.addWidget(clbtn) hbox.addWidget(okbtn) vbox = QVBoxLayout() vbox.addWidget(self.tilename) vbox.addWidget(self.table) vbox.addLayout(hbox) self.setLayout(vbox) self.resize(400, 300) self.table.setColumnWidth(1, 250) self.setModal(True) self.show() def setTable(self, index): try: raw = 2 + len(self.tilename.itemData(index).extraText) except TypeError: raw = 2 self.table.setRowCount(raw) self.table.setItem(0, 0, QTableWidgetItem('X position')) self.table.setCellWidget(0, 1, QSpinBox()) self.table.setItem(1, 0, QTableWidgetItem('Y position')) self.table.setCellWidget(1, 1, QSpinBox()) if self.tilename.itemData(index).extraText != None: i = 0 for line in self.tilename.itemData(index).extraText: self.table.setItem(2 + i, 0, QTableWidgetItem(line)) self.table.setCellWidget(2 + i, 1, QLineEdit('')) i += 1 def getParams(self): x = self.table.cellWidget(0, 1).value() y = self.table.cellWidget(1, 1).value() extra = None if self.tilename.currentData().extraTypes != None: i = 0 extra = [] for t in self.tilename.currentData().extraTypes: if t == 'bool': extra.append(bool(self.table.cellWidget(2 + i, 1).text())) elif t == 'int': extra.append(int(self.table.cellWidget(2 + i, 1).text())) elif t == 'float': extra.append(float(self.table.cellWidget(2 + i, 1).text())) elif t == 'str': extra.append(str(self.table.cellWidget(2 + i, 1).text())) else: extra.append(str(self.table.cellWidget(2 + i, 1).text())) i += 1 return (x, y, extra) def getTileParams(self): return self.output def onOk(self): self.output = (self.tilename.currentData(), self.getParams()) self.ready = True self.accept() def onCancel(self): self.output = (self.tilename.currentData(), self.getParams()) self.ready = True self.reject()
class AlarmDlg(ArtisanResizeablDialog): def __init__(self, parent = None, aw = None): super(AlarmDlg,self).__init__(parent, aw) self.setModal(True) self.setWindowTitle(QApplication.translate("Form Caption","Alarms",None)) self.helpdialog = None # restore window position settings = QSettings() if settings.contains("AlarmsGeometry"): self.restoreGeometry(settings.value("AlarmsGeometry")) #table for alarms self.alarmtable = QTableWidget() self.createalarmtable() self.alarmtable.itemSelectionChanged.connect(self.selectionChanged) allonButton = QPushButton(QApplication.translate("Button","All On",None)) allonButton.clicked.connect(self.alarmsAllOn) allonButton.setFocusPolicy(Qt.NoFocus) alloffButton = QPushButton(QApplication.translate("Button","All Off",None)) alloffButton.clicked.connect(self.alarmsAllOff) alloffButton.setFocusPolicy(Qt.NoFocus) addButton = QPushButton(QApplication.translate("Button","Add",None)) addButton.clicked.connect(self.addalarm) addButton.setMinimumWidth(80) addButton.setFocusPolicy(Qt.NoFocus) self.insertButton = QPushButton(QApplication.translate("Button","Insert",None)) self.insertButton.clicked.connect(self.insertalarm) self.insertButton.setMinimumWidth(80) self.insertButton.setFocusPolicy(Qt.NoFocus) self.insertButton.setEnabled(False) deleteButton = QPushButton(QApplication.translate("Button","Delete",None)) deleteButton.clicked.connect(self.deletealarm) deleteButton.setMinimumWidth(80) deleteButton.setFocusPolicy(Qt.NoFocus) self.copyalarmTableButton = QPushButton(QApplication.translate("Button", "Copy Table",None)) self.copyalarmTableButton.setToolTip(QApplication.translate("Tooltip","Copy table to clipboard, OPTION or ALT click for tabular text",None)) self.copyalarmTableButton.setFocusPolicy(Qt.NoFocus) self.copyalarmTableButton.clicked.connect(self.copyAlarmTabletoClipboard) importButton = QPushButton(QApplication.translate("Button","Load",None)) importButton.clicked.connect(self.importalarms) importButton.setMinimumWidth(80) importButton.setFocusPolicy(Qt.NoFocus) exportButton = QPushButton(QApplication.translate("Button","Save",None)) exportButton.clicked.connect(self.exportalarms) exportButton.setMinimumWidth(80) exportButton.setFocusPolicy(Qt.NoFocus) # connect the ArtisanDialog standard OK/Cancel buttons self.dialogbuttons.accepted.connect(self.closealarms) self.dialogbuttons.removeButton(self.dialogbuttons.button(QDialogButtonBox.Cancel)) helpButton = QPushButton(QApplication.translate("Button","Help",None)) helpButton.setToolTip(QApplication.translate("Tooltip","Show help",None)) helpButton.setFocusPolicy(Qt.NoFocus) helpButton.setMinimumWidth(80) helpButton.clicked.connect(self.showAlarmbuttonhelp) clearButton = QPushButton(QApplication.translate("Button","Clear",None)) clearButton.setToolTip(QApplication.translate("Tooltip","Clear alarms table",None)) clearButton.setFocusPolicy(Qt.NoFocus) clearButton.setMinimumWidth(80) clearButton.clicked.connect(self.clearalarms) self.loadAlarmsFromProfile = QCheckBox(QApplication.translate("CheckBox", "Load from profile",None)) self.loadAlarmsFromProfile.setChecked(self.aw.qmc.loadalarmsfromprofile) self.loadAlarmsFromBackground = QCheckBox(QApplication.translate("CheckBox", "Load from background",None)) self.loadAlarmsFromBackground.setChecked(self.aw.qmc.loadalarmsfrombackground) self.popupTimoutSpinBox = QSpinBox() self.popupTimoutSpinBox.setSuffix("s") self.popupTimoutSpinBox.setSingleStep(1) self.popupTimoutSpinBox.setRange(0,120) self.popupTimoutSpinBox.setAlignment(Qt.AlignRight) self.popupTimoutSpinBox.setValue(self.aw.qmc.alarm_popup_timout) popupTimeoutLabel = QLabel(QApplication.translate("Label", "PopUp TimeOut",None)) self.alarmsfile = QLabel(self.aw.qmc.alarmsfile) self.alarmsfile.setAlignment(Qt.AlignRight) self.alarmsfile.setMinimumWidth(300) self.alarmsfile.setSizePolicy(QSizePolicy.MinimumExpanding,QSizePolicy.Preferred) tablelayout = QVBoxLayout() buttonlayout = QHBoxLayout() okbuttonlayout = QHBoxLayout() mainlayout = QVBoxLayout() tablelayout.addWidget(self.alarmtable) buttonlayout.addWidget(addButton) buttonlayout.addWidget(self.insertButton) buttonlayout.addWidget(deleteButton) buttonlayout.addWidget(self.copyalarmTableButton) buttonlayout.addStretch() buttonlayout.addSpacing(10) buttonlayout.addWidget(allonButton) buttonlayout.addWidget(alloffButton) buttonlayout.addStretch() buttonlayout.addSpacing(10) buttonlayout.addWidget(importButton) buttonlayout.addWidget(exportButton) buttonlayout.addStretch() buttonlayout.addSpacing(15) buttonlayout.addWidget(clearButton) buttonlayout.addStretch() buttonlayout.addSpacing(15) buttonlayout.addWidget(helpButton) okbuttonlayout.addWidget(self.loadAlarmsFromProfile) okbuttonlayout.addSpacing(10) okbuttonlayout.addWidget(self.loadAlarmsFromBackground) okbuttonlayout.addSpacing(15) okbuttonlayout.addWidget(popupTimeoutLabel) okbuttonlayout.addWidget(self.popupTimoutSpinBox) okbuttonlayout.addWidget(self.alarmsfile) okbuttonlayout.addSpacing(15) okbuttonlayout.addWidget(self.dialogbuttons) mainlayout.addLayout(tablelayout) mainlayout.addLayout(buttonlayout) mainlayout.addLayout(okbuttonlayout) self.setLayout(mainlayout) self.dialogbuttons.button(QDialogButtonBox.Ok).setFocus() @pyqtSlot() def selectionChanged(self): selected = self.alarmtable.selectedRanges() if selected and len(selected) > 0: self.insertButton.setEnabled(True) else: self.insertButton.setEnabled(False) def deselectAll(self): selected = self.alarmtable.selectedRanges() if selected and len(selected) > 0: self.alarmtable.setRangeSelected(selected[0],False) @pyqtSlot(bool) def clearalarms(self): self.aw.qmc.alarmtablecolumnwidths = [self.alarmtable.columnWidth(c) for c in range(self.alarmtable.columnCount())] self.aw.qmc.alarmsfile = "" self.alarmsfile.setText(self.aw.qmc.alarmsfile) self.aw.qmc.alarmflag = [] self.aw.qmc.alarmguard = [] self.aw.qmc.alarmnegguard = [] self.aw.qmc.alarmtime = [] self.aw.qmc.alarmoffset = [] self.aw.qmc.alarmcond = [] self.aw.qmc.alarmstate = [] self.aw.qmc.alarmsource = [] self.aw.qmc.alarmtemperature = [] self.aw.qmc.alarmaction = [] self.aw.qmc.alarmbeep = [] self.aw.qmc.alarmstrings = [] self.alarmtable.setSortingEnabled(False) self.alarmtable.setRowCount(0) self.alarmtable.setSortingEnabled(True) @pyqtSlot(bool) def alarmsAllOn(self,_): self.alarmson(1) @pyqtSlot(bool) def alarmsAllOff(self,_): self.alarmson(0) def alarmson(self,flag): for i in range(len(self.aw.qmc.alarmflag)): if flag == 1: self.aw.qmc.alarmflag[i] = 1 else: self.aw.qmc.alarmflag[i] = 0 self.createalarmtable() @pyqtSlot(bool) def addalarm(self,_): alarm_flag = 1 alarm_guard = -1 alarm_negguard = -1 alarm_time = -1 alarm_offset = 0 alarm_cond = 1 alarm_state = -1 alarm_source = 1 alarm_temperature = 500. alarm_action = 0 alarm_beep = 0 alarm_string = QApplication.translate("Label","Enter description",None) selected = self.alarmtable.selectedRanges() if len(selected) > 0: self.savealarms() # we first "save" the alarmtable to be able to pick up the values of the selected row selected_idx = selected[0].topRow() selected_idx = int(self.alarmtable.item(selected_idx,0).text()) -1 # we derref the rows number that might be different per sorting order try: alarm_flag = self.aw.qmc.alarmflag[selected_idx] alarm_guard = self.aw.qmc.alarmguard[selected_idx] alarm_negguard = self.aw.qmc.alarmnegguard[selected_idx] alarm_time = self.aw.qmc.alarmtime[selected_idx] alarm_offset = self.aw.qmc.alarmoffset[selected_idx] alarm_cond = self.aw.qmc.alarmcond[selected_idx] alarm_state = self.aw.qmc.alarmstate[selected_idx] alarm_source = self.aw.qmc.alarmsource[selected_idx] alarm_temperature = self.aw.qmc.alarmtemperature[selected_idx] alarm_action = self.aw.qmc.alarmaction[selected_idx] alarm_beep = self.aw.qmc.alarmbeep[selected_idx] alarm_string= self.aw.qmc.alarmstrings[selected_idx] except: pass self.aw.qmc.alarmflag.append(alarm_flag) self.aw.qmc.alarmguard.append(alarm_guard) self.aw.qmc.alarmnegguard.append(alarm_negguard) self.aw.qmc.alarmtime.append(alarm_time) self.aw.qmc.alarmoffset.append(alarm_offset) self.aw.qmc.alarmcond.append(alarm_cond) self.aw.qmc.alarmstate.append(alarm_state) self.aw.qmc.alarmsource.append(alarm_source) self.aw.qmc.alarmtemperature.append(alarm_temperature) self.aw.qmc.alarmaction.append(alarm_action) self.aw.qmc.alarmbeep.append(alarm_beep) self.aw.qmc.alarmstrings.append(alarm_string) self.alarmtable.setSortingEnabled(False) nalarms = self.alarmtable.rowCount() self.alarmtable.setRowCount(nalarms + 1) self.setalarmtablerow(nalarms) header = self.alarmtable.horizontalHeader() header.setStretchLastSection(True) if len(self.aw.qmc.alarmflag) == 1: # only for the first entry we apply some default column width # improve width of Qlineedit columns self.alarmtable.resizeColumnsToContents() self.alarmtable.setColumnWidth(1,50) self.alarmtable.setColumnWidth(2,50) self.alarmtable.setColumnWidth(3,50) self.alarmtable.setColumnWidth(4,90) self.alarmtable.setColumnWidth(5,50) self.alarmtable.setColumnWidth(6,70) self.alarmtable.setColumnWidth(7,90) self.alarmtable.setColumnWidth(8,50) self.alarmtable.setColumnWidth(9,90) # remember the columnwidth for i in range(len(self.aw.qmc.alarmtablecolumnwidths)): try: self.alarmtable.setColumnWidth(i,self.aw.qmc.alarmtablecolumnwidths[i]) except: pass self.alarmtable.setSortingEnabled(True) else: self.deselectAll() # select newly added row i.e. the last one self.alarmtable.setRangeSelected(QTableWidgetSelectionRange(nalarms,0,nalarms,self.alarmtable.columnCount()-1),True) header.setStretchLastSection(True) self.markNotEnabledAlarmRows() self.alarmtable.setSortingEnabled(True) # self.alarmtable.viewport().update() # self.alarmtable.update() # self.repaint() @pyqtSlot(bool) def insertalarm(self,_): self.alarmtable.setSortingEnabled(False) nalarms = self.alarmtable.rowCount() if nalarms: alarm_flag = 1 alarm_guard = -1 alarm_negguard = -1 alarm_time = -1 alarm_offset = 0 alarm_cond = 1 alarm_state = 0 alarm_source = 1 alarm_temperature = 500. alarm_action = 0 alarm_beep = 0 alarm_string = QApplication.translate("Label","Enter description",None) # check for selection selected = self.alarmtable.selectedRanges() if selected and len(selected) > 0: self.savealarms() # we first "save" the alarmtable to be able to pick up the values of the selected row selected_row = selected[0].topRow() selected_row = int(self.alarmtable.item(selected_row,0).text()) -1 # we derref the rows number that might be different per sorting order try: alarm_flag = self.aw.qmc.alarmflag[selected_row] alarm_guard = self.aw.qmc.alarmguard[selected_row] alarm_negguard = self.aw.qmc.alarmnegguard[selected_row] alarm_time = self.aw.qmc.alarmtime[selected_row] alarm_offset = self.aw.qmc.alarmoffset[selected_row] alarm_cond = self.aw.qmc.alarmcond[selected_row] alarm_state = self.aw.qmc.alarmstate[selected_row] alarm_source = self.aw.qmc.alarmsource[selected_row] alarm_temperature = self.aw.qmc.alarmtemperature[selected_row] alarm_action = self.aw.qmc.alarmaction[selected_row] alarm_beep = self.aw.qmc.alarmbeep[selected_row] alarm_string= self.aw.qmc.alarmstrings[selected_row] except: pass self.aw.qmc.alarmflag.insert(selected_row,alarm_flag) self.aw.qmc.alarmguard.insert(selected_row,alarm_guard) self.aw.qmc.alarmnegguard.insert(selected_row,alarm_negguard) self.aw.qmc.alarmtime.insert(selected_row,alarm_time) self.aw.qmc.alarmoffset.insert(selected_row,alarm_offset) self.aw.qmc.alarmcond.insert(selected_row,alarm_cond) self.aw.qmc.alarmstate.insert(selected_row,alarm_state) self.aw.qmc.alarmsource.insert(selected_row,alarm_source) self.aw.qmc.alarmtemperature.insert(selected_row,alarm_temperature) self.aw.qmc.alarmaction.insert(selected_row,alarm_action) self.aw.qmc.alarmbeep.insert(selected_row,alarm_beep) self.aw.qmc.alarmstrings.insert(selected_row,alarm_string) self.alarmtable.insertRow(selected_row) self.setalarmtablerow(selected_row) # self.alarmtable.resizeColumnsToContents() # # improve width of Qlineedit columns # self.alarmtable.setColumnWidth(2,50) # self.alarmtable.setColumnWidth(3,50) # self.alarmtable.setColumnWidth(5,50) # self.alarmtable.setColumnWidth(6,80) # self.alarmtable.setColumnWidth(8,40) header = self.alarmtable.horizontalHeader() header.setStretchLastSection(False) self.deselectAll() # select newly inserted item self.alarmtable.setRangeSelected(QTableWidgetSelectionRange(selected_row,0,selected_row,self.alarmtable.columnCount()-1),True) header.setStretchLastSection(True) self.markNotEnabledAlarmRows() self.alarmtable.sortItems(0, Qt.AscendingOrder) # we first have to sort the table according to the row numbers # we no re-number rows self.renumberRows() # we correct the IfAlarm and ButNot references to items after the inserted one for i in range(self.alarmtable.rowCount()): guard = self.alarmtable.cellWidget(i,2) try: guard_value = int(str(guard.text())) - 1 except Exception: guard_value = -1 if guard_value >= selected_row: guard.setText(str(guard_value+2)) nguard = self.alarmtable.cellWidget(i,3) try: nguard_value = int(str(nguard.text())) - 1 except Exception: nguard_value = -1 if nguard_value >= selected_row: nguard.setText(str(nguard_value+2)) self.alarmtable.setSortingEnabled(True) def renumberRows(self): for i in range(self.alarmtable.rowCount()): self.alarmtable.setItem(i, 0, MyTableWidgetItemInt(str(i+1),i)) @pyqtSlot(bool) def deletealarm(self,_): self.aw.qmc.alarmtablecolumnwidths = [self.alarmtable.columnWidth(c) for c in range(self.alarmtable.columnCount())] self.alarmtable.setSortingEnabled(False) nalarms = self.alarmtable.rowCount() if nalarms: # check for selection selected = self.alarmtable.selectedRanges() if selected and len(selected) > 0: selected_row = selected[0].topRow() selected_row = int(self.alarmtable.item(selected_row,0).text()) -1 # we derref the rows number that might be different per sorting order self.alarmtable.removeRow(selected_row) self.aw.qmc.alarmflag = self.aw.qmc.alarmflag[0:selected_row] + self.aw.qmc.alarmflag[selected_row + 1:] self.aw.qmc.alarmguard = self.aw.qmc.alarmguard[0:selected_row] + self.aw.qmc.alarmguard[selected_row + 1:] self.aw.qmc.alarmnegguard = self.aw.qmc.alarmnegguard[0:selected_row] + self.aw.qmc.alarmnegguard[selected_row + 1:] self.aw.qmc.alarmtime = self.aw.qmc.alarmtime[0:selected_row] + self.aw.qmc.alarmtime[selected_row + 1:] self.aw.qmc.alarmoffset = self.aw.qmc.alarmoffset[0:selected_row] + self.aw.qmc.alarmoffset[selected_row + 1:] self.aw.qmc.alarmcond = self.aw.qmc.alarmcond[0:selected_row] + self.aw.qmc.alarmcond[selected_row + 1:] self.aw.qmc.alarmstate = self.aw.qmc.alarmstate[0:selected_row] + self.aw.qmc.alarmstate[selected_row + 1:] self.aw.qmc.alarmsource = self.aw.qmc.alarmsource[0:selected_row] + self.aw.qmc.alarmsource[selected_row + 1:] self.aw.qmc.alarmtemperature = self.aw.qmc.alarmtemperature[0:selected_row] + self.aw.qmc.alarmtemperature[selected_row + 1:] self.aw.qmc.alarmaction = self.aw.qmc.alarmaction[0:selected_row] + self.aw.qmc.alarmaction[selected_row + 1:] self.aw.qmc.alarmbeep = self.aw.qmc.alarmbeep[0:selected_row] + self.aw.qmc.alarmbeep[selected_row + 1:] self.aw.qmc.alarmstrings = self.aw.qmc.alarmstrings[0:selected_row] + self.aw.qmc.alarmstrings[selected_row + 1:] self.alarmtable.setRowCount(nalarms - 1) self.deselectAll() # select row number that was just deleted self.alarmtable.setRangeSelected(QTableWidgetSelectionRange(selected_row,0,selected_row,self.alarmtable.columnCount()-1),True) self.alarmtable.sortItems(0) self.alarmtable.sortItems(0, Qt.AscendingOrder) # we first have to sort the table according to the row numbers # renumber elements self.renumberRows() # we correct the IfAlarm and ButNot references to items after the deleted one for i in range(self.alarmtable.rowCount()): guard = self.alarmtable.cellWidget(i,2) try: guard_value = int(str(guard.text())) - 1 except Exception: guard_value = -1 if guard_value >= selected_row: guard.setText(str(guard_value)) nguard = self.alarmtable.cellWidget(i,3) try: nguard_value = int(str(nguard.text())) - 1 except Exception: nguard_value = -1 if nguard_value >= selected_row: nguard.setText(str(nguard_value)) else: self.alarmtable.removeRow(self.alarmtable.rowCount() - 1) # nothing selected, we pop the last element self.aw.qmc.alarmflag.pop() self.aw.qmc.alarmguard.pop() self.aw.qmc.alarmnegguard.pop() self.aw.qmc.alarmtime.pop() self.aw.qmc.alarmoffset.pop() self.aw.qmc.alarmcond.pop() self.aw.qmc.alarmstate.pop() self.aw.qmc.alarmsource.pop() self.aw.qmc.alarmtemperature.pop() self.aw.qmc.alarmaction.pop() self.aw.qmc.alarmbeep.pop() self.aw.qmc.alarmstrings.pop() self.alarmtable.setRowCount(nalarms - 1) self.deselectAll() self.alarmtable.sortItems(0) self.markNotEnabledAlarmRows() self.alarmtable.setSortingEnabled(True) @pyqtSlot(bool) def importalarms(self,_): self.aw.fileImport(QApplication.translate("Message", "Load Alarms",None),self.importalarmsJSON,ext="*.alrm *.alog") def importalarmsJSON(self,filename): try: _,ext = os.path.splitext(filename) if ext == ".alrm": import io infile = io.open(filename, 'r', encoding='utf-8') from json import load as json_load alarms = json_load(infile) infile.close() self.aw.qmc.alarmsfile = filename self.alarmsfile.setText(self.aw.qmc.alarmsfile) self.aw.qmc.alarmflag = alarms["alarmflags"] self.aw.qmc.alarmguard = alarms["alarmguards"] if "alarmnegguards" in alarms: self.aw.qmc.alarmnegguard = alarms["alarmnegguards"] else: self.aw.qmc.alarmnegguard = [0]*len(self.aw.qmc.alarmflag) self.aw.qmc.alarmtime = alarms["alarmtimes"] self.aw.qmc.alarmoffset = alarms["alarmoffsets"] self.aw.qmc.alarmcond = alarms["alarmconds"] self.aw.qmc.alarmsource = alarms["alarmsources"] self.aw.qmc.alarmtemperature = alarms["alarmtemperatures"] self.aw.qmc.alarmaction = alarms["alarmactions"] if "alarmbeep" in alarms: self.aw.qmc.alarmbeep = alarms["alarmbeep"] else: self.aw.qmc.alarmbeep = [0]*len(self.aw.qmc.alarmflag) self.aw.qmc.alarmstrings = alarms["alarmstrings"] elif ext == ".alog": obj = self.aw.deserialize(filename) self.aw.loadAlarmsFromProfile(filename,obj) self.alarmsfile.setText(self.aw.qmc.alarmsfile) self.aw.qmc.alarmstate = [-1]*len(self.aw.qmc.alarmflag) aitems = self.buildAlarmSourceList() for i in range(len(self.aw.qmc.alarmsource)): if self.aw.qmc.alarmsource[i] + 3 >= len(aitems): self.aw.qmc.alarmsource[i] = 1 # BT self.createalarmtable() except Exception as ex: # import traceback # traceback.print_exc(file=sys.stdout) _, _, exc_tb = sys.exc_info() self.aw.sendmessage(QApplication.translate("Message","Error loading alarm file", None)) self.aw.qmc.adderror((QApplication.translate("Error Message","Exception:",None) + " importalarmsJSON() {0}").format(str(ex)),exc_tb.tb_lineno) @pyqtSlot(bool) def exportalarms(self,_): self.aw.fileExport(QApplication.translate("Message", "Save Alarms",None),"*.alrm",self.exportalarmsJSON) def exportalarmsJSON(self,filename): try: self.savealarms() alarms = {} alarms["alarmflags"] = self.aw.qmc.alarmflag alarms["alarmguards"] = self.aw.qmc.alarmguard alarms["alarmnegguards"] = self.aw.qmc.alarmnegguard alarms["alarmtimes"] = self.aw.qmc.alarmtime alarms["alarmoffsets"] = self.aw.qmc.alarmoffset alarms["alarmconds"] = self.aw.qmc.alarmcond alarms["alarmsources"] = self.aw.qmc.alarmsource alarms["alarmtemperatures"] = self.aw.qmc.alarmtemperature alarms["alarmactions"] = self.aw.qmc.alarmaction alarms["alarmbeep"] = self.aw.qmc.alarmbeep alarms["alarmstrings"] = list(self.aw.qmc.alarmstrings) outfile = open(filename, 'w') from json import dump as json_dump json_dump(alarms, outfile, ensure_ascii=True) outfile.write('\n') outfile.close() return True except Exception as ex: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror((QApplication.translate("Error Message", "Exception:",None) + " exportalarmsJSON(): {0}").format(str(ex)),exc_tb.tb_lineno) return False @pyqtSlot() def closealarms(self): self.savealarms() # save column widths self.aw.qmc.alarmtablecolumnwidths = [self.alarmtable.columnWidth(c) for c in range(self.alarmtable.columnCount())] self.aw.qmc.alarm_popup_timout = int(self.popupTimoutSpinBox.value()) self.closeHelp() settings = QSettings() #save window geometry settings.setValue("AlarmsGeometry",self.saveGeometry()) self.accept() def closeEvent(self, _): self.closealarms() def savealarms(self): try: self.alarmtable.sortItems(0) nalarms = self.alarmtable.rowCount() self.aw.qmc.loadalarmsfromprofile = self.loadAlarmsFromProfile.isChecked() self.aw.qmc.loadalarmsfrombackground = self.loadAlarmsFromBackground.isChecked() self.aw.qmc.alarmflag = [1]*nalarms self.aw.qmc.alarmguard = [-1]*nalarms self.aw.qmc.alarmnegguard = [-1]*nalarms self.aw.qmc.alarmtime = [-1]*nalarms self.aw.qmc.alarmoffset = [0]*nalarms self.aw.qmc.alarmcond = [1]*nalarms self.aw.qmc.alarmsource = [1]*nalarms self.aw.qmc.alarmtemperature = [500.]*nalarms self.aw.qmc.alarmaction = [0]*nalarms self.aw.qmc.alarmbeep = [0]*nalarms self.aw.qmc.alarmstrings = [""]*nalarms for i in range(nalarms): flag = self.alarmtable.cellWidget(i,1) self.aw.qmc.alarmflag[i] = int(flag.isChecked()) guard = self.alarmtable.cellWidget(i,2) try: guard_value = int(str(guard.text())) - 1 except Exception: guard_value = -1 if guard_value > -1 and guard_value < nalarms: self.aw.qmc.alarmguard[i] = guard_value else: self.aw.qmc.alarmguard[i] = -1 negguard = self.alarmtable.cellWidget(i,3) try: negguard_value = int(str(negguard.text())) - 1 except Exception: negguard_value = -1 if negguard_value > -1 and negguard_value < nalarms: self.aw.qmc.alarmnegguard[i] = negguard_value else: self.aw.qmc.alarmnegguard[i] = -1 timez = self.alarmtable.cellWidget(i,4) self.aw.qmc.alarmtime[i] = self.aw.qmc.menuidx2alarmtime[timez.currentIndex()] offset = self.alarmtable.cellWidget(i,5) if offset and offset != "": self.aw.qmc.alarmoffset[i] = max(0,stringtoseconds(str(offset.text()))) atype = self.alarmtable.cellWidget(i,6) self.aw.qmc.alarmsource[i] = int(str(atype.currentIndex())) - 3 cond = self.alarmtable.cellWidget(i,7) self.aw.qmc.alarmcond[i] = int(str(cond.currentIndex())) temp = self.alarmtable.cellWidget(i,8) try: self.aw.qmc.alarmtemperature[i] = float(self.aw.comma2dot(str(temp.text()))) except Exception: self.aw.qmc.alarmtemperature[i] = 0.0 action = self.alarmtable.cellWidget(i,9) self.aw.qmc.alarmaction[i] = int(str(action.currentIndex() - 1)) beepWidget = self.alarmtable.cellWidget(i,10) beep = beepWidget.layout().itemAt(1).widget() if beep and beep is not None: self.aw.qmc.alarmbeep[i] = int(beep.isChecked()) description = self.alarmtable.cellWidget(i,11) self.aw.qmc.alarmstrings[i] = description.text() except Exception as ex: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror((QApplication.translate("Error Message", "Exception:",None) + " savealarms(): {0}").format(str(ex)),exc_tb.tb_lineno) def buildAlarmSourceList(self): extra_names = [] for i in range(len(self.aw.qmc.extradevices)): extra_names.append(str(i) + "xT1: " + self.aw.qmc.extraname1[i]) extra_names.append(str(i) + "xT2: " + self.aw.qmc.extraname2[i]) return ["", deltaLabelUTF8 + QApplication.translate("Label","ET",None), deltaLabelUTF8 + QApplication.translate("Label","BT",None), QApplication.translate("ComboBox","ET",None), QApplication.translate("ComboBox","BT",None)] + extra_names # creates Widget in row i of self.alarmtable and sets them to values from local dialog variables at position i def setalarmtablerow(self,i): #flag flagComboBox = QCheckBox() flagComboBox.setFocusPolicy(Qt.NoFocus) flagComboBox.setText(QApplication.translate("ComboBox","ON",None)) if self.aw.qmc.alarmflag[i]: flagComboBox.setCheckState(Qt.Checked) else: flagComboBox.setCheckState(Qt.Unchecked) #guarded by alarm if self.aw.qmc.alarmguard[i] > -1: guardstr = str(self.aw.qmc.alarmguard[i] + 1) else: guardstr = "0" guardedit = QLineEdit(guardstr) guardedit.setValidator(QIntValidator(0, 999,guardedit)) guardedit.setAlignment(Qt.AlignRight) #neg guarded by alarm if self.aw.qmc.alarmnegguard[i] > -1: negguardstr = str(self.aw.qmc.alarmnegguard[i] + 1) else: negguardstr = "0" negguardedit = QLineEdit(negguardstr) negguardedit.setValidator(QIntValidator(0, 999,negguardedit)) negguardedit.setAlignment(Qt.AlignRight) #Effective time from timeComboBox = MyQComboBox() timeComboBox.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) timeComboBox.addItems([QApplication.translate("ComboBox","ON",None), # qmc.alarmtime 9 QApplication.translate("ComboBox","START",None), # qmc.alarmtime -1 QApplication.translate("ComboBox","CHARGE",None), # qmc.alarmtime 0 QApplication.translate("ComboBox","TP",None), # qmc.alarmtime 8 QApplication.translate("ComboBox","DRY END",None), # qmc.alarmtime 1 QApplication.translate("ComboBox","FC START",None), # qmc.alarmtime 2 QApplication.translate("ComboBox","FC END",None), # qmc.alarmtime 3 QApplication.translate("ComboBox","SC START",None), # qmc.alarmtime 4 QApplication.translate("ComboBox","SC END",None), # qmc.alarmtime 5 QApplication.translate("ComboBox","DROP",None), # qmc.alarmtime 6 QApplication.translate("ComboBox","COOL",None), # qmc.alarmtime 7 QApplication.translate("ComboBox","If Alarm",None)]) # qmc.alarmtime 10 timeComboBox.setCurrentIndex(self.aw.qmc.alarmtime2menuidx[self.aw.qmc.alarmtime[i]]) #time after selected event timeoffsetedit = QLineEdit(stringfromseconds(max(0,self.aw.qmc.alarmoffset[i]))) timeoffsetedit.setAlignment(Qt.AlignRight) regextime = QRegExp(r"^[0-5][0-9]:[0-5][0-9]$") timeoffsetedit.setValidator(QRegExpValidator(regextime,self)) #type/source typeComboBox = MyQComboBox() typeComboBox.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) aitems = self.buildAlarmSourceList() typeComboBox.addItems(aitems) if self.aw.qmc.alarmsource[i] + 3 < len(aitems): typeComboBox.setCurrentIndex(self.aw.qmc.alarmsource[i] + 3) else: typeComboBox.setCurrentIndex(3) #condition condComboBox = MyQComboBox() condComboBox.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) condComboBox.addItems([QApplication.translate("ComboBox","below",None), QApplication.translate("ComboBox","above",None)]) condComboBox.setCurrentIndex(self.aw.qmc.alarmcond[i]) #temperature tempedit = QLineEdit(str(self.aw.float2float(self.aw.qmc.alarmtemperature[i]))) tempedit.setAlignment(Qt.AlignRight) tempedit.setMaximumWidth(130) # tempedit.setValidator(QIntValidator(0, 999,tempedit)) tempedit.setValidator(self.aw.createCLocaleDoubleValidator(-999.9, 999.9,1,tempedit)) #action actionComboBox = MyQComboBox() actionComboBox.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) actionComboBox.addItems(["", QApplication.translate("ComboBox","Pop Up",None), QApplication.translate("ComboBox","Call Program",None), QApplication.translate("ComboBox","Event Button",None), QApplication.translate("ComboBox","Slider",None) + " " + self.aw.qmc.etypesf(0), QApplication.translate("ComboBox","Slider",None) + " " + self.aw.qmc.etypesf(1), QApplication.translate("ComboBox","Slider",None) + " " + self.aw.qmc.etypesf(2), QApplication.translate("ComboBox","Slider",None) + " " + self.aw.qmc.etypesf(3), QApplication.translate("ComboBox","START",None), QApplication.translate("ComboBox","DRY",None), QApplication.translate("ComboBox","FCs",None), QApplication.translate("ComboBox","FCe",None), QApplication.translate("ComboBox","SCs",None), QApplication.translate("ComboBox","SCe",None), QApplication.translate("ComboBox","DROP",None), QApplication.translate("ComboBox","COOL END",None), QApplication.translate("ComboBox","OFF",None), QApplication.translate("ComboBox","CHARGE",None), QApplication.translate("ComboBox","RampSoak ON",None), QApplication.translate("ComboBox","RampSoak OFF",None), QApplication.translate("ComboBox","PID ON",None), QApplication.translate("ComboBox","PID OFF",None), QApplication.translate("ComboBox","SV",None), QApplication.translate("ComboBox","Playback ON",None), QApplication.translate("ComboBox","Playback OFF",None), QApplication.translate("ComboBox","Set Canvas Color",None), QApplication.translate("ComboBox","Reset Canvas Color",None)]) actionComboBox.setCurrentIndex(self.aw.qmc.alarmaction[i] + 1) #beep beepWidget = QWidget() beepComboBox = QCheckBox() beepComboBox.setFocusPolicy(Qt.NoFocus) beepLayout = QHBoxLayout() beepLayout.addStretch() beepLayout.addWidget(beepComboBox) beepLayout.addSpacing(6); beepLayout.addStretch() beepLayout.setContentsMargins(0,0,0,0) beepLayout.setSpacing(0) beepWidget.setLayout(beepLayout) if len(self.aw.qmc.alarmbeep) > i and self.aw.qmc.alarmbeep[i]: beepComboBox.setCheckState(Qt.Checked) else: beepComboBox.setCheckState(Qt.Unchecked) #text description descriptionedit = QLineEdit(self.aw.qmc.alarmstrings[i]) descriptionedit.setCursorPosition(0) self.alarmtable.setItem(i, 0, MyTableWidgetItemInt(str(i+1),i)) self.alarmtable.setCellWidget(i,1,flagComboBox) self.alarmtable.setItem(i, 1, MyTableWidgetItemQCheckBox(flagComboBox)) self.alarmtable.setCellWidget(i,2,guardedit) self.alarmtable.setItem(i, 2, MyTableWidgetItemQLineEdit(guardedit)) self.alarmtable.setCellWidget(i,3,negguardedit) self.alarmtable.setItem(i, 3, MyTableWidgetItemQLineEdit(negguardedit)) self.alarmtable.setCellWidget(i,4,timeComboBox) self.alarmtable.setItem(i, 4, MyTableWidgetItemQComboBox(timeComboBox)) self.alarmtable.setCellWidget(i,5,timeoffsetedit) self.alarmtable.setItem(i, 5, MyTableWidgetItemQLineEdit(timeoffsetedit)) self.alarmtable.setCellWidget(i,6,typeComboBox) self.alarmtable.setItem(i, 6, MyTableWidgetItemQComboBox(typeComboBox)) self.alarmtable.setCellWidget(i,7,condComboBox) self.alarmtable.setItem(i, 7, MyTableWidgetItemQComboBox(condComboBox)) self.alarmtable.setCellWidget(i,8,tempedit) self.alarmtable.setItem(i, 8, MyTableWidgetItemQLineEdit(tempedit)) self.alarmtable.setCellWidget(i,9,actionComboBox) self.alarmtable.setItem(i, 9, MyTableWidgetItemQComboBox(actionComboBox)) self.alarmtable.setCellWidget(i,10,beepWidget) self.alarmtable.setItem(i, 10, MyTableWidgetItemQCheckBox(beepWidget.layout().itemAt(1).widget())) self.alarmtable.setCellWidget(i,11,descriptionedit) self.alarmtable.setItem(i, 11, MyTableWidgetItemQLineEdit(descriptionedit)) # puts a gray background on alarm rows that have already been fired def markNotEnabledAlarmRows(self): for i in range(self.alarmtable.rowCount()): for j in range(11): try: if self.aw.qmc.alarmstate[i] != -1: #self.alarmtable.setItem(i,j,QTableWidgetItem()) self.alarmtable.item(i,j).setBackground(QColor(191, 191, 191)) except: pass def createalarmtable(self): try: self.alarmtable.clear() self.alarmtable.setTabKeyNavigation(True) self.alarmtable.setColumnCount(12) self.alarmtable.setHorizontalHeaderLabels([QApplication.translate("Table","Nr",None), QApplication.translate("Table","Status",None), QApplication.translate("Table","If Alarm",None), QApplication.translate("Table","But Not",None), QApplication.translate("Table","From",None), QApplication.translate("Table","Time",None), QApplication.translate("Table","Source",None), QApplication.translate("Table","Condition",None), QApplication.translate("Table","Value",None), QApplication.translate("Table","Action",None), QApplication.translate("Table","Beep",None), QApplication.translate("Table","Description",None)]) self.alarmtable.setAlternatingRowColors(True) self.alarmtable.setEditTriggers(QTableWidget.NoEditTriggers) self.alarmtable.setSelectionBehavior(QTableWidget.SelectRows) self.alarmtable.setSelectionMode(QTableWidget.SingleSelection) self.alarmtable.setShowGrid(True) nalarms = len(self.aw.qmc.alarmtemperature) self.alarmtable.verticalHeader().setSectionResizeMode(2) self.alarmtable.verticalHeader().setVisible(False) self.alarmtable.setSortingEnabled(False) if nalarms: self.alarmtable.setRowCount(nalarms) #populate table for i in range(nalarms): self.setalarmtablerow(i) header = self.alarmtable.horizontalHeader() header.setStretchLastSection(True) self.alarmtable.resizeColumnsToContents() # remember the columnwidth for i in range(len(self.aw.qmc.alarmtablecolumnwidths)): try: w = self.aw.qmc.alarmtablecolumnwidths[i] if i == 6: w = max(80,w) self.alarmtable.setColumnWidth(i,w) except: pass self.markNotEnabledAlarmRows() self.alarmtable.setSortingEnabled(True) self.alarmtable.sortItems(0) except Exception as ex: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror((QApplication.translate("Error Message","Exception:",None) + " createalarmtable() {0}").format(str(ex)),exc_tb.tb_lineno) @pyqtSlot(bool) def copyAlarmTabletoClipboard(self,_=False): nrows = self.alarmtable.rowCount() ncols = self.alarmtable.columnCount() clipboard = "" modifiers = QApplication.keyboardModifiers() if modifiers == Qt.AltModifier: #alt click tbl = prettytable.PrettyTable() fields = [] for c in range(ncols): fields.append(self.alarmtable.horizontalHeaderItem(c).text()) tbl.field_names = fields for r in range(nrows): rows = [] rows.append(self.alarmtable.item(r,0).text()) rows.append(str(self.alarmtable.cellWidget(r,1).isChecked())) rows.append(self.alarmtable.cellWidget(r,2).text()) rows.append(self.alarmtable.cellWidget(r,3).text()) rows.append(self.alarmtable.cellWidget(r,4).currentText()) rows.append(self.alarmtable.cellWidget(r,5).text()) rows.append(self.alarmtable.cellWidget(r,6).currentText()) rows.append(self.alarmtable.cellWidget(r,7).currentText()) rows.append(self.alarmtable.cellWidget(r,8).text()) rows.append(self.alarmtable.cellWidget(r,9).currentText()) rows.append(str(self.alarmtable.cellWidget(r,10).layout().itemAt(1).widget().isChecked())) rows.append(self.alarmtable.cellWidget(r,11).text()) tbl.add_row(rows) clipboard = tbl.get_string() else: for c in range(ncols): clipboard += self.alarmtable.horizontalHeaderItem(c).text() if c != (ncols-1): clipboard += '\t' clipboard += '\n' for r in range(nrows): clipboard += self.alarmtable.item(r,0).text() + '\t' clipboard += str(self.alarmtable.cellWidget(r,1).isChecked()) + '\t' clipboard += self.alarmtable.cellWidget(r,2).text() + '\t' clipboard += self.alarmtable.cellWidget(r,3).text() + '\t' clipboard += self.alarmtable.cellWidget(r,4).currentText() + '\t' clipboard += self.alarmtable.cellWidget(r,5).text() + '\t' clipboard += self.alarmtable.cellWidget(r,6).currentText() + '\t' clipboard += self.alarmtable.cellWidget(r,7).currentText() + '\t' clipboard += self.alarmtable.cellWidget(r,8).text() + '\t' clipboard += self.alarmtable.cellWidget(r,9).currentText() + '\t' clipboard += str(self.alarmtable.cellWidget(r,10).layout().itemAt(1).widget().isChecked()) + '\t' clipboard += self.alarmtable.cellWidget(r,11).text() + '\n' # copy to the system clipboard sys_clip = QApplication.clipboard() sys_clip.setText(clipboard) self.aw.sendmessage(QApplication.translate("Message","Alarm table copied to clipboard",None)) @pyqtSlot(bool) def showAlarmbuttonhelp(self,_=False): self.helpdialog = self.aw.showHelpDialog( self, # this dialog as parent self.helpdialog, # the existing help dialog QApplication.translate("Form Caption","Alarms Help",None), alarms_help.content()) def closeHelp(self): self.aw.closeHelpDialog(self.helpdialog)
class OutcomeEventClaster(QDialog): def __init__(self, header, outComeEventNames, outComeCategory, units, currency, parent = None): QDialog.__init__(self, parent) self._acceptState = False self._dataContainer = {} self._header = header self._Currency = currency self._units = units self._category = outComeCategory self._EventNames = outComeEventNames self.InitUI() self.addRowWidgets() self.show() #++++++++++++++++++++++++++++++ InitUI ++++++++++++++++++++++++++++++++ def InitUI(self): self.setWindowTitle("მონაცემთა შეტანა") self.setWindowIcon(QtGui.QIcon("icon/outcome.svg")) self.setFixedSize(1300, 900) vbox = QVBoxLayout() hbox = QHBoxLayout() vbox.setContentsMargins(2, 2, 2, 2) ############################## Calendar ############################### self.calendar = QCalendarWidget() self.calendar.setGridVisible(True) self.calendar.setFirstDayOfWeek(Qt.Monday) ############################### Table ################################# self.table = QTableWidget() self.table.setRowCount(1) self.table.setColumnCount(len(self._header)) self.table.setHorizontalHeaderLabels(self._header) self.table.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table.resizeRowsToContents() self.table.setSortingEnabled(False) self.table.setWordWrap(True) self.rowNumb = self.table.rowCount()-1 ############################## add Row ################################ self.addRowButton = QPushButton('დამატება') self.addRowButton.setMaximumWidth(100) self.addRowButton.setIcon(QIcon('icon/addRow.svg')) self.addRowButton.clicked.connect(self.addRow) ############################## del Row ################################ self.delRowButton = QPushButton('წაშლა') self.delRowButton.setMaximumWidth(100) self.delRowButton.setIcon(QIcon('icon/DelRow.svg')) self.delRowButton.clicked.connect(self.delRow) ############################### test ################################## sumHboxLayout = QHBoxLayout() self.sumMoney = QLineEdit() self.equivalentSumMoney = QLineEdit() sumHboxLayout.addWidget(self.sumMoney) sumHboxLayout.addWidget(self.equivalentSumMoney) self.testButton = QPushButton('ტესტი') self.testButton.setIcon(QIcon('icon/test.png')) self.testButton.clicked.connect(self.test) ############################## Accept ################################# self.acceptButton = QPushButton('დადასტურება', self) self.acceptButton.clicked.connect(self.acceptDialog) ############################## Reject ################################# self.rejectButton = QPushButton('გაუქმება', self) self.rejectButton.clicked.connect(self.rejectDialog) ###################### Add widgets on layouts ######################### hbox.addWidget(self.addRowButton) hbox.addWidget(self.delRowButton) vbox.addWidget(self.calendar,5) vbox.addWidget(self.table,90) vbox.addLayout(hbox) vbox.addLayout(sumHboxLayout) vbox.addWidget(self.testButton,5) hboxAcceptReject = QHBoxLayout() hboxAcceptReject.addWidget(self.acceptButton) hboxAcceptReject.addWidget(self.rejectButton) vbox.addLayout(hboxAcceptReject) self.setLayout(vbox) #++++++++++++++++++++++++++++ Add Row +++++++++++++++++++++++++++++++++ def addRow(self): self.rowNumb = self.table.rowCount() self.table.insertRow(self.rowNumb) self.addRowWidgets() #++++++++++++++++++++++++ Add Row Widgets +++++++++++++++++++++++++++++ def addRowWidgets(self): ########################### emountEdit ################################ quantityEdit = QLineEdit('1') quantityEdit.setValidator(QDoubleValidator()) quantityEdit.setMaximumWidth(30) units = QComboBox() units.setToolTip("<h5>ერთეული") units.setMaximumWidth(70) units.addItems(self._units) quantityEditHlayout = QHBoxLayout() quantityEditHlayout.addWidget(quantityEdit,20) quantityEditHlayout.addWidget(units,80) quantityEditWidgets = QWidget() quantityEditWidgets.setLayout(quantityEditHlayout) ####################### Category Selector ############################# outcomeCategorySelector = QComboBox() outcomeCategorySelector.addItems(self._category) ########################## Price Editor ############################### PriceEdit = QLineEdit() PriceEdit.setValidator(QDoubleValidator()) PriceEdit.setToolTip("<h5>გადახდა") PriceEdit.setMaximumWidth(70) #################### Equivalent Price Editor ########################## equivalentPriceEdit = QLineEdit() equivalentPriceEdit.setValidator(QDoubleValidator()) equivalentPriceEdit.setText("--") equivalentPriceEdit.setToolTip("<h5>კონვერტაცია ვალუტაში") equivalentPriceEdit.setMaximumWidth(70) ####################### Currency Selector ############################# CurrencySelector = QComboBox() for idx, key in enumerate(self._Currency): CurrencySelector.addItem(key) CurrencySelector.setItemData(idx, Qt.AlignCenter, Qt.TextAlignmentRole) CurrencySelector.setItemIcon(idx, QtGui.QIcon(self._Currency[key])) ################# Equivalent Currency Selector ######################## EqviCurrencySelector = QComboBox() for idx, key in enumerate(self._Currency): EqviCurrencySelector.addItem(key) EqviCurrencySelector.setItemData(idx, Qt.AlignCenter, Qt.TextAlignmentRole) EqviCurrencySelector.setItemIcon(idx, QtGui.QIcon(self._Currency[key])) ###################### App widgets in cells ########################### priceHlayout = QHBoxLayout() priceHlayout.addWidget(PriceEdit) priceHlayout.addWidget(CurrencySelector) priceHlayout.addWidget(equivalentPriceEdit) priceHlayout.addWidget(EqviCurrencySelector) priceWidgets = QWidget() priceWidgets.setLayout(priceHlayout) PayMethodWidgets = QWidget() PayMethod = QCheckBox() PayMethod.setToolTip("<h5>ნაღდით გადახდა") PayMethodHlayout = QHBoxLayout() PayMethodHlayout.addWidget(PayMethod) PayMethodHlayout.setAlignment( Qt.AlignCenter ) PayMethodWidgets.setLayout(PayMethodHlayout) eventContent = QTableWidgetItem('') self.table.setItem(self.rowNumb, 0, eventContent) eventContent.setData(Qt.UserRole, random.sample(self._EventNames, len(self._EventNames))) self.table.setItemDelegate(TableItemCompleter(self.table)) self.table.setCellWidget(self.rowNumb, 1, quantityEditWidgets) self.table.setCellWidget(self.rowNumb, 2, outcomeCategorySelector) self.table.setCellWidget(self.rowNumb, 3, priceWidgets) self.table.setCellWidget(self.rowNumb, 4, PayMethodWidgets) ###################### Set Table Cell Widths ########################## self.table.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeToContents) self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents) self.table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeToContents) self.table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeToContents) # +++++++++++++ String to float number formater +++++++++++++++++++++++ def _stingToFloatFormater(self, value): if ',' in value: value = value.replace(",", ".") return value else: return value #++++++++++++++++++++++++++ Delete Row ++++++++++++++++++++++++++++++++ def delRow(self): self.rowNumb = self.table.rowCount() if self.rowNumb > 1: selected_Row = self.table.currentRow() self.table.removeRow(selected_Row) #++++++++++++++++++++++ Set calendar date +++++++++++++++++++++++++++++ def setCalendarDate(self, date): self.calendar.setSelectedDate(QDate(date[0], date[1], date[2])) #++++++++++++++++++++++ Make data claster +++++++++++++++++++++++++++++ def makeDataClaster(self): self._dataContainer = {} dataContainerArray = [] self.rowNumb = self.table.rowCount() self.colNumb = self.table.columnCount() for row in range(self.rowNumb): dataContainerTemp = [] for column in range(self.colNumb): if column == 0: dataContainerTemp.append({'cell_0' : self.table.item(row,column).text()}) elif column == 1: dataContainerTemp.append({'cell_1.1' : self._stingToFloatFormater(self.table.cellWidget(row,column).children()[1].text()), 'cell_1.2' : self.table.cellWidget(row,column).children()[2].currentIndex()}) elif column == 2: dataContainerTemp.append({'cell_2.1' : self.table.cellWidget(row,column).currentIndex()}) elif column == 3: dataContainerTemp.append({'cell_3.1' : self._stingToFloatFormater(self.table.cellWidget(row,column).children()[1].text()), 'cell_3.2' : self.table.cellWidget(row,column).children()[2].currentIndex(), 'cell_3.3' : self._stingToFloatFormater(self.table.cellWidget(row,column).children()[3].text()), 'cell_3.4' : self.table.cellWidget(row,column).children()[4].currentIndex()}) elif column == 4: dataContainerTemp.append({'cell_4' : self.table.cellWidget(row,column).children()[1].isChecked()}) dataContainerArray.append(dataContainerTemp) self._dataContainer.update({self.calendar.selectedDate().toString("dd.MM.yyyy") : dataContainerArray}) #++++++++++++++++++++++ Edit data claster +++++++++++++++++++++++++++++ def EditDataClaster(self, DataClasterComponent, timeStamp): for _ in range(len(DataClasterComponent)-1): self.addRow() self.setCalendarDate(QDate.fromString(timeStamp, 'dd.MM.yyyy').getDate()) for row in range(len(DataClasterComponent)): self.table.item(row, 0).setText(DataClasterComponent[row][0]['cell_0']) self.table.cellWidget(row, 1).children()[1].setText(DataClasterComponent[row][1]['cell_1.1']) self.table.cellWidget(row, 1).children()[2].setCurrentIndex(DataClasterComponent[row][1]['cell_1.2']) self.table.cellWidget(row, 2).setCurrentIndex(DataClasterComponent[row][2]['cell_2.1']) self.table.cellWidget(row, 3).children()[1].setText(DataClasterComponent[row][3]['cell_3.1']) self.table.cellWidget(row, 3).children()[2].setCurrentIndex(DataClasterComponent[row][3]['cell_3.2']) self.table.cellWidget(row, 3).children()[3].setText(DataClasterComponent[row][3]['cell_3.3']) self.table.cellWidget(row, 3).children()[4].setCurrentIndex(DataClasterComponent[row][3]['cell_3.4']) self.table.cellWidget(row, 4).children()[1].setChecked(DataClasterComponent[row][4]['cell_4']) #+++++++++++++++++++++++++++ Accept +++++++++++++++++++++++++++++++++++ def acceptDialog(self): self.makeDataClaster() self._acceptState = True self.close() #+++++++++++++++++++++++++++ Reject +++++++++++++++++++++++++++++++++++ def rejectDialog(self): self._acceptState = False self.close() #++++++++++++++++++++ Get data claster part +++++++++++++++++++++++++++ def getDataClasterPart(self): return self._dataContainer, self._acceptState #++++++++++++++++++++++++++++ Test ++++++++++++++++++++++++++++++++++++ def test(self): print("Test") data = {'22.01.1993': [ [ {'cell_0': 'პური'}, {'cell_1.1': '2', 'cell_1.2': 1}, {'cell_2.1': 2}, { 'cell_3.1': '30', 'cell_3.2': 1, 'cell_3.3': '100', 'cell_3.4': 0}, {'cell_4': True}], [ {'cell_0': 'ლობიო'}, {'cell_1.1': '5', 'cell_1.2': 1}, {'cell_2.1': 3}, { 'cell_3.1': '64', 'cell_3.2': 2, 'cell_3.3': '54', 'cell_3.4': 3}, {'cell_4': True}]]} #self.EditDataClaster(data) self.makeDataClaster() self.rowNumb = self.table.rowCount() sumMoney = 0 equiSumMoney = 0 for row in range(self.rowNumb): try: sumMoney = sumMoney + round(float(self.table.cellWidget(row,3).children()[1].text()), 2) except ValueError: pass try: equiSumMoney = equiSumMoney + round(float(self.table.cellWidget(row,3).children()[3].text()), 2) except ValueError: pass self.sumMoney.setText(str(sumMoney)) self.equivalentSumMoney.setText(str(equiSumMoney))
class EditWidget(QWidget): """ This QWidget gather and check the user provided metadata and commit it to the database This QWidget is largely inspired from the CaptureWidget Attributes: self.show_result_widget_signal (pyqtSignal()): Is used to ask the MainSearchWidget to display the ResultWidget self.request_refresh_signal (pyqtSignal()): Is used to ask the SearchWidget to rerun the search after an edit """ show_result_widget_signal = pyqtSignal() request_refresh_signal = pyqtSignal() def __init__(self): # Initialize the parent class QWidget # this allow the use of the parent's methods when needed super(EditWidget, self).__init__() ######### self.edit_label = QLabel("Choisissez les éléments à modifier") ######### self.edit_table = QTableWidget() self.table_font = QFont(QFont().defaultFamily(), 12) ######### self.new_table_row_button = QPushButton("Ajouter") self.save_modifications_button = QPushButton("Sauvegarder") self.return_to_result_button = QPushButton('Retour') ######### dc_data = OrderedDict() dc_data['dc:contributor'] = "nom des acteurs" dc_data['dc:creator'] = "maison d'édition, scénariste ou réalisateur" dc_data['dc:description'] = "résumé de la vidéo" dc_data['dc:language'] = "langue de la vidéo: FRA, ENG" dc_data['dc:publisher'] = "entreprise qui a publié le film, par exemple Sony Pictures" dc_data['dc:subject'] = "thème du film: horreur, action, histoire d'amour..." dc_data['dc:title'] = "titre du film" dc_data['dcterms:isPartOf'] = "remplir si le film fait partie d'un ensemble de films comme Star Wars" dc_data['dcterms:created'] = "année de sortie du film" dc_data['ratio'] = "format visuel du film" dc_data['format_video'] = "format video de la cassette" self.digitise_table_row_tooltip = dc_data ######### self.raw_videos_path = FILES_PATHS["raw"] self.compressed_videos_path = FILES_PATHS["compressed"] self.imported_files_path = FILES_PATHS["imported"] ######### self.db_client = MongoClient("mongodb://localhost:27017/") digitize_app = self.db_client['digitize_app'] self.videos_metadata_collection = digitize_app['videos_metadata'] ######### self.capture_data = None ######### self.tab_init() @wrap_in_future @asyncio.coroutine def receive_data(self, dc_identifier): """ Receive data from the ResultWidget, parse it and call self.add_table_row for each row to add Args: dc_identifier (str): the uuid of the video """ self.capture_data = self.videos_metadata_collection.find_one({"dc:identifier": dc_identifier}, {'_id': False}) print("hey") print(self.capture_data) for key, values in self.capture_data.items(): if key in ('dc:identifier', 'duration', 'dc:type', 'files_path', 'dcterms:modified'): pass elif key in ('dc:subject', 'dc:publisher', 'dc:creator', 'dc:title', 'dc:language', 'dc:contributor', 'dcterms:isPartOf'): for value in values: row_count = self.edit_table.rowCount() self.add_table_row() self.edit_table.cellWidget(row_count, 0).setCurrentText(key) self.edit_table.cellWidget(row_count, 1).setText(value) elif key == 'dc:description': row_count = self.edit_table.rowCount() self.add_table_row() print(row_count) print(values) self.edit_table.cellWidget(row_count, 0).setCurrentText(key) # Ugly hack to let the combobox_changed function some time to react # the function is linked with a signal and the reaction is not instantaneous yield from asyncio.sleep(0.5) self.edit_table.cellWidget(row_count, 1).setText(values) elif key == 'dc:format': if 'format' in values: # if a file is imported, format may not be defined row_count = self.edit_table.rowCount() self.add_table_row() self.edit_table.cellWidget(row_count, 0).setCurrentText('format_video') yield from asyncio.sleep(0.5) self.edit_table.cellWidget(row_count, 1).setCurrentText(values['format']) if 'aspect_ratio' in values: # it's possible to delete the aspect_ratio key row_count = self.edit_table.rowCount() self.add_table_row() self.edit_table.cellWidget(row_count, 0).setCurrentText('ratio') yield from asyncio.sleep(0.5) self.edit_table.cellWidget(row_count, 1).setCurrentText(values['aspect_ratio']) elif key == 'dcterms:created': row_count = self.edit_table.rowCount() self.add_table_row() self.edit_table.cellWidget(row_count, 0).setCurrentText(key) self.edit_table.cellWidget(row_count, 1).setText(str(values)) def add_table_row(self): """ Is called when the "self.new_table_row_button" button is pressed or by the receive_row function This function will fill the combobox with their name and a tooltip, link the combobox to the "self.combobox_changed function" and link the delete button with the self.delete_table_row" function """ row_count = self.edit_table.rowCount() self.edit_table.insertRow(row_count) self.edit_table.setCellWidget(row_count, 0, QComboBox()) count = 0 for dc_key, dc_tooltip in self.digitise_table_row_tooltip.items(): self.edit_table.cellWidget(row_count, 0).addItem(dc_key) self.edit_table.cellWidget(row_count, 0).setItemData(count, dc_tooltip, Qt.ToolTipRole) count += 1 self.edit_table.cellWidget(row_count, 0).currentTextChanged[str].connect(self.combobox_changed) self.edit_table.setCellWidget(row_count, 1, QLineEdit()) self.edit_table.setCellWidget(row_count, 2, QPushButton("Delete")) self.edit_table.cellWidget(row_count, 2).clicked.connect(self.delete_table_row) def delete_table_row(self): """ Is linked to the delete button when a row is added. When the delete button is pressed, the function look up its row and delete it """ sender = self.sender() index = self.edit_table.indexAt(sender.pos()) if index.isValid(): self.edit_table.removeRow(index.row()) def combobox_changed(self, text): """ Is linked to the combobox when a row is added When the combobox selected item changes (example: from dc:contributor to dc:description), this function is called to make the row fit its new usage. (example: enter text or a date) Args: text (str): its the active combobox selection """ sender = self.sender() index = self.edit_table.indexAt(sender.pos()) if index.isValid(): row = index.row() if text == "dc:description": self.edit_table.removeCellWidget(row, 1) self.edit_table.setCellWidget(row, 1, QTextEdit()) self.edit_table.setRowHeight(row, 60) elif text == "dcterms:created": self.edit_table.removeCellWidget(row, 1) self.edit_table.setCellWidget(row, 1, QLineEdit()) self.edit_table.cellWidget(row, 1).setInputMask("0000") self.edit_table.setRowHeight(row, 30) elif text == "ratio": self.edit_table.removeCellWidget(row, 1) self.edit_table.setCellWidget(row, 1, QComboBox()) self.edit_table.setRowHeight(row, 30) self.edit_table.cellWidget(row, 1).addItems(["4:3", "16:9"]) elif text == "format_video": self.edit_table.removeCellWidget(row, 1) self.edit_table.setCellWidget(row, 1, QComboBox()) self.edit_table.setRowHeight(row, 30) self.edit_table.cellWidget(row, 1).addItems(["PAL", "SECAM", "NTSC"]) elif text == "dc:language": self.edit_table.removeCellWidget(row, 1) self.edit_table.setCellWidget(row, 1, QLineEdit()) self.edit_table.setRowHeight(row, 30) self.edit_table.cellWidget(row, 1).setInputMask("AAA") else: self.edit_table.removeCellWidget(row, 1) self.edit_table.setCellWidget(row, 1, QLineEdit()) self.edit_table.setRowHeight(row, 30) def save_modifications(self): """ Gather the user provided metadata and add the constants listed below. dublincore_dict["dcterms:modified"] = datetime.now().replace(microsecond=0).isoformat() """ dublincore_dict = dict() dublincore_dict["dc:format"] = dict() for row in range(self.edit_table.rowCount()): combobox_text = self.edit_table.cellWidget(row, 0).currentText() widget_type = self.edit_table.cellWidget(row, 1).metaObject().className() if widget_type == "QLineEdit": widget_text_value = self.edit_table.cellWidget(row, 1).displayText() elif widget_type == "QTextEdit": widget_text_value = self.edit_table.cellWidget(row, 1).toPlainText() elif widget_type == "QComboBox": widget_text_value = self.edit_table.cellWidget(row, 1).currentText() if widget_text_value != "": if combobox_text == "ratio": dublincore_dict["dc:format"]["aspect_ratio"] = widget_text_value elif combobox_text == "format_video": dublincore_dict["dc:format"]["format"] = widget_text_value elif combobox_text == "dcterms:created": dublincore_dict[combobox_text] = int(widget_text_value) elif combobox_text == "dc:description": dublincore_dict[combobox_text] = widget_text_value else: try: dublincore_dict[combobox_text].append(widget_text_value) except KeyError: dublincore_dict[combobox_text] = [widget_text_value] dublincore_dict["dcterms:modified"] = datetime.now().replace(microsecond=0).isoformat() if 'dc:title' in dublincore_dict and "dcterms:created" in dublincore_dict: dc_identifier = self.capture_data['dc:identifier'] self.videos_metadata_collection.update_one( filter={"dc:identifier": dc_identifier}, update={"$set": dublincore_dict}) info_box = QMessageBox() info_message = "Modifications sauvegardées !" info_box.information(info_box, "Attention", info_message) self.request_refresh_signal.emit() else: warning_box = QMessageBox() warning_message = "Il ne faut pas supprimer le titre ou la date de création de la vidéo !" warning_box.warning(warning_box, "Attention", warning_message) def reset_edit_table(self): self.edit_table.setRowCount(0) def tab_init(self): """ Is called when the CaptureWidget class init Its job is to put the widgets instantiated in the init function to their place and set some signals between functions and buttons """ grid = QGridLayout() self.setLayout(grid) ######### self.edit_table.setRowCount(0) self.edit_table.setColumnCount(3) self.edit_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) self.edit_table.setColumnWidth(0, 170) self.edit_table.setFont(self.table_font) self.edit_table.setHorizontalHeaderLabels(["", "", ""]) ######### grid.addWidget(self.edit_label, 0, 0) grid.addWidget(self.edit_table, 1, 0, 7, 4) grid.addWidget(self.new_table_row_button, 1, 5) grid.addWidget(self.return_to_result_button, 8, 0) grid.addWidget(self.save_modifications_button, 8, 5) ######### self.return_to_result_button.clicked.connect(self.show_result_widget_signal.emit) ######### self.new_table_row_button.clicked.connect(self.add_table_row) self.save_modifications_button.clicked.connect(self.save_modifications)
class InputTableModel(QDialog): def __init__(self, title, numVar, numCons, typeVar, objCrit, parent=None): super(InputTableModel, self).__init__(parent) self.problem = None self.problemTitle = title self.numVariables = numVar self.numConstraints = numCons self.objCriterion = objCrit self.typeVariable = typeVar self.tableModel = QTableWidget(self.numConstraints+1, self.numVariables+2) self.tableModel.setItemDelegate(Delegate(self)) listVariables = [] for m in range(self.numVariables): listVariables.append("X"+str(m)) listVariables.extend(["Direction","R.H.S"]) #Generar Filas listConstraints = ["Objetive"] for m in range(self.numConstraints): listConstraints.append("C"+str(m)) combo = QComboBox() combo.addItem('<') combo.addItem('<=') combo.addItem('=') combo.addItem('>=') combo.addItem('>') self.tableModel.setCellWidget(m+1, self.numVariables, combo) #listConstraints.extend(["LowerBound","UpperBound", "VariableType"]) self.tableModel.setCellWidget(0, self.numVariables, QLabel("")) self.tableModel.setHorizontalHeaderLabels(listVariables) self.tableModel.setVerticalHeaderLabels(listConstraints) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.verify) buttonBox.rejected.connect(self.reject) f = "Problem Title: " if self.objCriterion == True: f = f + self.problemTitle + " - Objetive: Maximitation" else: f = f + self.problemTitle + " - Objetive: Minimization" t = QLabel(f) mainLayout = QVBoxLayout() mainLayout.addWidget(t) mainLayout.addWidget(self.tableModel) mainLayout.addWidget(buttonBox) width = self.tableModel.columnWidth(1)*(self.tableModel.columnCount()+1) height = self.tableModel.rowHeight(0)*(self.tableModel.rowCount()+4) self.resize(QSize(width, height)) self.setWindowTitle("Input Problem Model") self.setLayout(mainLayout) def verify(self): #Matix Values matrix = [] matrixGraph = [] for f in range(self.tableModel.rowCount()): row = [] for c in range(self.tableModel.columnCount()): if c == self.numVariables: item = self.tableModel.cellWidget(f,c) if type(item) == QComboBox: row.append(item.currentText()) else: item = self.tableModel.item(f,c) if item == None: row.append(0) else: row.append(float(item.text())) if f == 0: row.pop(-1) matrix.append(row) flag = False for s in range(len(matrix[0])): if matrix[0][s] == 0: flag = True if flag == False: #Title and Criterion if self.objCriterion: self.problem = LpProblem(self.problemTitle, LpMaximize) else: self.problem = LpProblem(self.problemTitle, LpMinimize) #Non Negative Continuous if self.typeVariable == 1: x = LpVariable.matrix("x", list(range(self.numVariables)), 0, None) print "Non Negative Continuous" #Non Negative Integer elif self.typeVariable == 2: x = LpVariable.matrix("x", list(range(self.numVariables)), 0, None , LpInteger) print "Non Negative Integer" #Binary elif self.typeVariable == 3: x = LpVariable.matrix("x", list(range(self.numVariables)), 0, 1 , LpInteger) print "Binary" #Unrestricted else: x = LpVariable.matrix("x", list(range(self.numVariables)), None , None) print "Unrestricted" for i in range(len(matrix)): if i == 0: #Function Objetive weight = lpDot(matrix[i], x) self.problem += weight else: b = matrix[i][-1] sign = matrix[i][-2] constraint = lpDot(matrix[i][:-2], x) if sign == u'>': self.problem += constraint > b elif sign == u'>=': self.problem += constraint >= b elif sign == u'=': self.problem += constraint == b elif sign == u'<=': self.problem += constraint <= b else: self.problem += constraint < b #Linux: solvers.COIN_CMD() with coin-cbc installed. #Windows: Modified solvers.COINMP_DLL() in dir pulp to run. self.problem.solve(solvers.COIN_CMD()) if self.numVariables == 2: point = [] for r in self.problem.variables(): if r.name != '__dummy': point.append(r.varValue) self.canvas = mplc(self, width=5, height=8, dpi=100, matrixModel = matrix, title=self.problemTitle, point=point) self.accept() return answer = QMessageBox.warning(self, "Incomplete Input Problem", "Dont contain all the necessary information.\n" "Do you want to discard it?", QMessageBox.Yes, QMessageBox.No) if answer == QMessageBox.Yes: self.reject()
class UiMainWindow(QWidget): def __init__(self): super().__init__() self.initUI() self.size_table = 1 self.last_table_update = [] def initUI(self): self.setGeometry(200, 200, 720, 600) self.setWindowTitle("Session2") self.number = 1 self.date = 2 self.size_table = 10 self.pushButton_add = QPushButton("+", self) self.pushButton_add.resize(50, 50) self.pushButton_add.move(660, 500) self.pushButton_add.clicked.connect(self.add_stroka) self.pushButton_ok = QPushButton("Ok", self) self.pushButton_ok.resize(100, 50) self.pushButton_ok.move(10, 520) self.pushButton_ok.clicked.connect(self.ok) self.pushButton_download = QPushButton("Записать", self) self.pushButton_download.resize(100, 50) self.pushButton_download.move(130, 520) self.pushButton_download.clicked.connect(self.write) self.pushButton_open_file2 = QPushButton("Закрыть", self) self.pushButton_open_file2.resize(100, 50) self.pushButton_open_file2.move(250, 520) self.pushButton_open_file2.clicked.connect(self.closing) self.lineEdit_otvetstv = QLineEdit('', self) self.lineEdit_otvetstv.setPlaceholderText("") self.lineEdit_otvetstv.resize(200, 20) self.lineEdit_otvetstv.move(190, 50) self.lineEdit_otvetstv.setObjectName("lineEdit") self.drons = QLabel(self) self.drons.setText( f"Поступление комплектующих № 000{self.number} от {datetime.datetime.today().strftime('%d.%m.%Y')}" ) self.drons.move(10, 20) self.komplecktushie = QLabel(self) self.komplecktushie.setText("Ответственный за прием:") self.komplecktushie.move(10, 50) self.tableWidget_komplectuyshie = QTableWidget(self) self.tableWidget_komplectuyshie.setColumnCount(3) self.tableWidget_komplectuyshie.move(10, 100) self.tableWidget_komplectuyshie.resize(700, 400) self.tableWidget_komplectuyshie.setHorizontalHeaderItem( 0, QTableWidgetItem('Комплектующее')) self.tableWidget_komplectuyshie.setHorizontalHeaderItem( 1, QTableWidgetItem('Серийный номер')) self.tableWidget_komplectuyshie.setHorizontalHeaderItem( 2, QTableWidgetItem('Количество')) self.upload() def upload(self): combo_box_options = [] db_session.global_init('sql/db/drons1.sqlite') session = db_session.create_session() for user in session.query(details.DetailCategory): combo_box_options.append(user.name_det) self.tableWidget_komplectuyshie.setRowCount(1) item1 = QTableWidgetItem('') self.tableWidget_komplectuyshie.setItem(0, 1, item1) item2 = QTableWidgetItem('') self.tableWidget_komplectuyshie.setItem(0, 2, item2) combo = QComboBox() for t in combo_box_options: combo.addItem(t) self.tableWidget_komplectuyshie.setCellWidget(0, 0, combo) def ok(self): pass def write(self): a = self.read_table() db_session.global_init( '/Users/gavrishekaterina/PycharmProjects/olimp3-master/app/drons1.sqlite' ) print(a) for i in range(len(a)): b = balance.Balance() b.name_det = a[i][0] b.quantity = int(a[i][2]) b.date = datetime.datetime.today() session = db_session.create_session() session.add(b) session.commit() def add_stroka(self): combo_box_options = [] db_session.global_init('sql/db/drons1.sqlite') session = db_session.create_session() for user in session.query(details.DetailCategory): combo_box_options.append(user.name_det) self.tableWidget_komplectuyshie.setRowCount(self.size_table + 1) itm = QTableWidgetItem(str('')) combo = QComboBox() for t in combo_box_options: combo.addItem(t) self.tableWidget_komplectuyshie.setCellWidget(self.size_table, 0, combo) self.tableWidget_komplectuyshie.setItem(self.size_table, 1, itm) itm1 = QTableWidgetItem(str('')) self.tableWidget_komplectuyshie.setItem(self.size_table, 2, itm1) self.size_table += 1 self.tableWidget_komplectuyshie.resizeColumnsToContents() def closing(self): if self.last_table_update == self.read_table(): UiMainWindow.close(self) else: msg = QMessageBox() msg.setWindowTitle("Информация") msg.setText("Есть несохранённые изменения") # msg.setInformativeText(f"{message1}\n{message2}\n{message3}") msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) retval = msg.exec_() if retval == QMessageBox.Ok: UiMainWindow.close(self) def read_table(self): # эта функция возвращает данные таблицы # список состоит из списков, вот так: # [["комплектющее", "серийный номер", "количество"], ["комплектющее", "серийный номер", "количество"]] info_table = [] for i in range(self.size_table): a = [] for j in range(3): if j != 0: a.append(self.tableWidget_komplectuyshie.item(i, j).text()) else: a.append( self.tableWidget_komplectuyshie.cellWidget( i, j).currentText()) info_table.append(a) return info_table
class DeleteOrphansDirector(QMdiSubWindow): def __init__(self, main): """ Class for delete directors who are orphan in database. :param main: Reference for main windows. """ super(DeleteOrphansDirector, self).__init__() self.session = DB.get_session() self.director = self.session.query(Director) self.main = main window_title = texts.delete_orphans + ' ' + texts.director_p self.setWindowTitle(window_title) self.subwindow = QWidget() p = self.palette() p.setColor(self.backgroundRole(), QColor(230, 230, 250)) self.setPalette(p) self.setWidget(self.subwindow) font = QFont() font.setPointSize(12) # Vbox Main self.vbox_main = QVBoxLayout(self.subwindow) self.vbox_main.setContentsMargins(20, 20, 20, 20) self.vbox_main.setSpacing(10) # Table Cast self.table = QTableWidget() self.table.setColumnCount(2) self.table.setContentsMargins(20, 0, 0, 0) self.table.setHorizontalHeaderLabels([ texts.director_s, 'Del' ]) # table set column width w = int(0.5 * main.frameSize().width()) col_1 = int(0.60 * (w - 50)) col_2 = int(0.20 * (w - 50)) col_width = col_1 + col_2 + 4 self.table.setColumnWidth(0, col_1) self.table.setColumnWidth(1, col_2) self.table.rowHeight(30) self.table.setFixedWidth(col_width) self.table.horizontalHeader().setFont(font) self.table.horizontalHeader().setStyleSheet( 'background-color: rgb(230, 230, 230);') self.table.verticalHeader().setVisible(False) self.rows = 0 self.ch_del = [] self.vbox_main.addWidget(self.table) # Buttons self.pb_delete = pb_create(texts.pb_delete, 12, 40) self.pb_delete.setMinimumHeight(40) self.pb_delete.setShortcut('Ctrl+D') self.pb_delete.clicked.connect(self.delete) self.pb_leave = pb_create(texts.pb_leave, 12, 40) self.pb_leave.setMinimumHeight(40) self.pb_leave.setShortcut('Ctrl+Q') self.pb_leave.clicked.connect(self.close) self.pb_help = pb_create(texts.pb_help, height=40) self.pb_help.setMinimumHeight(40) self.pb_help.clicked.connect(self.help) self.pb_help.setShortcut('Ctrl+H') self.pb_select_all = pb_create(texts.pb_select_all, 12, 40) self.pb_select_all.setMinimumHeight(40) self.pb_select_all.setShortcut('Ctrl+A') self.pb_select_all.clicked.connect(self.select_all) self.hb_pb = QHBoxLayout() self.hb_pb.setSpacing(10) self.hb_pb.addWidget(self.pb_delete) self.hb_pb.addWidget(self.pb_leave) self.hb_pb.addWidget(self.pb_help) self.hb_pb.addWidget(self.pb_select_all) self.vbox_main.addLayout(self.hb_pb) self.width = col_width + 44 self.height = int(0.8 * main.frameSize().height()) self.setGeometry(0, 0, self.width, self.height) self.create_table() def create_table(self): """ Create a table for show all orphan directors info and with a QCheckBox that if is check the actor will be delete. """ sub = self.session.query(MovieDirector.director_id) sub = sub.distinct() director_result = self.director.filter(Director.id.notin_(sub)).all() for director in director_result: self.table.insertRow(self.rows) self.table.setItem(self.rows, 0, QTableWidgetItem(director.name)) ch_del = QCheckBox(str(director.id)) self.ch_del.append(ch_del) hb_del = hbox_create([self.ch_del[self.rows]], 0) hb_del.setAlignment(Qt.AlignCenter) cell_del = QWidget() cell_del.setLayout(hb_del) self.table.setCellWidget(self.rows, 1, cell_del) if self.rows % 2 != 0: self.table.item(self.rows, 0).setBackground( QColor(230, 230, 230) ) self.table.cellWidget(self.rows, 1).setStyleSheet( 'background-color: #E6E6E6;' 'color: #E6E6E6;' ) else: self.table.cellWidget(self.rows, 1).setStyleSheet( 'color: #FFFFFF;' ) self.table.item(self.rows, 0).setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self.rows += 1 height = self.rows * 30 + 20 self.table.setMinimumHeight(height) self.height = height + 130 self.setGeometry(0, 0, self.width, self.height) def delete(self): """ Delete director from database. """ delete_orphans(self.session, self.ch_del, Director, texts.director_s) self.clear() self.create_table() def select_all(self): """ Mark all delete QCheckBox. """ for ch in self.ch_del: ch.setChecked(True) # Clear def clear(self): """ Call for help. :return: Show a help view. """ for row in range(self.rows): self.table.removeRow(row) self.table.clear() self.table.setRowCount(0) self.rows = 0 self.ch_del = [] self.session.expire_all() # Help def help(self): # I have to perform help preview functions on the main because the bug # "stack_trace posix.cc (699)" does not let the page find its directory. dir = os.getcwd() url = 'file:///' + dir + '/views_help/help_delete_orphans.html' self.main.views_help(url, texts.help_edit_movie) # Close Event def closeEvent(self, event): self.session.close()
class RowControlTableWidget(QWidget): def __init__(self, items = [('col1_name', 'default text'), ('col2_name', ['dfeault', 'combo', 'elements'])]): super(RowControlTableWidget, self).__init__() self.ordered_column_keys = [ z[0] for z in items ] self.default_row = { z[0]:z[1] for z in items } self.table = QTableWidget(1, len(items)) self.table.setHorizontalHeaderLabels(self.ordered_column_keys) self.add_row_button = QPushButton('Add Row') self.add_row_button.clicked.connect(self.add_row) self.delete_row_button = QPushButton('Delete Row') self.delete_row_button.clicked.connect(self.delete_row) hbox = QHBoxLayout() hbox.setContentsMargins(0,0,0,0) hbox.addWidget(self.add_row_button) hbox.addWidget(self.delete_row_button) self.layout = QVBoxLayout() self.layout.setContentsMargins(0,0,0,0) self.layout.addLayout(hbox) self.layout.addWidget(self.table) def reset_row_template(self, items = [('col1_name', 'default text'), ('col2_name', ['dfeault', 'combo', 'elements'])]): # use to (re)set the values of the drop down elements inside the table cells self.ordered_column_keys = [ z[0] for z in items ] self.default_row = { z[0]:z[1] for z in items } def add_row(self): new_row_number = self.table.rowCount() self.table.setRowCount(self.table.rowCount()+1) for column, key in enumerate(self.ordered_column_keys): value = self.default_row[key] # print(value, type(value)) if isinstance(value, str): item = QTableWidgetItem(value) self.table.setItem(new_row_number, column, item) elif isinstance(value, list): combo_box = QComboBox() combo_box.insertItems(0, value) # combo_box.setCurrentText(value[0]) self.table.setCellWidget(new_row_number, column, combo_box) else: message = 'Table cells are expected to be either Dict (added asQComboBox via setCellWidget) or String (added as QTableWidgetItem). You have type ' + str(type(value)) message += ' at position ' + str(new_row_number) + ', ' + str(column) raise CellObjectException(message) def delete_row(self): self.table.removeRow(self.table.currentRow()) def show(self): self.table.show() self.add_row_button.show() self.delete_row_button.show() def hide(self): self.table.hide() self.add_row_button.hide() self.delete_row_button.hide() def set_text(self, items): # where items should be list of lists of objects that can be either dict (loads as QComboBox) or string (used in setItem) # print('siphon itmes', items) self.table.setRowCount(len(items)) self.table.setColumnCount(len(items[0])) for i, row in enumerate(items): # print('siphon row', row) for j, value in enumerate(row): if isinstance(value, str): item = QTableWidgetItem(value) self.table.setItem(i, j, item) elif isinstance(value, dict): combo_box = QComboBox() dict_keys = list(value.keys()) selected = dict_keys[0] if isinstance(value[selected], dict): combo_box.insertItems(0, list(value[selected].values())) else: combo_box.insertItems(0, value[selected]) combo_box.setCurrentText(selected) self.table.setCellWidget(i, j, combo_box) else: message = 'Table cells are expected to be either Dict (added asQComboBox via setCellWidget) or String (added as QTableWidgetItem). You have type ' + str(type(value)) message += ' at position ' + str(i) + ', ' + str(j) raise CellObjectException(message) def get_values(self): table = [] for i in range(self.table.rowCount()): row = [] for j in range(self.table.columnCount()): try: row.append(self.table.item(i, j).text()) except AttributeError: row.append(self.table.cellWidget(i, j).currentText()) table.append(row) return table
class Menumaker(QWidget): entries = [] def __init__(self): super().__init__() self.initTable() gen = QPushButton('Generate') gen.clicked.connect(self.output) filename = QLineEdit(FILENAME) hbox0 = QHBoxLayout() hbox0.addWidget(gen) hbox0.addWidget(filename) save = QPushButton('Save') savefn = QLineEdit('TileMenuDesktopEntries.cfg') hbox1 = QHBoxLayout() hbox1.addWidget(save) hbox1.addWidget(savefn) load = QPushButton('Load') loadfn = QLineEdit('TileMenuDesktopEntries.cfg') hbox2 = QHBoxLayout() hbox2.addWidget(load) hbox2.addWidget(loadfn) vbox = QVBoxLayout() vbox.addWidget(self.table) vbox.addLayout(hbox1) vbox.addLayout(hbox2) vbox.addLayout(hbox0) self.setGeometry(300, 300, 960, 500) self.setLayout(vbox) self.show() def findEntries(self): desktopfiles = [] for i in APPPATHLIST: try: lst = os.listdir(path=i) for j in lst: desktopfiles.append(i + '/' + j) except FileNotFoundError: pass self.entries = [] i = 0 for f in desktopfiles: file = open(f) params = {} for line in file: s = line.split('=') if s[0] == 'Icon' or s[0] == 'Exec' or s[0] == 'Name': params.update({s[0] : s[1][0:-1]}) if params.get('Icon', None) == None: params['Icon'] = 'noicon' if params.get('Name', None) == None: params['Name'] = 'noname' if params.get('Exec', None) == None: params['Exec'] = 'true' params['On'] = CHECKALL s = SIZE x = i % W * s y = i // W * s params.update({'Size':s, 'x':x, 'y':y}) params['Icon'] = self.iconPath(params['Icon']) self.entries.append(params) i += 1 def output(self, filename): self.getEntriesFromTable() filename = 'test.py' out = open(filename, 'w') out.write(BEGIN) for e in self.entries: if e.get('Exec') != None and e.get('On'): out.write(TEMPLATE % (e['x'], e['y'], e['Size'], e.get('Exec', ''), e.get('Icon', ''))) out.close() def initTable(self): self.findEntries() self.table = QTableWidget(len(self.entries), 4) self.table.setColumnWidth(0, self.table.rowHeight(0)) self.table.setColumnWidth(1, 150) self.table.setColumnWidth(2, 300) self.table.setColumnWidth(3, 400) i = 0 for e in self.entries: self.table.setCellWidget(i, 0, QCheckBox('')) self.table.cellWidget(i, 0).setCheckState(e['On']) self.table.cellWidget(i, 0).setTristate(False) self.table.setCellWidget(i, 1, QLabel(e['Name'])) self.table.setCellWidget(i, 2, QLineEdit(e['Exec'])) self.table.setCellWidget(i, 3, QLineEdit(e['Icon'])) i += 1 def getEntriesFromTable(self): for i in range(self.table.rowCount()): self.entries[i]['On'] = bool(self.table.cellWidget(i, 0).checkState()) self.entries[i]['Exec'] = self.table.cellWidget(i, 2).text() self.entries[i]['Icon'] = self.table.cellWidget(i, 3).text()
class ScanWidget(QWidget): def __init__(self, filename): super(ScanWidget, self).__init__() # 窗口类大小 self.filename = filename # 打开数据库 database = sqlite3.connect("./app.db") self.query = database.cursor() # 扫描录入和手动录入btn scanInputBtn = QPushButton("扫描录入") scanInputBtn.clicked.connect(self.showScanDialog) handInputBtn = QPushButton("手动录入") handInputBtn.clicked.connect(self.showScanHand) # 总价label和完成btn self.totalLabel = QLabel("总价: %.2f" % 0) self.finishBtn = QPushButton("完成") # self.finishBtn.clicked.connect(self.uploadData) # 表格空间 self.table_info = QTableWidget() self.table_info.setColumnCount(12) self.table_info.setHorizontalHeaderLabels(["条码", "名称", "品种", "单价", "单位", "分类", "包装完整性", "有无配送码", "配送码", "数量", "总价", "操作"]) self.table_info.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 布局填充数据 layout = QVBoxLayout() btn_layout = QHBoxLayout() btn_widget = QWidget() btn_layout.addWidget(scanInputBtn) btn_layout.addWidget(handInputBtn) btn_widget.setLayout(btn_layout) layout.addWidget(self.table_info) layout.addWidget(btn_widget) layout.addWidget(self.totalLabel) layout.addWidget(self.finishBtn) self.setLayout(layout) # 绘制页面格式 style_str = "QLabel{font-size: 30px;}" + "QLineEdit{font-size: 30px;}" + \ "QPushButton{font-size: 25px; background-color: green; min-height: 30px}" + \ "QComboBox{font-size: 30px;}" + \ "QHeaderView{font-size: 25px;} QTableWidget{font-size: 25px;}" self.setStyleSheet(style_str) self.initYanData() # 初始化数据 def initYanData(self): wb = openpyxl.load_workbook(self.filename) results = get_yan_info(wb) for result in results: self.tableAddInfo(result) # 显示弹窗扫描录入 def showScanDialog(self): self.scan_dial = ScanDial() self.scan_dial.dialogSignal.connect(self.queryYanInfo) self.scan_dial.show() # 显示弹窗选择录入 def showScanSwitch(self, yan_id): self.scan_switch = ScanSwitch(yan_id) self.scan_switch.dialogSignal.connect(self.handleSwitch) self.scan_switch.show() # 显示弹窗手动录入 def showScanHand(self, yan_id): self.scan_hand = ScanHand(yan_id) # self.scan_hand.yanidSignal.connect(self.queryYanInfo) self.scan_hand.yaninfoSignal.connect(self.handleHand) self.scan_hand.show() # 查询烟草信息 def queryYanInfo(self, yan_id): res = self.querySql(yan_id) # 如果未查询到数据为空字典 self.scan_dial.close() if not res: # 未查询到数据,弹窗让用户选择重新扫描还是手动输入 self.showScanSwitch(yan_id) else: # 查询到数据,显示到页面中 self.tableAddInfo(res) # 封装查询语句 def querySql(self, yan_id): result = self.query.execute("select * from yaninfo where yan_id == %s" % yan_id) response = {} for row in result: response = { "yan_id": row[0], "yan_name": row[1], "yan_type": row[2], "yan_price": str(row[3]), "yan_unit": "条", "yan_pinzhong": "卷烟" } return response # 选择窗口 def handleSwitch(self, data, yan_id): self.scan_switch.close() if data == 0: # 继续扫描 self.showScanDialog() else: # 手动输入 print(123, yan_id) self.showScanHand(yan_id) # 处理手写数据 def handleHand(self, data): self.scan_hand.db.close() self.scan_hand.close() self.tableAddInfo(data) # 设置窗口表格数据 def tableAddInfo(self, data): # 如果已经在数据中,提示 if self.idHasIn(data["yan_id"]): QMessageBox.critical(self, "错误", "数据已经在列表中", QMessageBox.Yes) return index = self.table_info.rowCount() self.table_info.setRowCount(index + 1) self.table_info.setItem(index, ColIndex.yan_id, QTableWidgetItem(data["yan_id"])) self.table_info.setItem(index, ColIndex.yan_name, QTableWidgetItem(data["yan_name"])) yan_pinzhong = QLineEdit() if "yan_pinzhong" not in data.keys(): data["yan_pinzhong"] = "卷烟" yan_pinzhong.setText(data["yan_pinzhong"]) self.table_info.setCellWidget(index, ColIndex.yan_pinzhong, yan_pinzhong) self.table_info.setItem(index, ColIndex.yan_price, QTableWidgetItem(str(data["yan_price"]))) self.table_info.setItem(index, ColIndex.yan_unit, QTableWidgetItem(data["yan_unit"])) # 包装完整性 yan_baozhuang = QComboBox() yan_baozhuang.addItems(["完好无破损", "有破损"]) yan_baozhuang.setCurrentIndex(0) if "yan_baozhuang" in data.keys(): if data["yan_baozhuang"] == "完好无破损": yan_baozhuang.setCurrentIndex(0) else: yan_baozhuang.setCurrentIndex(1) else: yan_baozhuang.setCurrentIndex(0) self.table_info.setCellWidget(index, ColIndex.yan_baozhuang, yan_baozhuang) # 烟草分类 yan_sort = QComboBox() yan_sort.addItems(["假", "非", "无专卖字样", "授权生产", "专供出口"]) # 如果yan_id不是以6901028开头的,默认是走私烟 if re.match(r"^6901028.*", data["yan_id"]): pass else: data["yan_sort"] = "无专卖字样" if "yan_sort" in data.keys(): if data["yan_sort"] == "假": yan_sort.setCurrentIndex(0) elif data["yan_sort"] == "非": yan_sort.setCurrentIndex(1) elif data["yan_sort"] == "无专卖字样": yan_sort.setCurrentIndex(2) elif data["yan_sort"] == "授权生产": yan_sort.setCurrentIndex(3) else: yan_sort.setCurrentIndex(4) self.table_info.setCellWidget(index, ColIndex.yan_sort, yan_sort) # 有无配送码 peisong_code = QLineEdit() peisong_status = QComboBox() peisong_status.addItems(["有配送码", "无配送码", "配送码模糊不清"]) if "yan_peisong_status" in data.keys(): if data["yan_peisong_status"] == "配送码": peisong_status.setCurrentIndex(0) peisong_code.setText(data["peisong_code"]) elif data["yan_peisong_status"] == "无配送码": peisong_status.setCurrentIndex(1) else: peisong_status.setCurrentIndex(2) else: peisong_status.setCurrentIndex(0) self.table_info.setCellWidget(index, ColIndex.yan_peisong_status, peisong_status) self.table_info.setCellWidget(index, ColIndex.yan_peisong_code, peisong_code) # 数量 yan_count = TableEdit(index=index) if "yan_count" in data.keys(): yan_count.setText(data["yan_count"]) yan_validator = QIntValidator(1, 9999999) yan_count.setValidator(yan_validator) yan_count.textChanged.connect(self.getSelfTotalPrice) self.table_info.setCellWidget(index, ColIndex.yan_count, yan_count) # 单种类烟草总价 if "yan_total" in data.keys(): self.table_info.setItem(index, ColIndex.yan_total, QTableWidgetItem(data["yan_total"])) else: self.table_info.setItem(index, ColIndex.yan_total, QTableWidgetItem(0)) # 删除按钮 btn_del = TableBtn(name="删除", index=index) btn_del.clicked.connect(self.deleteRow) self.table_info.setCellWidget(index, ColIndex.yan_del, btn_del) # 获取单条烟草的总价 def getSelfTotalPrice(self): try: count = int(self.sender().text()) except Exception as e: count = 0 index = self.sender().index price = float(self.table_info.item(index, ColIndex.yan_price.value).text()) self.table_info.item(self.sender().index, ColIndex.yan_total).setText("%.2f" % (count * price)) self.totalLabel.setText("总价: %.2f" % self.getAllTotalPrice()) # 获取此次扫描的总价 def getAllTotalPrice(self): row_count = self.table_info.rowCount() price_count = 0 for i in range(row_count): try: self_count = float(self.table_info.item(i, ColIndex.yan_total).text()) except Exception as e: print(e) self_count = 0 price_count += self_count return price_count # 删除所在行 def deleteRow(self): sender = self.sender() self.table_info.removeRow(sender.index) self.updateRowIndex() # 更新索引 def updateRowIndex(self): row_count = self.table_info.rowCount() for i in range(row_count): self.table_info.cellWidget(i, ColIndex.yan_count.value).set_index(i) self.table_info.cellWidget(i, ColIndex.yan_del.value).set_index(i) # 判断列表中是否有该数据 def idHasIn(self, id): row_count = self.table_info.rowCount() has_in = False for i in range(row_count): if self.table_info.item(i, ColIndex.yan_id.value).text() == id: has_in = True break return has_in # 上传数据 def uploadData(self): wb = openpyxl.load_workbook(self.filename) try: ws = wb["违规烟草记录"] except Exception as e: ws = wb.create_sheet(title="违规烟草记录") title_list = ["条形码", "名称", "单价", "单位", "分类", "数量", "总价", "品种", "包装完整性", "有无配送码", "配送码"] # 设置表头 for index, title in enumerate(title_list): ws[getLetter(index) + "1"] = title # 填充数据 row_count = self.table_info.rowCount() num_count = 0 price_count = 0.0 for i in range(row_count): ws["A" + str(i + 2)] = self.table_info.item(i, ColIndex.yan_id.value).text() ws["B" + str(i + 2)] = self.table_info.item(i, ColIndex.yan_name.value).text() ws["C" + str(i + 2)] = self.table_info.item(i, ColIndex.yan_price.value).text() ws["D" + str(i + 2)] = self.table_info.item(i, ColIndex.yan_unit.value).text() yan_sort = self.table_info.cellWidget(i, ColIndex.yan_sort.value).currentText() yan_count = self.table_info.cellWidget(i, ColIndex.yan_count.value).text() yan_total = self.table_info.item(i, ColIndex.yan_total.value).text() yan_pinzhong = self.table_info.cellWidget(i, ColIndex.yan_pinzhong.value).text() ws["E" + str(i + 2)] = yan_sort ws["F" + str(i + 2)] = yan_count num_count += int(yan_count) ws["G" + str(i + 2)] = yan_total ws["H" + str(i + 2)] = yan_pinzhong baozhuang = self.table_info.cellWidget(i, ColIndex.yan_baozhuang.value).currentText() ws["I" + str(i + 2)] = baozhuang peisong_status = self.table_info.cellWidget(i, ColIndex.yan_peisong_status.value).currentText() ws["J" + str(i + 2)] = peisong_status peisong_code = self.table_info.cellWidget(i, ColIndex.yan_peisong_code.value).text() ws["K" + str(i + 2)] = peisong_code price_count += float(yan_total) ws["L1"] = "总条数:" + str(num_count) ws["M1"] = "总案值:" + str(price_count) wb.save(self.filename)
class Content(QWidget): def __init__(self, rows, columns): super().__init__() self.table = QTableWidget(rows, columns, self) self.table.setHorizontalHeaderLabels(['Name', 'Starting Time', 'Duration (Hrs)', 'Booking Date (MM-DD)', 'Booking Time', 'Booking Location']) header = self.table.horizontalHeader() header.setFont(QFont('SansSerif', 14)) header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.ResizeToContents) header.setSectionResizeMode(4, QHeaderView.ResizeToContents) header.setSectionResizeMode(5, QHeaderView.ResizeToContents) # header.setSectionResizeMode(6, QHeaderView.ResizeToContents) header.setStretchLastSection(True) b = ['Student' for j in range(1,rows)] b.insert(0, 'Example') self.table.setVerticalHeaderLabels(b) # index = self.table.verticalHeader() # for i in range(rows): # index.setSectionResizeMode(i, QHeaderView.ResizeToContents) # self.table.setSelection self.table.setFont(QFont('SansSerif', 12)) self.table.setItem(0,0,QTableWidgetItem('Eric Yung')) self.table.setItem(0,1,QTableWidgetItem('14:00')) # select self.table.setItem(0,2,QTableWidgetItem('2')) # select self.table.setItem(0,3,QTableWidgetItem('Click below to choose')) # calendar # self.table.setItem(0,4,QTableWidgetItem('20-01')) # calendar self.table.setItem(0,4,QTableWidgetItem('14:00-16:00')) # time range self.table.setItem(0,5,QTableWidgetItem('FoTan/ YauMaTei/ ShekMun')) # selection # Todo: Replace hardcoded columns with variables for row in range(1,rows): # Set empty text boxes empty_text_cols = (0, 1, 2, 4) # hardcode for col in empty_text_cols: item = QTableWidgetItem('') self.table.setItem(row, col, item) # Set column 3 calender button btn = QPushButton('Choose Time') btn.clicked.connect(partial(self.showCalendar, row)) self.table.setCellWidget(row, 3, btn) # hardcode # Set column 5 location dropdown list combo = QComboBox() combo.addItem('') # use n/a? combo.addItem("FoTan") combo.addItem("YauMaTei") combo.addItem("ShekMun") self.table.setCellWidget(row, 5, combo) # hardcode datelabel = QLabel('Date:') datelabel.setFont(QFont('SansSerif', 14)) time_of_the_day = QLabel('%s' %datetime.datetime.now().date()) time_of_the_day.setFont(QFont('SansSerif', 14)) locationlabel = QLabel("Centre:") locationlabel.setFont(QFont('SansSerif', 14)) location = QComboBox() location.setFont(QFont('SansSerif', 14)) location.addItem('') location.addItem("FoTan") location.addItem("YauMaTei") location.addItem("ShekMun") # Todo(alan): consider making this a class attr self.location_labels = ('', 'F', 'Y', 'S') # Todo(alan): refactor these attrs? self.time_of_the_day = time_of_the_day self.location = location self.vbox1 = QVBoxLayout() self.hbox = QHBoxLayout() hbox_firstlay = QHBoxLayout() # self.vbox1.addStretch(1) # self.hbox_firstlay.addStretch(0.5) hbox_firstlay.addWidget(datelabel) hbox_firstlay.addWidget(self.time_of_the_day) hbox_firstlay.addStretch(0.5) # hbox_firstlay.addSpacing(50) hbox_firstlay.addWidget(locationlabel) hbox_firstlay.addWidget(self.location) self.vbox1.addLayout(hbox_firstlay) self.hbox.addWidget(self.table) self.vbox1.addLayout(self.hbox) # self.vbox1.setStretch(1,1) self.setLayout(self.vbox1) def handleSave(self): path = QFileDialog.getSaveFileName(self, 'Save File', '.csv', 'CSV(*.csv)')[0] # saved flap for smoother terminating self.saved = 0 try: with open(path, 'w', encoding='big5-hkscs') as stream: writer = csv.writer(stream) rowdata = [] rowdata.extend(('Name', 'Starting Time', 'Duration', 'Booking Date', 'Booking Time', 'Booking Location')) rowdata.append('%s' % self.time_of_the_day.text()) rowdata.append('%s' % self.location_labels[self.location.currentIndex()]) writer.writerow(rowdata) for row in range(1, self.table.rowCount()): rowdata = [] for column in range(self.table.columnCount()): if column == 5: item = self.table.cellWidget(row, column) # this is setting the location if item is not None: rowdata.append(self.location_labels[item.currentIndex()]) else: rowdata.append('') elif column == 3: item = self.table.cellWidget(row, column) # this is setting the location if item.text() != 'Choose Time': rowdata.append(item.text()) else: rowdata.append('') else: item = self.table.item(row, column) if item is not None and str(item.text()) != 'Enter': rowdata.append(str(item.text())) elif str(item.text()) == 'Enter': rowdata.append('') else: rowdata.append('') writer.writerow(rowdata) self.saved = 1 # self.e.updatedateApp.emit() except FileNotFoundError: pass def handleOpen(self): path = QFileDialog.getOpenFileName(self, 'Open File', '.csv', 'CSV(*.csv)')[0] try: with open(path, 'r', encoding='big5-hkscs') as stream: self.table.setRowCount(0) self.table.setColumnCount(0) for rowdata in csv.reader(stream): row = self.table.rowCount() self.table.insertRow(row) self.table.setColumnCount(len(rowdata)) for column, data in enumerate(rowdata): # data = QTableWidgetItem(data) if column == 5: if data == "F": data = "FoTan" elif data == "Y": data = "YauMaTei" elif data == "S": data = "ShekMun" else: data = 'Enter' combo = QComboBox() combo.addItem('Enter') combo.addItem("FoTan") combo.addItem("YauMaTei") combo.addItem("ShekMun") self.table.setCellWidget(row, column, combo) index = combo.findText(data, Qt.MatchFixedString) combo.setCurrentIndex(index) else: item = QTableWidgetItem(data) self.table.setItem(row, column, item) except FileNotFoundError: pass def showCalendar(self, row): dialog = QDialog() vbox1 = QVBoxLayout() cal = QCalendarWidget() cal.setGridVisible(True) dialog.setToolTip('Double-click to confirm') # single click cal.clicked[QDate].connect(partial(self.setDate, row, cal)) # double click cal.activated[QDate].connect(partial(self.setDateAndClose, row, cal, dialog)) vbox1.addWidget(cal) dialog.setLayout(vbox1) dialog.exec() def setDate(self, row, cal): date = cal.selectedDate() self.table.cellWidget(row, 3).setText((date.toString())) def setDateAndClose(self, row, cal, dialog): self.setDate(row, cal) dialog.close()
class IncomeEventClaster(QDialog): def __init__(self, header, IncomeSourceCategory, currency, parent = None): QDialog.__init__(self, parent) self._acceptState = False self._dataContainer = {} self._header = header self._IncomeSourceCategory = IncomeSourceCategory self._Currency = currency self.date = [1993,1,22] self.InitUI() self.addRowWidgets() self.show() #+++++++++++++++++++++++++++ InitUI +++++++++++++++++++++++++++++++++++ def InitUI(self): self.setWindowTitle("მონაცემთა შეტანა") self.setWindowIcon(QtGui.QIcon("icon/income.svg")) self.setFixedSize(750, 900) vbox = QVBoxLayout() hbox = QHBoxLayout() vbox.setContentsMargins(2, 2, 2, 2) ########################### Calendar ################################## self.calendar = QCalendarWidget() self.calendar.setGridVisible(True) self.calendar.setFirstDayOfWeek(Qt.Monday) ############################ Table #################################### self.table = QTableWidget() self.table.setRowCount(1) self.table.setColumnCount(len(self._header)) self.table.setHorizontalHeaderLabels(self._header) self.table.setSortingEnabled(False) self.table.setWordWrap(True) self.rowNumb = self.table.rowCount()-1 ########################### add Row ################################### self.addRowButton = QPushButton('დამატება') self.addRowButton.setMaximumWidth(100) self.addRowButton.setIcon(QIcon('icon/addRow.svg')) self.addRowButton.clicked.connect(self.addRow) ########################### del Row ################################### self.delRowButton = QPushButton('წაშლა') self.delRowButton.setMaximumWidth(100) self.delRowButton.setIcon(QIcon('icon/DelRow.svg')) self.delRowButton.clicked.connect(self.delRow) ############################# test #################################### self.testButton = QPushButton('ტესტი') self.testButton.setIcon(QIcon('icon/test.png')) self.testButton.clicked.connect(self.test) ############################ Accept ################################### self.acceptButton = QPushButton('დადასტურება', self) self.acceptButton.clicked.connect(self.acceptDialog) ############################ Reject ################################### self.rejectButton = QPushButton('გაუქმება', self) self.rejectButton.clicked.connect(self.rejectDialog) #################### Add widgets on layouts ########################### hbox.addWidget(self.addRowButton) hbox.addWidget(self.delRowButton) vbox.addWidget(self.calendar,5) vbox.addWidget(self.table,90) vbox.addLayout(hbox) vbox.addWidget(self.testButton,5) hboxAcceptReject = QHBoxLayout() hboxAcceptReject.addWidget(self.acceptButton) hboxAcceptReject.addWidget(self.rejectButton) vbox.addLayout(hboxAcceptReject) self.setLayout(vbox) #++++++++++++++++++++++++++ Add Row +++++++++++++++++++++++++++++++++++ def addRow(self): self.rowNumb = self.table.rowCount() self.table.insertRow(self.rowNumb) self.addRowWidgets() #++++++++++++++++++++++ Add Row Widgets +++++++++++++++++++++++++++++++ def addRowWidgets(self): ########################## emountEdit ################################# quantityEdit = QLineEdit('') quantityEdit.setValidator(QDoubleValidator()) ###################### Currency Selector ############################## CurrencySelector = QComboBox() for idx, key in enumerate(self._Currency): CurrencySelector.addItem(key) CurrencySelector.setItemData(idx, Qt.AlignCenter, Qt.TextAlignmentRole) CurrencySelector.setItemIcon(idx, QtGui.QIcon(self._Currency[key])) quantityEditHlayout = QHBoxLayout() quantityEditHlayout.addWidget(quantityEdit,50) quantityEditHlayout.addWidget(CurrencySelector,50) quantityEditWidgets = QWidget() quantityEditWidgets.setLayout(quantityEditHlayout) ################## Income Category Selector ########################### incomeCategorySelector = QComboBox() incomeCategorySelector.addItems(self._IncomeSourceCategory) self.table.setCellWidget(self.rowNumb, 0, incomeCategorySelector) self.table.setCellWidget(self.rowNumb, 1, quantityEditWidgets) self.table.cellWidget(self.rowNumb,0).activated.connect(self.incomeCategoryFormater) ################### Set Table Cell Widths ############################# self.table.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) # +++++++++++++ String to float number formater +++++++++++++++++++++++ def _stingToFloatFormater(self, value): if ',' in value: value = value.replace(",", ".") return value else: return value #++++++++++++++++++++++++ Delete Row ++++++++++++++++++++++++++++++++++ def delRow(self): self.rowNumb = self.table.rowCount() if self.rowNumb > 1: selected_Row = self.table.currentRow() self.table.removeRow(selected_Row) self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) #+++++++++++++++++++++ Set calendar date ++++++++++++++++++++++++++++++ def setCalendarDate(self, date): self.calendar.setSelectedDate(QDate(date[0], date[1], date[2])) #+++++++++++++++++++++ Make data claster ++++++++++++++++++++++++++++++ def makeDataClaster(self): self._dataContainer = {} dataContainerArray = [] self.rowNumb = self.table.rowCount() self.colNumb = self.table.columnCount() for row in range(self.rowNumb): dataContainerTemp = [] for column in range(self.colNumb): if column == 0: dataContainerTemp.append({'cell_0' : self.table.cellWidget(row,column).currentIndex()}) elif column == 1: if len(self.table.cellWidget(row, 1).children()[0]) == 2: dataContainerTemp.append({'cell_1.1' : self.table.cellWidget(row,column).children()[1].text(), 'cell_1.2' : self.table.cellWidget(row,column).children()[2].currentIndex()}) elif len(self.table.cellWidget(row, 1).children()[0]) == 4: dataContainerTemp.append({'cell_1.1' : self._stingToFloatFormater(self.table.cellWidget(row,column).children()[1].text()), 'cell_1.2' : self.table.cellWidget(row,column).children()[2].currentIndex(), 'cell_1.3' : self._stingToFloatFormater(self.table.cellWidget(row,column).children()[3].text()), 'cell_1.4' : self.table.cellWidget(row,column).children()[4].currentIndex()}) dataContainerArray.append(dataContainerTemp) self._dataContainer.update({self.calendar.selectedDate().toString("dd.MM.yyyy") : dataContainerArray}) #+++++++++++++++++++++ Edit data claster ++++++++++++++++++++++++++++++ def EditDataClaster(self, DataClasterComponent, timeStamp): for _ in range(len(DataClasterComponent)-1): self.addRow() self.setCalendarDate(QDate.fromString(timeStamp, 'dd.MM.yyyy').getDate()) for row, rowData in enumerate(DataClasterComponent): self.table.cellWidget(row, 0).setCurrentIndex(rowData[0]['cell_0']) self.table.cellWidget(row, 1).children()[1].setText(rowData[1]['cell_1.1']) self.table.cellWidget(row, 1).children()[2].setCurrentIndex(rowData[1]['cell_1.2']) if len(rowData[1]) == 4: quantityEdit = QLineEdit('') quantityEdit.setValidator(QDoubleValidator()) CurrencySelector = QComboBox() for idx, key in enumerate(self._Currency): CurrencySelector.addItem(key) CurrencySelector.setItemData(idx, Qt.AlignCenter, Qt.TextAlignmentRole) CurrencySelector.setItemIcon(idx, QtGui.QIcon(self._Currency[key])) self.table.cellWidget(row, 1).children()[0].addWidget(quantityEdit,50) self.table.cellWidget(row, 1).children()[0].addWidget(CurrencySelector,50) self.table.cellWidget(row, 1).children()[3].setText(rowData[1]['cell_1.3']) self.table.cellWidget(row, 1).children()[4].setCurrentIndex(rowData[1]['cell_1.4']) self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) #++++++++++++++++++++++++++ Accept ++++++++++++++++++++++++++++++++++++ def acceptDialog(self): self.makeDataClaster() self._acceptState = True self.close() #++++++++++++++++++++++++++ Reject ++++++++++++++++++++++++++++++++++++ def rejectDialog(self): self._acceptState = False self.close() #++++++++++++++++++ Get data claster part +++++++++++++++++++++++++++++ def getDataClasterPart(self): return self._dataContainer, self._acceptState #++++++++++++++++++ incomeCategoryFormater ++++++++++++++++++++++++++++ def incomeCategoryFormater(self): changedSelectrorIndex = self.sender() self.rowNumb = self.table.rowCount() for row in range (self.rowNumb): if self.table.cellWidget(row,0) == changedSelectrorIndex: if self.table.cellWidget(row,0).currentIndex() == 7: if len(self.table.cellWidget(row, 1).children()[0]) == 2: quantityEdit = QLineEdit('') quantityEdit.setValidator(QDoubleValidator()) CurrencySelector = QComboBox() for idx, key in enumerate(self._Currency): CurrencySelector.addItem(key) CurrencySelector.setItemData(idx, Qt.AlignCenter, Qt.TextAlignmentRole) CurrencySelector.setItemIcon(idx, QtGui.QIcon(self._Currency[key])) self.table.cellWidget(row, 1).children()[0].addWidget(quantityEdit,50) self.table.cellWidget(row, 1).children()[0].addWidget(CurrencySelector,50) else: try: self.table.cellWidget(row, 1).children()[0].itemAt(2).widget().deleteLater() self.table.cellWidget(row, 1).children()[0].itemAt(3).widget().deleteLater() except AttributeError: pass self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) def read(self): return self._dataContainer #+++++++++++++++++++++++++++ Test +++++++++++++++++++++++++++++++++++++ def test(self): print("Test") self.makeDataClaster()
class PasswordVault_newAccount(QWidget): _dirIcon = os.getcwd() + '/Icon/' _dirBackup = os.getcwd() + '/Backup/' def __init__(self): super(PasswordVault_newAccount, self).__init__() self.myVault = '' self.filename = '' # a fill directory self.password = '' self.viewpass = False self.countViewpassword = [] self.countCheckbox = [] self.countCheckboxAll = False self.table = QTableWidget() self.vlayout = QVBoxLayout() self.move(550, 400) self.setWindowTitle("New account for password vault") self.drawTable() self.events() self.show() def events(self): # Table events self.tablebtnAdd.clicked.connect(self._tablebtnAdd) self.tablebtnDelete.clicked.connect(self._tablebtnDelete) self.tablebtnSave.clicked.connect(self._tablebtnSave) self.table.cellClicked.connect(self._cellCLicked) self.btn_viewpass.clicked.connect(self._viewPass) self.tablebtnSave.installEventFilter(self) self.tbox_pass.installEventFilter(self) #self.tablebtnChangePassword.clicked.connect(self._tableChangepass) #self.table.itemSelectionChanged.connect(self._tableEditTable) def drawTable(self): #check=True height = self.frameGeometry().height() width = self.table.frameGeometry().width() fontBold = QFont() fontBold.setBold(True) self.tablebtnSave = QPushButton("Save") self.tablebtnDelete = QPushButton('-') self.tablebtnAdd = QPushButton('+') sizeHint_height = self.tablebtnAdd.sizeHint().height() self.size = sizeHint_height print(self.size) self.lbl_pass = QLabel("Password:"******"ID")) self.table.setItem(0, 2, QTableWidgetItem('Password')) self.table.setItem(0, 3, QTableWidgetItem('')) self.table.setItem(0, 4, QTableWidgetItem('')) for i in range(0, 5): #print(i) self.table.item(0, i).setFont(fontBold) self.table.item(0, i).setFlags(Qt.ItemIsEnabled) # import data to the table #==== UPDATA the PasswordVault Layout self.table.resizeColumnsToContents() self.vlayout.addWidget(self.table) self.vlayout.addLayout(hboxTable) self.setLayout(self.vlayout) #rint(width,height) #self.table.setFocusPolicy(Qt.NoFocus) self._tablebtnAdd() self.resize(width - (width * 0.2), height - (height * 0.3)) def widgetInsideTable(self): # ===== Button view pass inside table ===== # viewPassbtn=QPushButton() # viewPassbtn.setFixedHeight(self.size_of_btn) # viewPassbtn.setFixedWidth(self.size_of_btn) # viewPassbtn.setIcon(QIcon(self._dirIcon+'icons8-eye-1.png')) # ====== CheckBox ====== checkBox = QTableWidgetItem() checkBox.setIcon(QIcon(self._dirIcon + 'icons8-checkbox-0.png')) checkBox.setFlags(Qt.ItemIsEnabled) ItemViewPass = QTableWidgetItem() ItemViewPass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) ItemViewPass.setFlags(Qt.ItemIsEnabled) self.table.setIconSize(QSize(self.size, self.size)) return checkBox, ItemViewPass def eventFilter(self, ob, event): #print(event.type()) if ob is self.tablebtnSave and event.type() == 129: #print (ob, event.type()) if self.tbox_pass.text() == '': self.tbox_pass.setText("Enter your pass word") self.tbox_pass.setStyleSheet("color: red") self.tbox_pass.setEchoMode(0) self.viewpass = True self.btn_viewpass.setIcon( QIcon(self._dirIcon + 'icons8-eye-0.png')) self.tablebtnSave.setDisabled(True) elif ob is self.tbox_pass and event.type() == 2: self.tbox_pass.setText('') self.tbox_pass.setEchoMode(2) self.viewpass = False self.btn_viewpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) self.tablebtnSave.setDisabled(False) self.tbox_pass.setStyleSheet("color: black") return False def saveFileDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, a = QFileDialog.getSaveFileName( self, "QFileDialog.getSaveFileName()", "", "Text Files (*.txt)", options=options) #print(a) if fileName: return fileName def convertData_2_bytes(self): # this function is user before encrypt data noRow = self.table.rowCount() data = '' for i in range(1, noRow): #print(len(self._listAccount)) Service = self.table.item(i, 0).text() ID = self.table.item(i, 1).text() PASS = self.table.cellWidget(i, 2).text() data += f',{Service},{ID},{PASS}' data = str.encode(data[1:]) return data @pyqtSlot() def _viewPass(self): self.viewpass = not self.viewpass if self.viewpass == True: self.tbox_pass.setEchoMode(0) self.btn_viewpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-0.png')) #print ("echo 0") else: self.tbox_pass.setEchoMode(2) self.btn_viewpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) def _tablebtnAdd( self ): # when a new row added a new account created coreponding to the row nomber #print(self.table.rowCount()) checkBox, iViewPass = self.widgetInsideTable() self.table.insertRow(self.table.rowCount()) newRowidx = self.table.rowCount() - 1 # setup new row self.table.setItem(newRowidx, 0, QTableWidgetItem(' new service')) self.table.setItem(newRowidx, 1, QTableWidgetItem(' new ID ')) self.table.setCellWidget(newRowidx, 2, QLineEdit('type pass')) self.table.setItem(newRowidx, 3, iViewPass) self.table.setItem(newRowidx, 4, checkBox) #self.table.item(newRowidx,3).setIcon(QIcon(self._dirIcon+'icons8-eye-0.png')) self.table.cellWidget(newRowidx, 2).setEchoMode(2) self.countViewpassword.append(True) self.countCheckbox.append(False) self.table.resizeColumnsToContents() def _tablebtnDelete(self): #print(self.countCheckbox) #print(len(self.countCheckbox)) idx = 0 out = True while idx < len(self.countCheckbox): checkBox = self.countCheckbox[idx] if checkBox == True: self.table.removeRow(idx + 1) self.countCheckbox.remove(self.countCheckbox[idx]) idx = -1 idx += 1 #.statusBar.showMessage(f'A row at {self.currentRow-2} was delete') #print(self.countCheckbox) def _tablebtnSave(self): self.filename = self.saveFileDialog() + '.txt' self.password = self.tbox_pass.text() self.myVault = Vault(self.password, self.filename) dataReady = self.convertData_2_bytes() self.myVault.encrypt(dataReady) os.chmod(self.filename, S_IREAD) def _cellCLicked(self, row, column): ## cellClicked for view password if column == 3 and row > 0: self.countViewpassword[row - 1] = not self.countViewpassword[row - 1] if self.countViewpassword[row - 1] == False: self.table.cellWidget(row, 2).setEchoMode(0) self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-eye-0.png')) else: self.table.cellWidget(row, 2).setEchoMode(2) self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-eye-1.png')) ## cellClicked for cehckbox elif column == 4 and row > 0: #print (self.countCheckbox[row-1]) self.countCheckbox[row - 1] = not self.countCheckbox[row - 1] # print('clicked',row, column,self.countCheckbox[row-1]) if self.countCheckbox[row - 1] == True: self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-1.png')) else: self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-0.png')) #print(self.countCheckbox) elif row == 0 and column == 4: self.countCheckboxAll = not self.countCheckboxAll for i in range(1, self.table.rowCount()): if self.countCheckboxAll == True: self.countCheckbox[i - 1] = True self.table.item(i, 4).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-1.png')) else: self.countCheckbox[i - 1] = False self.table.item(i, 4).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-0.png')) self.table.resizeColumnsToContents() # if __name__ == "__main__": # app = QApplication(sys.argv) # w=PasswordVault_newAccount() # try: # sys.exit(app.exec_()) # except: # pass
class CaptureWidget(QWidget): """ This QWidget gather and check the user provided metadata and ask the MainWindow to launch the capture Attributes: self.receive_enable_decklink_radio_1 (pyqtSignal([bool])): signal sent by the StatusWidget self.receive_enable_decklink_radio_2 (pyqtSignal([bool])): signal sent by the StatusWidget self.set_statusbar_text_signal (pyqtSignal([str])): Is used to display text on the MainWindow's statusbar """ receive_enable_decklink_radio_1 = pyqtSignal([bool]) receive_enable_decklink_radio_2 = pyqtSignal([bool]) set_statusbar_text_signal = pyqtSignal([str]) def __init__(self, parent): # Initialize the parent class QWidget # this allow the use of the parent's methods when needed super(CaptureWidget, self).__init__(parent=parent) self.main_window = None ######### self.decklink_label = QLabel("Choisissez la source vidéo") self.decklink_radio_1 = QRadioButton("Decklink 1 (NTSC/PAL)") self.decklink_radio_2 = QRadioButton("Decklink 2 (NTSC/PAL/SECAM)") self.file_import_radio = QRadioButton("importer fichier vidéo") self.dvd_import_radio = QRadioButton("importer dvd") self.lossless_import_checkbox = QCheckBox( "Importer sans perte de qualité") ######### self.digitise_table = QTableWidget() self.table_font = QFont(QFont().defaultFamily(), 12) self.new_table_row_button = QPushButton("Ajouter") self.launch_ffplay_button = QPushButton("Lancer aperçu") self.launch_digitise_button = QPushButton("Numériser") ######### dc_data = OrderedDict() dc_data['dc:contributor'] = "nom des acteurs" dc_data['dc:creator'] = "maison d'édition, scénariste ou réalisateur" dc_data['dc:description'] = "résumé de la vidéo" dc_data['dc:language'] = "langue de la vidéo: FRA, ENG" dc_data[ 'dc:publisher'] = "entreprise qui a publié le film, par exemple Sony Pictures" dc_data[ 'dc:subject'] = "thème du film: horreur, action, histoire d'amour..." dc_data['dc:title'] = "titre du film" dc_data[ 'dcterms:isPartOf'] = "remplir si le film fait partie d'un ensemble de films comme Star Wars" dc_data['dcterms:created'] = "année de sortie du film" dc_data['durée'] = "durée du film en minutes" dc_data['ratio'] = "format visuel du film" dc_data['format_video'] = "format video de la cassette" self.digitise_table_row_tooltip = dc_data ######### self.raw_videos_path = FILES_PATHS["raw"] self.compressed_videos_path = FILES_PATHS["compressed"] self.imported_files_path = FILES_PATHS["imported"] ######### self.backend_is_alive_timer = QTimer() ######### self.tab_init() def delayed_init(self): """ Is called if the wamp router is successfully joined, if you don't wait, you get this: 'NoneType' object has no attribute 'parent' Traceback (most recent call last): File "/usr/local/lib/python3.4/dist-packages/autobahn/wamp/websocket.py", line 62, in onOpen self._session.onOpen(self) AttributeError: 'NoneType' object has no attribute 'onOpen' """ self.main_window = self.parent().parent().parent( ) # MainWindow -> QTabWidget -> QStackedWidget @wrap_in_future @asyncio.coroutine def launch_capture(self, metadata): """ Call the 'launch_capture' function in the backend Args: metadata (list): [digitise_infos, dublincore_dict] """ print("metadata") print(metadata) yield from self.main_window.call('com.digitize_app.launch_capture', metadata) def launch_ffplay(self): decklink_id = None video_format = None if self.decklink_radio_1.isChecked( ) and self.decklink_radio_1.isEnabled(): decklink_id = '1' elif self.decklink_radio_2.isChecked( ) and self.decklink_radio_2.isEnabled(): decklink_id = '2' else: error_box = QMessageBox() error_box.setText( "Veuillez sélectionner une carte d'aquisition non utilisée") error_box.setWindowTitle("Erreur") error_box.exec_() for row in range(self.digitise_table.rowCount()): combobox_text = self.digitise_table.cellWidget(row, 0).currentText() if combobox_text == 'format_video': video_format = self.digitise_table.cellWidget(row, 1).currentText() break if video_format is None and decklink_id == '1': error_box = QMessageBox() error_box.setText("Veuillez préciser le format de la vidéo") error_box.setWindowTitle("Erreur") error_box.exec_() if decklink_id == '1' and video_format: decklink_input = "Intensity Pro (1)" if video_format == 'SECAM': error_box = QMessageBox() error_box.setText( "Il est impossible de numériser une cassette SECAM avec la carte numéro 1" ) error_box.setWindowTitle("Erreur") error_box.exec_() elif video_format == 'PAL': subprocess.Popen([ 'ffplay', '-f', 'decklink', '-format_code', 'pal', '-video_input', 'composite', '-i', decklink_input ]) elif video_format == 'NTSC': subprocess.Popen([ 'ffplay', '-f', 'decklink', '-format_code', 'ntsc', '-video_input', 'composite', '-i', decklink_input ]) elif decklink_id == '2': decklink_input = "Intensity Pro (2)" subprocess.Popen([ 'ffplay', '-f', 'decklink', '-format_code', 'hp60', '-video_input', 'hdmi', '-aspect', '4:3', '-i', decklink_input ]) def backend_is_alive_beacon(self): """ Is called when the backend send a beacon Effect: make a timer decrement from 15000 ms. If the timer reach zero, the widget can't start a new capture. """ self.backend_is_alive_timer.setInterval(39000) def add_table_row(self): """ Is called when the "self.new_table_row_button" button is pressed This function will fill the combobox with their name and a tooltip, link the combobox to the "self.combobox_changed function" and link the delete button with the self.delete_table_row" function """ row_count = self.digitise_table.rowCount() self.digitise_table.insertRow(row_count) self.digitise_table.setCellWidget(row_count, 0, QComboBox()) count = 0 for dc_key, dc_tooltip in self.digitise_table_row_tooltip.items(): self.digitise_table.cellWidget(row_count, 0).addItem(dc_key) self.digitise_table.cellWidget(row_count, 0).setItemData( count, dc_tooltip, Qt.ToolTipRole) count += 1 self.digitise_table.cellWidget(row_count, 0).activated[str].connect( self.combobox_changed) self.digitise_table.setCellWidget(row_count, 1, QLineEdit()) self.digitise_table.setCellWidget(row_count, 2, QPushButton("Delete")) self.digitise_table.cellWidget(row_count, 2).clicked.connect( self.delete_table_row) def delete_table_row(self): """ Is linked to the delete button when a row is added. When the delete button is pressed, the function look up its row and delete it """ sender = self.sender() index = self.digitise_table.indexAt(sender.pos()) if index.isValid(): self.digitise_table.removeRow(index.row()) def combobox_changed(self, text): """ Is linked to the combobox when a row is added When the combobox selected item changes (example: from dc:contributor to dc:description), this function is called to make the row fit its new usage. (example: enter text or a date) Args: text (str): its the active combobox selection """ index = self.digitise_table.indexAt(self.sender().pos()) comboboxes_names_counter = [] for row in range(self.digitise_table.rowCount()): comboboxes_names_counter.append( self.digitise_table.cellWidget(row, 0).currentText()) comboboxes_names_counter = Counter(comboboxes_names_counter) forbidden_duplicates = [ "dc:description", "dcterms:created", "durée", "ratio", "format_video" ] if text in forbidden_duplicates and comboboxes_names_counter[text] > 1: self.digitise_table.cellWidget(index.row(), 0).setCurrentText('dc:contributor') text = 'dc:contributor' error_box = QMessageBox() error_box.setText( "Il est impossible d'avoir plus d'une entrée de ce type") error_box.setWindowTitle("Erreur") error_box.exec_() if index.isValid(): row = index.row() if text == "dc:description": self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QTextEdit()) self.digitise_table.setRowHeight(row, 60) elif text == "dcterms:created": self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QLineEdit()) self.digitise_table.cellWidget(row, 1).setInputMask("0000") self.digitise_table.setRowHeight(row, 30) elif text == "durée": self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QLineEdit()) self.digitise_table.setRowHeight(row, 30) self.digitise_table.cellWidget(row, 1).setInputMask("000") elif text == "ratio": self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QComboBox()) self.digitise_table.setRowHeight(row, 30) self.digitise_table.cellWidget(row, 1).addItems(["4:3", "16:9"]) elif text == "format_video": self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QComboBox()) self.digitise_table.setRowHeight(row, 30) self.digitise_table.cellWidget(row, 1).addItems( ["PAL", "SECAM", "NTSC"]) elif text == "dc:language": self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QLineEdit()) self.digitise_table.setRowHeight(row, 30) self.digitise_table.cellWidget(row, 1).setInputMask("AAA") else: self.digitise_table.removeCellWidget(row, 1) self.digitise_table.setCellWidget(row, 1, QLineEdit()) self.digitise_table.setRowHeight(row, 30) def metadata_checker(self, capture_action, data): """ Check if the required metadata is present. If yes it launches the launch_capture function Args: capture_action (str): tell which capture_action the metadata_checker function should launch Possible values: decklink, file, DVD data: [digitise_infos, dublincore_dict] """ # this check if at least a duration, title, and creation date is set before sending the data to the back end if capture_action == "decklink" and "duration" in data[1].get('dc:format', {}) \ and "format" in data[1].get('dc:format', {}) and "dc:title" in data[1] and "dcterms:created" in data[1] \ and self.check_remaining_space(VHS_duration=data[1]["dc:format"]["duration"]): self.launch_digitise_button.setEnabled(False) self.launch_capture(data) self.launch_digitise_button.setEnabled(True) # set status bar temp text self.set_statusbar_text_signal.emit("Numérisation Decklink lancée") elif capture_action == "file" and "file_path" in data[0] and "dc:title" in data[1] and "dcterms:created" in data[1] \ and self.check_remaining_space(import_file_path=data[0]["file_path"]): self.launch_digitise_button.setEnabled(False) self.launch_capture(data) self.launch_digitise_button.setEnabled(True) self.set_statusbar_text_signal.emit( "Enregistrement du fichier lancé !") elif capture_action == "DVD" and "dc:title" in data[1] and "dcterms:created" in data[1] \ and self.check_remaining_space(for_DVD=True): self.launch_digitise_button.setEnabled(False) self.launch_capture(data) self.launch_digitise_button.setEnabled(True) self.set_statusbar_text_signal.emit( "Enregistrement du DVD lancé !") else: warning_box = QMessageBox() warning_message = ( "Les informations suivantes sont necessaires:\n" " Pour enregistrer un dvd:\n" " un titre et la date de creation de l'oeuvre\n" " Pour enregistrer une cassette:\n" " la durée, un titre, le format et l'année de creation de l'oeuvre\n" " Pour copier un fichier:\n" " un titre et la date de création de l'oeuvre\n" "\n" " Il faut aussi avoir sélectionné une méthode d'enregistrement (decklink, dvd...)" ) warning_box.warning(warning_box, "Attention", warning_message) self.launch_digitise_button.setEnabled(True) def check_remaining_space(self, for_DVD=None, import_file_path=None, VHS_duration=None): """ Check the remaining space in the folder where the video will be saved Args: for_DVD (bool): import_file_path (str): VHS_duration (str): Returns: bool: True if successful, False otherwise. """ error_text = "L'espace disque est insuffisant pour enregistrer la vidéo, " + \ "veuillez contacter le responsable informatique." if for_DVD: free_space = shutil.disk_usage(self.compressed_videos_path)[2] file_size = 15000000000 # 15GB if free_space - file_size < 10000000000: # 10GB error_box = QMessageBox() error_box.setText(error_text) error_box.setWindowTitle("Erreur") error_box.exec_() return False else: return True elif import_file_path: free_space = shutil.disk_usage(self.imported_files_path)[2] file_size = os.path.getsize(import_file_path) if free_space - file_size < 10000000000: # 10GB error_box = QMessageBox() error_box.setText(error_text) error_box.setWindowTitle("Erreur") error_box.exec_() return False else: return True elif VHS_duration: free_space = shutil.disk_usage(self.compressed_videos_path)[2] file_size = VHS_duration * 6.6 * 1000000000 if free_space - file_size < 100000000000: # 100GB error_box = QMessageBox() error_box.setText(error_text) error_box.setWindowTitle("Erreur") error_box.exec_() return False else: return True def gather_metadata(self): """ Gather the user provided metadata and add the constants listed below. dublincore_dict["dc:rights"] = "usage libre pour l'éducation" dublincore_dict["dc:type"] = "video" dublincore_dict["dcterms:modified"] = datetime.now().replace(microsecond=0).isoformat() Notes: This function also set default values for this key but it can be overridden by the user dublincore_dict['dc:format'] = {'aspect_ratio': '4:3', 'format': 'Non spécifié'} Call the 'self.metadata_checker' function with the parameter [digitise_infos, dublincore_dict] """ # prevent button hammering self.launch_digitise_button.setEnabled(False) file_path = None if self.file_import_radio.isChecked(): file_dialog = QFileDialog(self) file_path = file_dialog.getOpenFileName( directory=FILES_PATHS["home_dir"]) file_path = file_path[0] print(file_path) dublincore_dict = dict() dublincore_dict["dc:format"] = {"aspect_ratio": "4:3"} for row in range(self.digitise_table.rowCount()): combobox_text = self.digitise_table.cellWidget(row, 0).currentText() widget_type = self.digitise_table.cellWidget( row, 1).metaObject().className() if widget_type == "QLineEdit": widget_text_value = self.digitise_table.cellWidget( row, 1).displayText() elif widget_type == "QTextEdit": widget_text_value = self.digitise_table.cellWidget( row, 1).toPlainText() elif widget_type == "QComboBox": widget_text_value = self.digitise_table.cellWidget( row, 1).currentText() if widget_text_value != "": if combobox_text == "durée": dublincore_dict["dc:format"]["duration"] = int( widget_text_value) * 60 # convert minutes to seconds elif combobox_text == "ratio": dublincore_dict["dc:format"][ "aspect_ratio"] = widget_text_value elif combobox_text == "format_video": dublincore_dict["dc:format"]["format"] = widget_text_value elif combobox_text == "dcterms:created": dublincore_dict[combobox_text] = int(widget_text_value) elif combobox_text == "dc:description": dublincore_dict[combobox_text] = widget_text_value else: try: dublincore_dict[combobox_text].append( widget_text_value) except KeyError: dublincore_dict[combobox_text] = [widget_text_value] dublincore_dict["dc:rights"] = "usage libre pour l'éducation" dublincore_dict["dc:type"] = "video" dublincore_dict["dcterms:modified"] = datetime.now().replace( microsecond=0).isoformat() # Handle the other infos capture_action = None digitise_infos = {} if self.decklink_radio_1.isChecked( ) and self.decklink_radio_1.isEnabled(): digitise_infos["source"] = "decklink_1" digitise_infos[ "lossless_import"] = self.lossless_import_checkbox.isChecked() capture_action = "decklink" elif self.decklink_radio_2.isChecked( ) and self.decklink_radio_2.isEnabled(): digitise_infos["source"] = "decklink_2" digitise_infos[ "lossless_import"] = self.lossless_import_checkbox.isChecked() capture_action = "decklink" elif self.file_import_radio.isChecked(): digitise_infos["source"] = "file" capture_action = "file" elif self.dvd_import_radio.isChecked(): digitise_infos["source"] = "DVD" capture_action = "DVD" digitise_infos["file_path"] = file_path to_be_send = [digitise_infos, dublincore_dict] print(to_be_send) self.metadata_checker(capture_action=capture_action, data=to_be_send) def tab_init(self): """ Is called when the CaptureWidget class init Its job is to put the widgets instantiated in the init function to their place and set some signals between functions and buttons """ grid = QGridLayout() self.setLayout(grid) ######### self.digitise_table.setRowCount(0) self.digitise_table.setColumnCount(3) self.digitise_table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.digitise_table.setColumnWidth(0, 170) self.digitise_table.setFont(self.table_font) self.digitise_table.setHorizontalHeaderLabels(["", "", ""]) ######### grid.addWidget(self.decklink_label, 0, 0) grid.addWidget(self.decklink_radio_1, 0, 1) grid.addWidget(self.file_import_radio, 0, 3) grid.addWidget(self.lossless_import_checkbox, 1, 0) grid.addWidget(self.decklink_radio_2, 1, 1) grid.addWidget(self.dvd_import_radio, 1, 3) grid.addWidget(self.digitise_table, 2, 0, 7, 4) grid.addWidget(self.new_table_row_button, 2, 5) grid.addWidget(self.launch_ffplay_button, 5, 5) grid.addWidget(self.launch_digitise_button, 8, 5) ######### self.dvd_import_radio.toggled.connect( self.lossless_import_checkbox.setDisabled) self.dvd_import_radio.toggled.connect( self.launch_ffplay_button.setDisabled) self.file_import_radio.toggled.connect( self.lossless_import_checkbox.setDisabled) self.file_import_radio.toggled.connect( self.launch_ffplay_button.setDisabled) ######### self.backend_is_alive_timer.start(15000) self.backend_is_alive_timer.timeout.connect( partial(self.launch_digitise_button.setDisabled, True)) self.receive_enable_decklink_radio_1.connect( self.decklink_radio_1.setEnabled) self.receive_enable_decklink_radio_2.connect( self.decklink_radio_2.setEnabled) ######### self.new_table_row_button.clicked.connect(self.add_table_row) self.launch_ffplay_button.clicked.connect(self.launch_ffplay) self.launch_digitise_button.clicked.connect(self.gather_metadata)
class ImageListWidget(QWidget): def __init__(self, parent=None): super(ImageListWidget, self).__init__(parent) self.resize(110, 768) self.setupUi() self.row_last = 0 def setupUi(self): self.icontable = QTableWidget() self.icontable.setColumnCount(2) self.icontable.setColumnWidth(0, 200) self.icontable.setColumnWidth(1, 300) self.icontable.horizontalHeader().setVisible(False) hlayout = QHBoxLayout() hlayout.addWidget(self.icontable) self.setLayout(hlayout) def clear(self): self.row_last = 0 self.icontable.clear() def get_item(self): combox = QComboBox() combox.addItems(['欧拉角', '四元数']) # hlayout = QHBoxLayout() # hlayout.addWidget(combox) return combox def addItem(self, file_name): exif = piexif.load(file_name) thumbnail = exif.pop('thumbnail') if thumbnail is not None: pix = QPixmap() pix.loadFromData(thumbnail, "JPG") else: pix = QPixmap() pix.load(file_name) pix_scaled = pix.scaled(200, 200, Qt.KeepAspectRatio, Qt.SmoothTransformation) label = QLabel("") label.setPixmap(pix_scaled) self.icontable.insertRow(self.row_last) self.icontable.setCellWidget(self.row_last, 0, label) # self.icontable.setItem(self.row_last, 1, QTableWidgetItem("123")) pos = PosItemWidget(QSize(300, pix_scaled.size().height())) self.icontable.setCellWidget(self.row_last, 1, pos) self.icontable.setRowHeight(self.row_last, pix_scaled.size().height()) self.row_last = self.row_last + 1 self.icontable.scrollToBottom() def get_pos(self): quats = np.zeros((self.icontable.rowCount(), 4)) trans = np.zeros((self.icontable.rowCount(), 3)) for row in range(self.icontable.rowCount()): trans[row, :] = np.array([ self.icontable.cellWidget(row, 1).spinbox_tx.value(), self.icontable.cellWidget(row, 1).spinbox_ty.value(), self.icontable.cellWidget(row, 1).spinbox_tz.value() ]) if self.icontable.cellWidget(row, 1).combox.currentText() == '欧拉角': x = self.icontable.cellWidget(row, 1).spinbox_x.value() y = self.icontable.cellWidget(row, 1).spinbox_y.value() z = self.icontable.cellWidget(row, 1).spinbox_z.value() rot_temp = Rotation.from_euler('ZYX', np.array([z, y, x]), degrees=True) quats[row, :] = rot_temp.as_quat() elif self.icontable.cellWidget(row, 1).combox.currentText() == '四元数': x = self.icontable.cellWidget(row, 1).spinbox_x.value() y = self.icontable.cellWidget(row, 1).spinbox_y.value() z = self.icontable.cellWidget(row, 1).spinbox_z.value() w = self.icontable.cellWidget(row, 1).spinbox_w.value() q = np.array([x, y, z, w]) if np.linalg.norm(q) == 0: w = 1 q = np.array([0, 0, 0, 1]) self.icontable.cellWidget(row, 1).spinbox_x.setValue( x / np.linalg.norm(q)) self.icontable.cellWidget(row, 1).spinbox_y.setValue( y / np.linalg.norm(q)) self.icontable.cellWidget(row, 1).spinbox_z.setValue( z / np.linalg.norm(q)) self.icontable.cellWidget(row, 1).spinbox_w.setValue( w / np.linalg.norm(q)) rot_temp = Rotation.from_quat(np.array([x, y, z, w])) quats[row, :] = rot_temp.as_quat() rot = Rotation.from_quat(quats) return rot, trans
class Menu(QMainWindow): def __init__(self, parent): super().__init__(parent) self.db = DB() self.initUI() def initUI(self): in_class = "menu" self.sidebar = sidebar.Sidebar(self) self.sidebar.window.connect(self.getvalue) self.addDockWidget(Qt.LeftDockWidgetArea, self.sidebar) header = AppName(in_class) footer = Footer() add_and_search = AddSearchFrame(in_class) add_and_search.add_button.clicked.connect(lambda: self.add_menu(in_class)) add_and_search.search_button.clicked.connect( lambda: self.search_menu(add_and_search.search_box)) self.table = QTableWidget() self.table.setColumnCount(5) # self.table.setStyleSheet("border: none") # self.table.setStyleSheet( # "background-color: rgb(255, 255, 255);\n" # 'font: 10pt "MS Shell Dlg 2";\n' # "color: rgb(30, 45, 66);" # ) # self.table.setHorizontalHeaderItem(0, QTableWidgetItem("ID")) self.table.setHorizontalHeaderItem(0, QTableWidgetItem("Food")) self.table.setHorizontalHeaderItem(1, QTableWidgetItem("Category")) self.table.setHorizontalHeaderItem(2, QTableWidgetItem("Price")) # self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Bonus")) # self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Joining Date")) # self.table.setHorizontalHeaderItem(6, QTableWidgetItem("Total Salary")) self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Edit")) self.table.setHorizontalHeaderItem(4, QTableWidgetItem("Delete")) data = self.load_menu_data() print(data) for x in data: print(x) self.populate_table(data) self.table.resizeColumnsToContents() layout = QVBoxLayout() layout.addWidget(header) layout.addWidget(add_and_search) layout.addWidget(self.table) # layout.addStretch() layout.addWidget(footer) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) centralWidget = QWidget() centralWidget.setLayout(layout) self.setCentralWidget(centralWidget) self.setContentsMargins(0, 0, 0, 0) # self.resize(800, 600) self.setWindowTitle("Employee") self.resize(1160, 605) self.show() self.center() def center(self): '''centers the window on the screen''' screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def getvalue(self, value): print(value) print(type(value)) if value == 1: self.hide() view = sidebar.Dashboard(self) elif value == 2: self.hide() view = sidebar.Employee(self) elif value == 3: self.hide() view = sidebar.Table(self) elif value == 4: self.hide() view = sidebar.Reservations(self) elif value == 5: pass elif value == 6: self.hide() view = sidebar.Settings(self) elif value == 7: self.hide() view = sidebar.Orders(self) elif value == 8: self.hide() view = sidebar.Menu(self) elif value == 9: self.hide() view = sidebar.Bill(self) def load_menu_data(self): query = "SELECT food_name, price, category_name FROM menu " \ "join category on menu.category_id = category.id order by category_name" result = self.db.fetch(query) return result ''' This function is called after an employee has been added and returns only the last row. ''' def add_update_menu_data(self): query = "SELECT food_name, price, category_name FROM menu " \ "join category on menu.category_id = category.id " \ "order by id desc limit 1;" result = self.db.fetch(query) return result def edit_menu(self): emp_row = self.table.indexAt(self.sender().pos()) id = self.table.cellWidget(emp_row.row(), emp_row.column()).objectName() print(emp_row.row()) print(id) print(type(id)) ''' Get the data from the database for that user. ''' data = self.get_data(id) print("Data") print(data) # print(type(data[4])) view = AddMenuDetails(self, "update", data[0]) view.nametextbox.setText(data[0]) view.pricetextbox.setText(str(data[1])) category = self.get_category(data[2]) view.category_list.setCurrentText(category) view.closing.connect(self.editupdate_emp) def get_category(self, category): query = "SELECT category_name FROM category " \ "where id=%s" values = (category,) result = self.db.fetch(query, values) for (category) in result: category = category[0] return category def editupdate_emp(self, check): print("I am here") print(check) self.table.clearContents() self.table.setRowCount(0) data = self.load_menu_data() self.populate_table(data) self.table.resizeColumnsToContents() # self.table.resizeColumnsToContents() def get_data(self, id): query = "SELECT food_name, price, category_id FROM menu " \ "where food_name=%s" values = (id,) result = self.db.fetch(query, values) for (food_name, price, category) in result: food_name = food_name price = price category = category return [food_name, price, category] def delete_menu(self): emp_row = self.table.indexAt(self.sender().pos()) # print(emp_row.row()) # print(emp_row.column()) # print(self.table.cellWidget(emp_row.row(), emp_row.column()).objectName()) id = self.table.cellWidget(emp_row.row(), emp_row.column()).objectName() # print(id) # print(emp_row.child(emp_row.row(), emp_row.column())) query = "DELETE FROM menu WHERE food_name=%s" values = (id,) result = self.db.execute(query, values) self.table.clearContents() self.table.setRowCount(0) data = self.load_menu_data() self.populate_table(data) def add_menu(self, where): if where == "menu": print("Employee Button Clicked from Menu") view = AddMenuDetails(self, "add") view.closing.connect(self.update_menu) elif where == "stocks": print("Stock Button Clicked") def search_menu(self, search_obj): search = search_obj.text() search_obj.setText("") print("Search") if search != "": query = "SELECT * FROM menu WHERE food_name like %s" values = ("%" + search + "%",) else: query = "SELECT * FROM menu" values = () self.table.clearContents() self.table.setRowCount(0) data = self.db.fetch(query, values) self.populate_table(data) ''' Repopulates the employee table with the updated data. ''' def update_menu(self, check): print("I am here") print(check) self.table.clearContents() self.table.setRowCount(0) data = self.load_menu_data() self.populate_table(data) ''' This function populates the employee table with data. ''' def populate_table(self, data): for (food_name, price, category_name) in data: self.table.insertRow(self.table.rowCount()) self.table.setItem(self.table.rowCount() - 1, 0, QTableWidgetItem(str(food_name))) self.table.setItem(self.table.rowCount() - 1, 1, QTableWidgetItem(str(category_name))) self.table.setItem(self.table.rowCount() - 1, 2, QTableWidgetItem(str(price))) # self.table.setItem(self.table.rowCount() - 1, 3, QTableWidgetItem(str(bonus))) # self.table.setItem(self.table.rowCount() - 1, 3, QTableWidgetItem(str(joining_date.strftime("%d-%m-%Y")))) edit = QPushButton(self.table) edit.setObjectName(str(food_name)) edit.setStyleSheet("background-color: rgb(50,205,50);") edit.setText("Edit") edit.adjustSize() edit.clicked.connect(self.edit_menu) self.table.setCellWidget(self.table.rowCount() - 1, 3, edit) delete = QPushButton(self.table) delete.setObjectName(str(food_name)) delete.setStyleSheet("background-color: #d63447;") delete.setText("Delete") delete.adjustSize() delete.clicked.connect(self.delete_menu) # delete.mousePressEvent = functools.partial(self.delete_menu, source_object=delete) self.table.setCellWidget(self.table.rowCount() - 1, 4, delete)
def _copy_time(self, timeTable: QtWidgets.QTableWidget): row = timeTable.currentRow() time = timeTable.cellWidget(row, 1).time() timeTable.cellWidget(row, 2).setTime(time) timeTable.item(row, 3).setText("") # 停时变成0 self.showStatus.emit(f"{timeTable.item(row,0).text()}站到达时间复制成功")
class bridgePanel(QMainWindow, QObject): start = pyqtSignal() stop = pyqtSignal() def __init__(self, app): super().__init__() self.__v2rayshellConfigFile = { "preferences": { "v2ray-core": "", "v2ray-coreFilePath": "", "connection": { "connect": "switch", "interval": 45, "timeout": 3, "enable": True, "trytimes": 3 } }, "configFiles": [{ "enable": True, "hostName": "", "configFileName": "" }] } self.bridgetreasureChest = bridgetreasureChest.bridgetreasureChest() self.app = app self.translate = QCoreApplication.translate self.__v2rayshellVersion = "20180204" self.__windowTitile = "V2Ray-shell" + " " + self.__v2rayshellVersion self.runv2raycore = False self.iconStart = QIcon() self.iconStop = QIcon() self.__iconSize = QSize(32, 32) self.iconStart.addPixmap(QPixmap(filePath + "/icons/start.png"), QIcon.Normal, QIcon.On) self.iconStop.addPixmap(QPixmap(filePath + "/icons/stop.png"), QIcon.Disabled, QIcon.On) self.currentRowRightClicked = False self.v2rayshellTrayIcon = QSystemTrayIcon() self.v2rayshellTrayIcon.setIcon(self.iconStart) self.v2rayshellTrayIcon.show() self.radioButtonGroup = QButtonGroup() self.setV2RayshellLanguage() self.trytimes = self.bridgetreasureChest.getConnectiontrytimes() self.interval = self.bridgetreasureChest.getConnectioninterval() self.proxyTryConnect = proxyTryconnect() if v2rayshellDebug: self.proxyTryConnect.setresetTime(6, 3) else: self.proxyTryConnect.setresetTime(self.interval, self.trytimes) self.labelBridge = (self.translate("bridgePanel", "Start/Stop"), self.translate("bridgePanel", "Host Name"), self.translate("bridgePanel", "Config Name"), self.translate("bridgePanel", "Proxy"), self.translate("bridgePanel", "Time Lag")) self.createBridgePanel() def createBridgePanel(self): self.setWindowTitle(self.__windowTitile) self.setWindowIcon(self.iconStart) menubar = self.menuBar() self.statusBar() self.actionNewV2rayConfigFile = QAction( self.translate("bridgePanel", "Add V2Ray-core Config File"), self) self.actionNewV2rayConfigFile.setShortcut(QKeySequence.New) self.actionNewV2rayConfigFile.setStatusTip( self.translate("bridgePanel", "Add V2Ray-core Config File")) self.actionSaveV2rayshellConfigFile = QAction( self.translate("bridgePanel", "Save V2Ray-shell Config File"), self) self.actionSaveV2rayshellConfigFile.setShortcut(QKeySequence.Save) self.actionSaveV2rayshellConfigFile.setStatusTip( self.translate("bridgePanel", "Save V2Ray-shell Config File")) self.actionReloadV2rayshellConfigFile = QAction( self.translate("bridgePanel", "Open V2Ray-shell Config File"), self) self.actionReloadV2rayshellConfigFile.setShortcut(QKeySequence.Open) self.actionReloadV2rayshellConfigFile.setStatusTip( self.translate("bridgePanel", "Open V2Ray-shell Config File")) self.actionQuitV2rayshellPanel = QAction( self.translate("bridgePanel", "Quit"), self) if sys.platform.startswith('win'): self.actionQuitV2rayshellPanel.setShortcut("Ctrl+Q") else: self.actionQuitV2rayshellPanel.setShortcut(QKeySequence.Quit) self.actionQuitV2rayshellPanel.setStatusTip( self.translate("bridgePanel", "Quit V2Ray-shell")) fileMenu = menubar.addMenu(self.translate("bridgePanel", "&File")) fileMenu.addAction(self.actionNewV2rayConfigFile) fileMenu.addSeparator() fileMenu.addAction(self.actionReloadV2rayshellConfigFile) fileMenu.addAction(self.actionSaveV2rayshellConfigFile) fileMenu.addSeparator() fileMenu.addAction(self.actionQuitV2rayshellPanel) self.texteditBridge = QTextEdit(self) self.texteditBridge.setReadOnly(True) self.tableWidgetBridge = QTableWidget() self.tableWidgetBridge.setRowCount(0) self.tableWidgetBridge.setColumnCount(5) self.tableWidgetBridge.setHorizontalHeaderLabels(self.labelBridge) self.tableWidgetBridge.setSelectionMode( QAbstractItemView.SingleSelection) self.tableWidgetBridge.setSelectionBehavior( QAbstractItemView.SelectRows) self.tableWidgetBridge.setEditTriggers( QAbstractItemView.NoEditTriggers) #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.tableWidgetBridge.setContextMenuPolicy(Qt.CustomContextMenu) self.popMenu = popMenu = QMenu(self.tableWidgetBridge) self.actionpopMenuAddV2rayConfigFile = QAction( self.translate("bridgePanel", "Add V2Ray Config File"), self) self.actionpopMenuAddV2rayConfigFile.setShortcut("Ctrl+n") self.actionpopMenuEditV2rayConfigFile = QAction( self.translate("bridgePanel", "Edit V2Ray Config File"), self) self.actionpopMenuProxyCheckTimeLag = QAction( self.translate("bridgePanel", "Proxy Time Lag Check..."), self) self.actionpopMenuDeleteRow = QAction( self.translate("bridgePanel", "Delete"), self) popMenu.addAction(self.actionpopMenuAddV2rayConfigFile) popMenu.addAction(self.actionpopMenuEditV2rayConfigFile) popMenu.addAction(self.actionpopMenuProxyCheckTimeLag) popMenu.addAction(self.actionpopMenuDeleteRow) self.actionopenV2rayshellPreferencesPanel = QAction( self.translate("bridgePanel", "preferences"), self) self.actionopenV2rayshellPreferencesPanel.setStatusTip( self.translate("bridgePanel", "Setting V2Ray-shell")) optionMenu = menubar.addMenu(self.translate("bridgePanel", "&options")) optionMenu.addAction(self.actionpopMenuProxyCheckTimeLag) optionMenu.addAction(self.actionopenV2rayshellPreferencesPanel) helpMenu = menubar.addMenu(self.translate("bridgePanel", "&help")) self.actioncheckv2raycoreupdate = QAction( self.translate("bridgePanel", "check V2Ray-core update"), self) self.actionv2rayshellBugreport = QAction( self.translate("bridgePanel", "Bug Report"), self) self.actionaboutv2rayshell = QAction( self.translate("bridgePanel", "About"), self) helpMenu.addAction(self.actioncheckv2raycoreupdate) helpMenu.addAction(self.actionv2rayshellBugreport) helpMenu.addAction(self.actionaboutv2rayshell) toolBar = QToolBar() self.actionV2rayStart = QAction(self.translate("bridgePanel", "Start")) self.actionV2rayStart.setIcon(self.style().standardIcon( getattr(QStyle, "SP_MediaPlay"))) self.actionV2rayStop = QAction(self.translate("bridgePanel", "Stop")) self.actionV2rayStop.setIcon(self.style().standardIcon( getattr(QStyle, "SP_MediaStop"))) toolBar.addAction(self.actionV2rayStart) toolBar.addAction(self.actionV2rayStop) self.addToolBar(toolBar) self.trayIconMenu = QMenu() self.v2rayshellTrayIcon.setContextMenu(self.trayIconMenu) self.trayIconMenushowhidePanel = QAction( self.translate("bridgePanel", "Show/Hide")) self.trayIconMenuclosePanel = QAction( self.translate("bridgePanel", "Quit")) self.trayIconMenu.addAction(self.trayIconMenushowhidePanel) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.trayIconMenuclosePanel) self.splitterBridge = QSplitter(Qt.Vertical) self.splitterBridge.addWidget(self.tableWidgetBridge) self.splitterBridge.addWidget(self.texteditBridge) self.setCentralWidget(self.splitterBridge) self.createBridgePanelSignals() self.onloadV2rayshellConfigFile(init=True) self.onv2raycoreStart() self.autocheckv2raycoreUpdate() def createBridgePanelSignals(self): self.actionNewV2rayConfigFile.triggered.connect( self.tableWidgetBridgeAddNewV2rayConfigFile) self.actionReloadV2rayshellConfigFile.triggered.connect( self.onloadV2rayshellConfigFile) self.actionSaveV2rayshellConfigFile.triggered.connect( self.onsaveV2rayshellConfigFile) self.actionopenV2rayshellPreferencesPanel.triggered.connect( self.createBridgepreferencesPanel) self.actionpopMenuAddV2rayConfigFile.triggered.connect( self.tableWidgetBridgeAddNewV2rayConfigFile) self.actionpopMenuEditV2rayConfigFile.triggered.connect( self.oncreatenauticalChartPanel) self.actionpopMenuDeleteRow.triggered.connect( self.tableWidgetBridgeDelete) self.actionpopMenuProxyCheckTimeLag.triggered.connect( self.onproxyserverTimeLagTest) self.actioncheckv2raycoreupdate.triggered.connect( self.onopenv2rayupdatePanel) self.actionv2rayshellBugreport.triggered.connect(self.bugReportPanel) self.actionQuitV2rayshellPanel.triggered.connect(self.close) self.actionV2rayStart.triggered.connect(self.onv2raycoreStart) self.actionV2rayStop.triggered.connect(self.onv2raycoreStop) self.actionaboutv2rayshell.triggered.connect(self.about) self.radioButtonGroup.buttonClicked.connect(self.onradioButtonClicked) self.tableWidgetBridge.cellDoubleClicked.connect( self.ontableWidgetBridgecellDoubleClicked) self.tableWidgetBridge.customContextMenuRequested.connect( self.ontableWidgetBridgeRightClicked) self.v2rayshellTrayIcon.activated.connect(self.restorebridgePanel) self.trayIconMenushowhidePanel.triggered.connect( self.onsystemTrayIconMenushowhidebridgePanel) self.trayIconMenuclosePanel.triggered.connect(self.close) self.proxyTryConnect.reconnectproxy.connect(self.swapNextConfigFile) self.start.connect(self.onupdateinstallFinishedstartNewV2raycore) self.stop.connect(self.onv2raycoreStop) def setV2RayshellLanguage(self): self.trans = QTranslator() language = self.bridgetreasureChest.getLanguage() allLanguages = self.bridgetreasureChest.getAllLanguage() if language and allLanguages: if language in allLanguages: self.trans.load(allLanguages[language]) self.app.installTranslator(self.trans) def autocheckv2raycoreUpdate(self): self.v2rayshellautoUpdate = updatePanel.updateV2ray() self.bridgeSingal = (self.start, self.stop) self.trycheckUpdate = QTimer() self.trycheckUpdate.timeout.connect( lambda: self.v2rayshellautoUpdate.enableUpdateSchedule( self.bridgetreasureChest, self.bridgeSingal)) self.trycheckUpdate.start(1000 * 60 * 60 * 4) ### Check every four hours self.trycheckUpdate.singleShot( ### Check when the script is started 1000 * 15, ### fifty seconds lambda: self.v2rayshellautoUpdate.enableUpdateSchedule( self.bridgetreasureChest, self.bridgeSingal)) def event(self, event): if (event.type() == QEvent.WindowStateChange and self.isMinimized()): self.setWindowFlags(self.windowFlags() & ~Qt.Tool) self.v2rayshellTrayIcon.show() return True else: return super(bridgePanel, self).event(event) def onsystemTrayIconMenushowhidebridgePanel(self): if self.isHidden(): self.showNormal() elif self.isVisible(): self.hide() def restorebridgePanel(self, reason): if reason == QSystemTrayIcon.Trigger: if self.isVisible(): self.hide() elif self.isHidden(): self.showNormal() def close(self): super(bridgePanel, self).close() self.v2rayshellTrayIcon.hide() self.onv2raycoreStop() def closeEvent(self, event): self.close() event.accept() sys.exit(self.app.exec_()) def onv2raycoreStop(self): if (self.runv2raycore): self.runv2raycore.stop.emit() try: ### force stop checking proxy time lag del self.autoCheckTimer except Exception: pass def onupdateinstallFinishedstartNewV2raycore(self): self.onloadV2rayshellConfigFile(init=True) self.onv2raycoreStart() def onv2raycoreStart(self): currentActiveRow = False rowCount = self.tableWidgetBridge.rowCount() for i in range(rowCount): currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0) if currentActiveRow.isChecked(): self.texteditBridge.clear() option = self.tableWidgetBridge.item(i, 2) if option: option = '-config="{}" -format=json'.format(option.text()) else: option = "" filePath = self.bridgetreasureChest.getV2raycoreFilePath() if (filePath == False or filePath == ""): filePath = "v2ray" self.runv2raycore = runV2raycore.runV2raycore( outputTextEdit=self.texteditBridge, v2rayPath=filePath, v2rayOption=option, bridgetreasureChest=self.bridgetreasureChest) self.runv2raycore.start.emit() self.autocheckProxy(i) break else: del currentActiveRow def autocheckProxy(self, row): ### TODO """ Frequent access to the server may cause suspicion of DDOS attacks, which may put the VPS server at risk. """ enableAutoCheck = self.bridgetreasureChest.getConnectionEnable() if (enableAutoCheck): self.proxyStatus = proxyTest.proxyStatus() self.autoCheckTimer = QTimer() invervalTime = self.bridgetreasureChest.getConnectioninterval() timeout = self.bridgetreasureChest.getConnectiontimeout() proxyAddress = self.getProxyAddressFromTableWidget(row) if proxyAddress: self.autoCheckTimer.timeout.connect( lambda: self.startCheckProxy(timeout=timeout, proxyAddress=proxyAddress, row=row, proxyStatus=self.proxyStatus)) self.bridgetreasureChest.setProxy(proxyAddress) if v2rayshellDebug: self.autoCheckTimer.start(6000) else: self.autoCheckTimer.start(1000 * invervalTime) self.autoCheckTimer.singleShot( 100, lambda: self.startCheckProxy(timeout=timeout, proxyAddress=proxyAddress, row=row, proxyStatus=self.proxyStatus)) def setTableWidgetTimelag(self, row, proxyStatus): newlabelTimelag = self.setlabelTimeLagColor(proxyStatus) oldlabelTimelag = self.tableWidgetBridge.cellWidget(row, 4) del oldlabelTimelag self.tableWidgetBridge.setCellWidget(row, 4, newlabelTimelag) self.tableWidgetBridge.resizeColumnsToContents() def startCheckProxy(self, timeout, proxyAddress, row, proxyStatus): if (proxyAddress): proxyStatus.clear() proxyStatus.signal.connect( lambda: self.setTableWidgetTimelag(row, proxyStatus)) self.proxy = proxyTest.proxyTest(proxyprotocol=proxyAddress[0], proxyhostname=proxyAddress[1], proxyhostport=int( proxyAddress[2]), getproxyStatus=proxyStatus, timeout=int(timeout)) def setlabelTimeLagColor(self, proxyStatus=False): labelTimeLag = QLabel() if (proxyStatus and proxyStatus.getProxyError() == False): labelFont = QFont() labelFont.setPointSize(12) labelFont.setBold(True) labelTimeLag.setFont(labelFont) forestGreen = "QLabel {color: rgb(34, 139, 34)}" darkOrange = "QLabel {color: rgb(255, 140, 0)}" red = "QLabel {color: rgb(194,24,7)}" if (proxyStatus.getElapsedTime() < 260): labelTimeLag.setStyleSheet(forestGreen) elif (proxyStatus.getElapsedTime() > 420): labelTimeLag.setStyleSheet(red) else: labelTimeLag.setStyleSheet(darkOrange) labelTimeLag.setText("{} ms".format( str(proxyStatus.getElapsedTime()))) return labelTimeLag elif (proxyStatus and proxyStatus.getProxyError()): labelTimeLag.setText("{}:{}".format( proxyStatus.getProxyErrorString(), proxyStatus.getProxyErrorCode())) self.proxyTryConnect.trytimesDecrease() return labelTimeLag def swapNextConfigFile(self): self.onv2raycoreStop() try: self.trytimes = self.bridgetreasureChest.getConnectiontrytimes() self.interval = self.bridgetreasureChest.getConnectioninterval() self.proxyTryConnect.stopperiodicCheckProxyStatus() if v2rayshellDebug: self.proxyTryConnect.setresetTime(6, 3) else: self.proxyTryConnect.setresetTime(self.interval, self.trytimes) except Exception: self.proxyTryConnect.setresetTime(60, 3) if (self.bridgetreasureChest.connectionisSwitch()): ### swap next row's configFile buttons = self.radioButtonGroup.buttons() buttonsNumber = len(buttons) activeRow = False for i in range(buttonsNumber): if buttons[i].isChecked(): buttons[i].setChecked(False) if i == buttonsNumber - 1: buttons[0].setChecked(True) activeRow = 0 break else: buttons[i + 1].setChecked(True) activeRow = i + 1 break ### change the row icons for i in range(buttonsNumber): widget = self.tableWidgetBridge.cellWidget(i, 0) if (widget): widget.setIcon(self.iconStop) widget.setIconSize(self.__iconSize) if (widget.isChecked()): pass widget = self.tableWidgetBridge.cellWidget(activeRow, 0) if widget: widget.setIcon(self.iconStart) widget.setIconSize(self.__iconSize) self.onv2raycoreStart() def onopenv2rayupdatePanel(self): currentActiveRow = False rowCount = self.tableWidgetBridge.rowCount() currentRow = False for i in range(rowCount): currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0) if currentActiveRow.isChecked(): currentRow = i break if (currentActiveRow and currentActiveRow.isChecked()): proxy = self.tableWidgetBridge.item(currentRow, 3) proxy = proxy.text().split(":") protocol = QNetworkProxy.Socks5Proxy if (proxy[0] == "socks"): protocol = QNetworkProxy.Socks5Proxy elif (proxy[0] == "http"): protocol = QNetworkProxy.HttpProxy hostName = proxy[1] hostPort = int(proxy[2]) v2rayAPI = updatePanel.v2rayAPI() self.createupdatePanel = updatePanel.v2rayUpdatePanel( v2rayapi=v2rayAPI, protocol=protocol, proxyhostName=hostName, port=hostPort, bridgetreasureChest=self.bridgetreasureChest) self.createupdatePanel.createPanel() self.createupdatePanel.setAttribute(Qt.WA_DeleteOnClose) self.createupdatePanel.setWindowIcon(self.iconStart) self.createupdatePanel.setWindowTitle( self.translate("bridgePanel", "Check V2Ray-core update")) self.createupdatePanel.resize(QSize(1024, 320)) self.createupdatePanel.move( QApplication.desktop().screen().rect().center() - self.createupdatePanel.rect().center()) self.createupdatePanel.show() self.createupdatePanel.exec_() else: self.noPoxyServerRunning() def ontableWidgetBridgeRightClicked(self, pos): index = self.tableWidgetBridge.indexAt(pos) clickedRow.rightClickedRow = index.row() clickedRow.mousePos = QCursor().pos() self.popMenu.move(QCursor().pos()) self.popMenu.show() def ontableWidgetBridgecellDoubleClicked(self, row, column): if (column == 1): hostName, ok = QInputDialog.getText( self, self.translate("bridgePanel", 'Host Name'), self.translate("bridgePanel", 'Enter Host Name:')) if (ok): self.tableWidgetBridge.setItem(row, column, QTableWidgetItem(str(hostName))) self.tableWidgetBridge.resizeColumnsToContents() elif (column == 2): fileNames = self.onopenV2rayConfigJSONFile() if (fileNames): for fileName in fileNames: self.tableWidgetBridge.setItem( row, column, QTableWidgetItem(str(fileName))) self.tableWidgetBridge.resizeColumnsToContents() elif (column == 3): self.onproxyserverTimeLagTest() elif (column == 4): self.onproxyserverTimeLagTest() def getProxyAddressFromTableWidget(self, row): proxy = self.tableWidgetBridge.item(row, 3) try: proxy = proxy.text().split(":") except Exception: return False if (proxy[0] == "socks"): proxy[0] = QNetworkProxy.Socks5Proxy elif (proxy[0] == "http"): proxy[0] = QNetworkProxy.HttpProxy if len(proxy) < 3: return False else: return proxy def onproxyserverTimeLagTest(self): proxyStatus = proxyTest.proxyStatus() """ right clicked mouse button pop a menu check proxy """ currentActiveRow = False rowCount = self.tableWidgetBridge.rowCount() currentRow = False for i in range(rowCount): currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0) if currentActiveRow.isChecked(): currentRow = i break if (currentActiveRow and currentActiveRow.isChecked()): proxy = self.getProxyAddressFromTableWidget(currentRow) protocol = proxy[0] hostName = proxy[1] hostPort = int(proxy[2]) proxy = proxyTest.proxyTestPanel(proxyhostname=hostName, proxyhostport=hostPort, proxyprotocol=protocol, getproxyStatus=proxyStatus) proxy.createproxyTestPanel() proxy.setAttribute(Qt.WA_DeleteOnClose) proxy.setWindowTitle( self.translate("bridgePanel", "Proxy Time Lag Check")) proxy.setWindowIcon(self.iconStart) proxy.resize(QSize(600, 480)) proxy.move(QApplication.desktop().screen().rect().center() - proxy.rect().center()) proxy.show() proxy.exec_() else: self.noPoxyServerRunning() def noPoxyServerRunning(self): warningPanel = QDialog() warningPanel.setAttribute(Qt.WA_DeleteOnClose) warningPanel.setWindowTitle(self.translate("bridgePanel", "Warnnig...")) warningPanel.setWindowIcon(self.iconStop) labelMsg = QLabel( self.translate( "bridgePanel", "There no any server is running, \n[File]->[Add V2Ray-core Config File] (Ctrl+n) add a config.json." )) vbox = QVBoxLayout() vbox.addWidget(labelMsg) warningPanel.setLayout(vbox) warningPanel.move(QApplication.desktop().screen().rect().center() - warningPanel.rect().center()) warningPanel.open() warningPanel.exec_() def getProxyAddressFromJSONFile(self, filePath): from bridgehouse.editMap.port import treasureChest, openV2rayJSONFile tempTreasureChest = treasureChest.treasureChest() openV2rayJSONFile.openV2rayJSONFile( filePath, tempTreasureChest, disableLog=True).initboundJSONData() inbound = tempTreasureChest.getInbound() if (inbound): protocol = inbound["protocol"] ipAddress = inbound["listen"] port = inbound["port"] if (protocol == "socks" or protocol == "http"): return "{}:{}:{}".format(protocol, ipAddress, port) else: return False else: return False def onradioButtonClicked(self, e): rowCount = self.tableWidgetBridge.rowCount() #radioButtonClickedRow = 0 for i in range(rowCount): widget = self.tableWidgetBridge.cellWidget(i, 0) if (widget): widget.setIcon(self.iconStop) widget.setIconSize(self.__iconSize) if (widget.isChecked()): #radioButtonClickedRow = i pass e.setIcon(self.iconStart) e.setIconSize(self.__iconSize) def onloadV2rayshellConfigFile(self, init=False): """ when the script first start, and auto load v2ray-shell config file. """ if init: self.settingv2rayshelltableWidget() else: def openV2rayshellConfigFile(): options = QFileDialog.Options() filePath, _ = QFileDialog.getOpenFileName( self, self.translate("bridgePanel", "Open V2Ray-sehll Config File"), "", "V2Ray-shell config file (*.v2rayshell)", options=options) if (filePath): self.bridgetreasureChest.clear() self.tableWidgetBridge.setRowCount(0) self.bridgetreasureChest.inibridgeJSONData( v2rayshellConfigFileName=filePath) self.settingv2rayshelltableWidget() openV2rayshellConfigFile() def onopenV2rayConfigJSONFile(self): """ open a new v2ray config file to tabelWidget """ options = QFileDialog.Options() filePaths, _ = QFileDialog.getOpenFileNames( self, self.translate("bridgePanel", "Open V2Ray-core Config File"), "", """ V2Ray config file (*.json);; All File (*);; """, options=options) if (filePaths): return filePaths else: return False def createBridgepreferencesPanel(self): self.createpreferencesPanel = bridgePreference.bridgepreferencesPanel( self.bridgetreasureChest) self.createpreferencesPanel.setAttribute(Qt.WA_DeleteOnClose) self.createpreferencesPanel.createpreferencesPanel() self.createpreferencesPanel.setWindowIcon(self.iconStart) self.createpreferencesPanel.move( QApplication.desktop().screen().rect().center() - self.createpreferencesPanel.rect().center()) self.createpreferencesPanel.open() self.createpreferencesPanel.exec_() def settingv2rayshelltableWidget(self): v2rayConfigFiles = self.bridgetreasureChest.getV2raycoreconfigFiles() if v2rayConfigFiles == False: return v2rayConfigFilesNumber = len(v2rayConfigFiles) if (v2rayConfigFilesNumber > 0): self.tableWidgetBridge.setRowCount(0) for i in range(v2rayConfigFilesNumber): try: enable = bool(v2rayConfigFiles[i]["enable"]) hostName = str(v2rayConfigFiles[i]["hostName"]) configFileName = str(v2rayConfigFiles[i]["configFileName"]) except Exception: pass radioButtonStopStart = QRadioButton(self) radioButtonStopStart.setIcon( self.iconStop if not enable else self.iconStart) radioButtonStopStart.setChecked(True if enable else False) radioButtonStopStart.setIconSize(self.__iconSize) self.radioButtonGroup.addButton(radioButtonStopStart) self.tableWidgetBridge.setRowCount(i + 1) self.tableWidgetBridge.setCellWidget(i, 0, radioButtonStopStart) self.tableWidgetBridge.setItem(i, 1, QTableWidgetItem(hostName)) self.tableWidgetBridge.setItem( i, 2, QTableWidgetItem(configFileName)) self.tableWidgetBridge.setItem( i, 3, QTableWidgetItem( self.getProxyAddressFromJSONFile(configFileName))) self.tableWidgetBridge.resizeColumnsToContents() #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) def onsaveV2rayshellConfigFile(self): self.bridgetreasureChest.clearconfigFiles() rowCount = self.tableWidgetBridge.rowCount() for i in range(rowCount): enable = self.tableWidgetBridge.cellWidget(i, 0) if enable and enable.isChecked(): enable = True else: enable = False hostName = self.tableWidgetBridge.item(i, 1) if hostName: hostName = hostName.text() else: hostName = "" config = self.tableWidgetBridge.item(i, 2) if config: config = config.text() else: config = "" self.bridgetreasureChest.setV2raycoreconfigFiles( enable, hostName, configFileName=config) self.bridgetreasureChest.save.emit() def oncreatenauticalChartPanel(self): v2rayConfigFileName = self.tableWidgetBridge.item( clickedRow.rightClickedRow, 2) if (v2rayConfigFileName): nc = nauticalChartPanel.nauticalChartPanel( v2rayConfigFileName.text()) nc.setAttribute(Qt.WA_DeleteOnClose) nc.createPanel() nc.setWindowTitle( self.translate("bridgePanel", "V2Ray config file edit")) nc.setWindowIcon(self.iconStart) nc.setGeometry(0, 0, 1024, 768) ### move widget to center nc.move(QApplication.desktop().screen().rect().center() - nc.rect().center()) nc.show() nc.exec_() def tableWidgetBridgeAddNewV2rayConfigFile(self): configFileNames = self.onopenV2rayConfigJSONFile() if (configFileNames): for configFileName in configFileNames: rowCount = self.tableWidgetBridge.rowCount() radioButtonStopStart = QRadioButton(self) radioButtonStopStart.setIcon(self.iconStop) radioButtonStopStart.setIconSize(self.__iconSize) self.radioButtonGroup.addButton(radioButtonStopStart) self.tableWidgetBridge.setRowCount(rowCount + 1) self.tableWidgetBridge.setCellWidget(rowCount, 0, radioButtonStopStart) self.tableWidgetBridge.setItem(rowCount, 1, QTableWidgetItem("")) self.tableWidgetBridge.setItem( rowCount, 2, QTableWidgetItem(configFileName)) self.tableWidgetBridge.setItem( rowCount, 3, QTableWidgetItem( self.getProxyAddressFromJSONFile(configFileName))) self.tableWidgetBridge.resizeColumnsToContents() else: pass def tableWidgetBridgeDelete(self): self.tableWidgetBridge.removeRow(clickedRow.rightClickedRow) def validateV2rayJSONFile(self, JSONData): """ simply validate a V2Ray json file. """ try: JSONData["inbound"] JSONData["outbound"] except KeyError: return False else: return True def about(self): NineteenEightySeven = QLabel( self.translate( "bridgePanel", """Across the Great Wall, we can reach every corner in the world.""" )) ### Crossing the Great Wall to Join the World Timeless = QLabel( self.translate( "bridgePanel", """You weren't thinking about that when you were creating it.\nBecause if you did? You never would have gone through with it.""" )) DwayneRichardHipp = QLabel( self.translate( "bridgePanel", """May you do good and not evil.\nMay you find forgiveness for yourself and forgive others.\nMay you share freely, never taking more than you give.""" )) vbox = QVBoxLayout() vbox.addWidget(NineteenEightySeven) vbox.addWidget(Timeless) vbox.addWidget(DwayneRichardHipp) dialogAbout = QDialog() dialogAbout.setAttribute(Qt.WA_DeleteOnClose) dialogAbout.setWindowTitle( self.translate("bridgePanel", "About V2Ray-shell")) dialogAbout.setWindowIcon(self.iconStart) dialogAbout.move(QApplication.desktop().screen().rect().center() - dialogAbout.rect().center()) dialogAbout.setLayout(vbox) dialogAbout.open() dialogAbout.exec_() def bugReportPanel(self): self.bugReport = bugReport.bugReport() self.bugReport.setAttribute(Qt.WA_DeleteOnClose) self.bugReport.setWindowTitle( self.translate("bridgePanel", "Bug Report")) self.bugReport.setWindowIcon(self.iconStart) self.bugReport.createPanel() self.bugReport.show() self.bugReport.setGeometry(250, 150, 1024, 768)