def askQuestion(self, title, msg): """Ask a question with a yes/no dialog.""" # Used in RespiRate and MouseFunctions # We can't use QMessageBox.question because it creates a modal dialog (i.e # it blocks viewing/interacting with other RespiRate windows). This means # that a user would not be able to check the data graphs until after # choosing whether to export the data. if self == 'noself': self = QWidget() ask = QMessageBox(self) ask.setWindowTitle(title) ask.setText(msg) ask.setIcon(QMessageBox.Question) ask.setDefaultButton(QMessageBox.Yes) ask.setStandardButtons(QMessageBox.Yes | QMessageBox.No) ask.setWindowModality(0) ask.activateWindow() ask.show() retval = ask.exec_() if retval == QMessageBox.Yes: ans = 'yes' else: ans = 'no' return ans
def on_btn_power_off_clicked(self): font = QFont() font.setFamily('Arial') font.setPointSize(10) dialog = QMessageBox(None) dialog.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Popup) dialog.setText('POWER OFF') dialog.setIcon(QMessageBox.Warning) dialog.setStandardButtons(QMessageBox.Cancel | QMessageBox.Reset | QMessageBox.Close) btn_cancel = dialog.button(QMessageBox.Cancel) btn_cancel.setText('CANCEL') btn_cancel.setFont(font) btn_reset = dialog.button(QMessageBox.Reset) btn_reset.setText('RESET') btn_reset.setFont(font) btn_close = dialog.button(QMessageBox.Close) btn_close.setText('POWER OFF') btn_close.setFont(font) dialog.exec_() dialog.activateWindow() btn_clicked = dialog.clickedButton() if btn_clicked == btn_cancel: pass elif btn_clicked == btn_reset: pass elif btn_clicked == btn_close: self.closeEvent()
def show_message(title, info, type_=QMessageBox.Information): """ show message """ QApplication.instance() message_box = QMessageBox() message_box.setText(info) message_box.setWindowTitle(title) message_box.setWindowIcon(QtGui.QIcon(Path.ICON_PATH)) message_box.setIcon(type_) message_box.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) message_box.activateWindow() message_box.exec_()
def Messaging(title, text, icon): msgBox = QMessageBox() msgBox.setWindowTitle(title) msgBox.setText(text) msgBox.setStandardButtons(QMessageBox.Yes) if icon == 'Information': msgBox.setIcon(QMessageBox.Information) elif icon == 'Question': msgBox.setIcon(QMessageBox.Question) elif icon == 'Warning': msgBox.setIcon(QMessageBox.Warning) else: msgBox.setIcon(QMessageBox.Critical) msgBox.setDefaultButton(QMessageBox.Yes) msgBox.setWindowIcon(QIcon('image/information-icon.png')) msgBox.setWindowFlags(Qt.WindowStaysOnTopHint) msgBox.setWindowFlags(msgBox.windowFlags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMaximizeButtonHint & ~Qt.WindowMinimizeButtonHint) msgBox.activateWindow() msgBox.raise_() result = msgBox.exec_() return result
def on_systray_activated(): buttons = qApp.mouseButtons() if not buttons: msgBox = QMessageBox() msgBox.setWindowTitle('Exit') msgBox.setText('Are you sure to quit?') msgBox.setStandardButtons(QMessageBox.No | QMessageBox.Yes) msgBox.setIcon(QMessageBox.Information) msgBox.setDefaultButton(QMessageBox.No) msgBox.setWindowIcon(QIcon('image/icon.png')) msgBox.setWindowFlags(Qt.WindowStaysOnTopHint) msgBox.setWindowFlags(msgBox.windowFlags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMaximizeButtonHint & ~Qt.WindowMinimizeButtonHint) msgBox.activateWindow() msgBox.raise_() result = msgBox.exec_() if result == QMessageBox.Yes: WifiServer.EXIT = True quit(0) sys.exit(0)
class Gui(QWidget): def __init__(self, parent=None): super(Gui, self).__init__(parent) # Other classes self.db_manager = DatabaseManager() self.db_sitemanager = mysql.connector.connect( host="srv-11.edyson.nl", user="******", password="******", database="frisonline_sitemanager") self.db_sitemanager_cursor = self.db_sitemanager.cursor() self.stacker = Stacker() self.initExcel() # Multithreading self.threadpool = QThreadPool() self.popup_window_trigger_thread = PopupWindowTriggerThread(self) self.popup_window_trigger_thread.finished_stacking_signal.connect( self.displayPopupWindowFinishedStacking) self.popup_window_trigger_thread.start() # Create all the layouts and button events self.createButtonsLayout() self.createButtonEvents() self.createGridOrdersLayout() self.createGridDrawing() self.createGridOrdersEvents() self.createMainLayout() self.setLayout(self.main_layout) self.refreshNewOrders() def getBrandsFromSitemanager(self): cursor = self.db_sitemanager_cursor cursor.execute( "SELECT DISTINCT brandname from fsm_website_product WHERE fsm_website_id = 68" ) result = cursor.fetchall() brands = [x[0] for x in result] brands.extend(["Ondervloer 3,6mm", "Ondervloer 5mm"]) return brands def getProductNamesFromSitemanager(self, brand): if brand == "Ondervloer 3,6mm" or brand == "Ondervloer 5mm": self.grid_product_options_dropdown.clear() self.grid_product_dropdown.clear() return [] else: brand = str("'" + brand + "'") cursor = self.db_sitemanager_cursor cursor.execute( "SELECT fwpl.name, fwpl.fsm_website_product_id from fsm_website_product inner join fsm_website_product_language fwpl on fsm_website_product.id = fwpl.fsm_website_product_id WHERE fsm_website_id = 68 AND brandname = " + str(brand)) result = cursor.fetchall() return [x[0] for x in result] def getProductOptionsFromSitemanager(self, product_name): product_name = str("'" + product_name + "'") cursor = self.db_sitemanager_cursor cursor.execute( "SELECT fwpol.name FROM fsm_website_product p INNER JOIN fsm_website_product_language fwpl ON fwpl.fsm_website_product_id = p.id INNER JOIN fsm_website_product_option fwpo ON p.id = fwpo.fsm_website_product_id INNER JOIN fsm_website_product_option_language fwpol ON fwpo.id = fwpol.fsm_website_product_option_id WHERE p.fsm_website_id = 68 AND fwpl.name = " + product_name) result = cursor.fetchall() return [x[0] for x in result] def initExcel(self): desktop = Helper.getDesktopPath() path = desktop + "/paklijsten/" file_name = "paklijst.xlsx" self.excel_parser = ExcelParser( data_logger=self.stacker.getDataLogger(), path=path, file_name=file_name, sheet_name='Paklijst') self.stacker.setExcelParser(path=path, file_name=file_name) def fillProductNames(self, brand): product_names = self.getProductNamesFromSitemanager(brand) self.grid_product_dropdown.clear() for product_name in product_names: self.grid_product_dropdown.addItem(product_name) def fillProductOptions(self, product_name): product_options = self.getProductOptionsFromSitemanager(product_name) self.grid_product_options_dropdown.clear() for product_option in product_options: self.grid_product_options_dropdown.addItem(product_option) # this creates the middle side of the GUI def createButtonsLayout(self): self.buttons_layout = QVBoxLayout() group_box = QGroupBox("Grid") self.create_grid_button = QPushButton("Create New Grid") self.remove_grid_button = QPushButton("Remove Grid") grid_layout = QGridLayout() grid_layout.addWidget(self.create_grid_button, 3, 0) grid_layout.addWidget(self.remove_grid_button, 3, 1) self.load_orders_button = QPushButton("Load new orders") self.clear_orders_button = QPushButton("Clear new orders") self.excel_file_line_edit = QLineEdit("test2.xlsm") self.grid_product_label = QLabel("Product name") self.grid_product_option_label = QLabel("Product option") self.grid_product_dropdown = QComboBox(self) self.grid_product_options_dropdown = QComboBox(self) self.grid_brand_label = QLabel("Brand") self.grid_brand_dropdown = QComboBox(self) self.grid_product_dropdown.activated[str].connect( self.onProductNameDropdownChanged) self.grid_product_options_dropdown.activated[str].connect( self.onProductOptionsDropdownChanged) self.grid_brand_dropdown.activated[str].connect( self.onBrandDropdownChanged) grid_layout.addWidget(self.grid_product_label, 4, 0) grid_layout.addWidget(self.grid_brand_label, 4, 1) grid_layout.addWidget(self.grid_product_dropdown, 5, 0) grid_layout.addWidget(self.grid_product_option_label, 6, 0) grid_layout.addWidget(self.grid_product_options_dropdown, 7, 0) # grid_layout.addWidget(self.grid_color_line_edit, 5, 0) grid_layout.addWidget(self.grid_brand_dropdown, 5, 1) for brand in self.getBrandsFromSitemanager(): self.grid_brand_dropdown.addItem(str(brand)) self.create_grid_grid_width_label = QLabel("Width") self.create_grid_grid_width_line_edit = QLineEdit("100") self.create_grid_grid_height_label = QLabel("Length") self.create_grid_grid_height_line_edit = QLineEdit("100") grid_layout.addWidget(self.create_grid_grid_width_label, 8, 0) grid_layout.addWidget(self.create_grid_grid_width_line_edit, 9, 0) grid_layout.addWidget(self.create_grid_grid_height_label, 8, 1) grid_layout.addWidget(self.create_grid_grid_height_line_edit, 9, 1) group_box.setLayout(grid_layout) self.buttons_layout.addWidget(group_box) self.clear_database_button = QPushButton("Clear database") self.buttons_layout.addWidget(self.load_orders_button) self.buttons_layout.addWidget(self.excel_file_line_edit) self.buttons_layout.addWidget(self.clear_orders_button) self.buttons_layout.addWidget(self.clear_database_button) group_box = QGroupBox("Stacking") layout = QVBoxLayout() self.stop_stacking_button = QPushButton("Stop") self.start_stacking_automatic_button = QPushButton("Automatic") standard_orders_layout = QGridLayout() self.standard_orders_label = QLabel("Standard orders") self.standard_order_60_80_checkbox = QCheckBox("60 x 80") self.standard_order_60_80_checkbox.setChecked(True) self.standard_order_100_80_checkbox = QCheckBox("100 x 80") self.standard_order_50_80_checkbox = QCheckBox("50 x 80") self.standard_order_40_70_checkbox = QCheckBox("40 x 70") layout.addWidget(self.start_stacking_automatic_button) layout.addWidget(self.stop_stacking_button) layout.addWidget(self.standard_orders_label) standard_orders_layout.addWidget(self.standard_order_60_80_checkbox, 0, 0) standard_orders_layout.addWidget(self.standard_order_100_80_checkbox, 1, 0) standard_orders_layout.addWidget(self.standard_order_50_80_checkbox, 0, 1) standard_orders_layout.addWidget(self.standard_order_40_70_checkbox, 1, 1) layout.addLayout(standard_orders_layout) self.fill_orders_with_smaller_in_larger_grid_widths_radiobutton = QRadioButton( "Fill orders with smaller grid widths in larger ones") self.fill_orders_with_smaller_in_larger_grid_widths_radiobutton.setChecked( True) layout.addWidget( self.fill_orders_with_smaller_in_larger_grid_widths_radiobutton) code_status_label = QLabel("Status") self.code_status_line_edit = QLineEdit() layout.addWidget(code_status_label) layout.addWidget(self.code_status_line_edit) group_box.setLayout(layout) self.buttons_layout.addWidget(group_box) self.buttons_layout.addStretch() def onProductNameDropdownChanged(self): self.fillProductOptions(self.grid_product_dropdown.currentText()) def onBrandDropdownChanged(self): self.fillProductNames(self.grid_brand_dropdown.currentText()) def onProductOptionsDropdownChanged(self): if self.grid_product_options_dropdown.currentText().split( )[0] == "Rolbreedte": print(self.grid_product_options_dropdown.currentText().split()[1]) self.create_grid_grid_width_line_edit.setText( self.grid_product_options_dropdown.currentText().split()[1]) def createButtonEvents(self): self.create_grid_button.clicked.connect(self.onCreateGridClick) self.remove_grid_button.clicked.connect(self.onRemoveGridClick) self.stop_stacking_button.clicked.connect( lambda: self.useMultithread(self.onStopStackingClick)) self.start_stacking_automatic_button.clicked.connect( lambda: self.useMultithread(self.onStartStackingAutomaticClick)) self.load_orders_button.clicked.connect(self.onLoadOrdersClick) self.clear_orders_button.clicked.connect(self.onClearNewOrdersClick) self.clear_database_button.clicked.connect(self.onClearDatabaseClick) def useMultithread(self, function): worker = Worker(function) self.threadpool.start(worker) def onCreateGridClick(self): brand = self.grid_brand_dropdown.currentText() width = self.create_grid_grid_width_line_edit.text() height = self.create_grid_grid_height_line_edit.text() product_name = self.grid_product_dropdown.currentText() product_option = self.grid_product_options_dropdown.currentText() color = self.getTypeFromProductNameAndProductOption( product_name, product_option) grid = self.db_manager.createUniqueGrid(width=width, height=height, brand=brand, color=color) list_widget_item = QListWidgetItem("Grid " + str(grid.getName())) self.list_widget_grids.addItem(list_widget_item) self.list_widget_grids.repaint() def transformType(self, _type): transformation_dict = { "82783-0": "82783-0", "82782-0": "82782-0", "102082-0": "13747-388585", "98305-0": "13747-388585", "102075-0": "13747-388585", "102078-0": "13747-3885845", "98304-0": "13738-388571", "98303-0": "13738-388571", "102081-0": "13738-388571", "14778-0": "13738-388571", "102074-0": "13738-388570", "102083-0": "13743-388577", "100906-0": "13743-388577", "102076-0": "13743-388577", "102079-0": "13743-388576", "102080-0": "13746-388583", "100907-0": "13746-388583", "102077-0": "13746-388583", "102084-0": "13746-388582", } if _type in transformation_dict.keys(): return transformation_dict[_type] else: return _type def getTypeFromProductNameAndProductOption(self, product_name, product_option): product_name = str("'" + product_name + "'") product_option = str("'" + product_option + "'") cursor = self.db_sitemanager_cursor query = "SELECT fwpl.fsm_website_product_id, fwpo.id, fwpol.name FROM fsm_website_product p INNER JOIN fsm_website_product_language fwpl ON fwpl.fsm_website_product_id = p.id INNER JOIN fsm_website_product_option fwpo ON p.id = fwpo.fsm_website_product_id INNER JOIN fsm_website_product_option_language fwpol ON fwpo.id = fwpol.fsm_website_product_option_id WHERE p.fsm_website_id = 68 AND fwpl.name = " + product_name + " AND fwpol.name = " + product_option cursor.execute(query) result = cursor.fetchall() product_name_code = result[0][0] product_option_code = result[0][1] _type = str(product_name_code) + "-" + str(product_option_code) _type = self.transformType(_type) return _type def onEmptyGridClick(self): grid_number = int( self.list_widget_grids.currentItem().text().split(' ')[1]) grid = self.db_manager.getGrid(grid_number) self.db_manager.emptyGrid(grid) self.refreshGrids() self.refreshNewOrders() def refreshNewOrders(self): self.removeAllNewOrderItems() unstacked_rectangles = self.db_manager.getUnstackedRectangles() for rectangle in unstacked_rectangles: list_widget_item = QListWidgetItem("Order " + str(rectangle.getName())) self.list_widget_new_orders.addItem(list_widget_item) def removeAllNewOrderItems(self): self.list_widget_new_orders.clear() def removeAllOrderItems(self): self.list_widget_orders.clear() def refreshGrids(self): grids = self.db_manager.getGridsNotCut() self.list_widget_grids.clear() for grid in grids: list_widget_item = QListWidgetItem("Grid " + str(grid.getName())) self.list_widget_grids.addItem(list_widget_item) def onRemoveGridClick(self): grid_number = int( self.list_widget_grids.currentItem().text().split(' ')[1]) grid = self.db_manager.getGrid(grid_number) self.removeGridItem(remove_completely=True) def onStartStackingClick(self): self.loadOrders() self.stacker.startStacking() grid_number = int( self.list_widget_grids.currentItem().text().split(' ')[1]) grid = self.db_manager.getGrid(grid_number) self.updateCodeStatus("Stacking started for grid " + str(grid_number)) self.stacker.setGrid(grid) self.setFillParameters() self.stacker.start(automatic=False) self.refreshGrid(grid_number) self.refreshNewOrders() self.updateCodeStatus("Done with stacking grid " + str(grid_number) + "!") def updateCodeStatus(self, text): self.code_status_line_edit.setText(text) def onStopStackingClick(self): self.stacker.stopStacking() def onStartStackingAutomaticClick(self): self.setFillParameters() self.loadOrdersCreateNecessaryGridsAndStartStacking() # signal thread that we should execute popup window self.popup_window_trigger_thread.setFinishedStacking(True) def displayPopupWindowFinishedStacking(self): self.popup_window = QMessageBox() popup_message = "" popup_message += str(self.stacker.getDataLogger( ).getSuccessfullyStackedRectangles()) + "/" + str( self.stacker.getDataLogger().getTotalRectanglesToStack( )) + " succesfully stacked orders \n \n" popup_message += "Total execution time is " + str( round(self.stacker.getDataLogger().getTotalExecutionTime() / 60, 2)) + "min \n \n" popup_message += str(self.stacker.getDataLogger().getAmountOfErrors() ) + " error(s) occured: \n" if self.stacker.getDataLogger().getAmountOfErrors() > 0: for error in self.stacker.getDataLogger().getErrorData(): popup_message += str(error) + "\n" self.popup_window.setText(popup_message) self.popup_window.setIcon(QMessageBox.Information) self.popup_window.setWindowTitle("Stacker finished") # https://stackoverflow.com/questions/6087887/bring-window-to-front-raise-show-activatewindow-don-t-work self.popup_window.setWindowState(self.popup_window.windowState() & ~Qt.WindowActive) self.popup_window.show() self.popup_window.activateWindow() def setFillParameters(self): standard_sizes = [] if self.standard_order_60_80_checkbox.isChecked(): standard_sizes.append((60, 80)) if self.standard_order_100_80_checkbox.isChecked(): standard_sizes.append((100, 80)) if self.standard_order_50_80_checkbox.isChecked(): standard_sizes.append((50, 80)) if self.standard_order_40_70_checkbox.isChecked(): standard_sizes.append((40, 70)) self.stacker.setStandardSizesToFill(standard_sizes) if self.fill_orders_with_smaller_in_larger_grid_widths_radiobutton.isChecked( ): self.stacker.setFillOrdersWithSmallerGridWidths(True) else: self.stacker.setFillOrdersWithSmallerGridWidths(False) def loadOrdersCreateNecessaryGridsAndStartStacking(self): self.updateCodeStatus( "Creating grids, stacking and exporting. Please wait...") self.stacker.start(automatic=True) self.refreshGrids() self.refreshNewOrders() self.updateCodeStatus("Done with automatic stacking!") def onLoadOrdersClick(self): self.loadOrders() def loadOrders(self): file_name = self.excel_file_line_edit.text() desktop = Helper.getDesktopPath() path = desktop + "/paklijsten/" self.excel_parser.setFileName(file_name) self.stacker.setExcelParser(path=path, file_name=file_name) unstacked_rectangles = self.excel_parser.getUnstackedRectangles() self.db_manager.addRectangles(unstacked_rectangles) self.refreshNewOrders() def onClearNewOrdersClick(self): self.db_manager.clearNewOrders() self.refreshNewOrders() def onMakeDatabaseBackupClick(self): self.db_manager.makeBackup() def onClearDatabaseClick(self): self.db_manager.clearDatabase() self.refreshGrids() self.refreshNewOrders() def onExportClick(self): grid_number = int( self.list_widget_grids.currentItem().text().split(' ')[1]) grid = self.db_manager.getGrid(grid_number, for_cutting=True) if self.export_dxf_radio_button.isChecked(): self.stacker.convertRectanglesToMillimetersOptimizeAndExportGrid() elif self.export_pdf_radio_button.isChecked(): grid.toPdf() elif self.export_html_radio_button.isChecked(): grid.toHtml() def onCutClick(self): self.removeGridItem('uncut') def onUncutClick(self): self.removeGridItem('cut') def removeGridItem(self, current_grid_state='uncut', remove_completely=False): if current_grid_state == 'cut': list_widget_current = self.list_widget_cut_grids list_widget_next = self.list_widget_grids elif current_grid_state == 'uncut': list_widget_current = self.list_widget_grids list_widget_next = self.list_widget_cut_grids grid_number = int( list_widget_current.currentItem().text().split(' ')[1]) grid = self.db_manager.getGrid(grid_number) if current_grid_state == 'cut': grid.setUncut() elif current_grid_state == 'uncut': grid.setCut() if not remove_completely: self.db_manager.updateGrid(grid) else: self.db_manager.removeGrid(grid) item = list_widget_current.findItems( list_widget_current.currentItem().text(), Qt.MatchExactly) row = list_widget_current.row(item[0]) list_widget_current.takeItem(row) if not remove_completely: list_widget_next.addItem(item[0]) def createGridOrdersLayout(self): self.grid_orders_layout = QVBoxLayout() self.list_widget_grids = QListWidget() self.list_widget_cut_grids = QListWidget() self.list_widget_orders = QListWidget() self.list_widget_new_orders = QListWidget() grids = self.db_manager.getGridsNotCut() for grid in grids: list_widget_item = QListWidgetItem("Grid " + str(grid.getName())) self.list_widget_grids.addItem(list_widget_item) cut_grids = self.db_manager.getGridsCut() for grid in cut_grids: list_widget_item = QListWidgetItem("Grid " + str(grid.getName())) self.list_widget_cut_grids.addItem(list_widget_item) cut_uncut_group_box = QGroupBox("") self.cut_uncut_layout = QGridLayout() grids_label = QLabel("Available Grids") self.cut_uncut_layout.addWidget(grids_label, 0, 0) self.cut_uncut_layout.addWidget(self.list_widget_grids, 1, 0) uncut_color_label = QLabel("Type") uncut_width_label = QLabel("Width") uncut_height_label = QLabel("Length") uncut_brand_label = QLabel("Brand") quantity_orders_in_grid_label_name = QLabel("Quantity: ") self.uncut_color_line_edit = QLineEdit() self.uncut_width_line_edit = QLineEdit() self.uncut_brand_line_edit = QLineEdit() self.uncut_height_line_edit = QLineEdit() self.quantity_orders_in_grid_label_value = QLabel() self.cut_uncut_layout.addWidget(uncut_color_label, 2, 0) self.cut_uncut_layout.addWidget(self.uncut_color_line_edit, 3, 0) self.cut_uncut_layout.addWidget(uncut_width_label, 4, 0) self.cut_uncut_layout.addWidget(self.uncut_width_line_edit, 5, 0) self.cut_uncut_layout.addWidget(uncut_height_label, 6, 0) self.cut_uncut_layout.addWidget(self.uncut_height_line_edit, 7, 0) self.cut_uncut_layout.addWidget(uncut_brand_label, 8, 0) self.cut_uncut_layout.addWidget(self.uncut_brand_line_edit, 9, 0) cut_uncut_group_box.setLayout(self.cut_uncut_layout) self.grid_orders_layout.addWidget(cut_uncut_group_box) grid_orders_groupbox = QGroupBox("Orders in grid") grid_orders_layout = QGridLayout() quantity_orders_in_grid_layout = QHBoxLayout() quantity_orders_in_grid_layout.addWidget( quantity_orders_in_grid_label_name) quantity_orders_in_grid_layout.addWidget( self.quantity_orders_in_grid_label_value) grid_orders_layout.addLayout(quantity_orders_in_grid_layout, 0, 0) grid_orders_layout.addWidget(self.list_widget_orders, 1, 0) order_width_label = QLabel("Width") order_height_label = QLabel("Length") order_color_label = QLabel("Type") order_grid_width_label = QLabel("Grid width") order_brand_label = QLabel("Brand") self.width_line_edit = QLineEdit() self.height_line_edit = QLineEdit() self.color_line_edit = QLineEdit() self.grid_width_line_edit = QLineEdit() self.brand_line_edit = QLineEdit() grid_orders_layout.addWidget(order_width_label, 2, 0) grid_orders_layout.addWidget(self.width_line_edit, 3, 0) grid_orders_layout.addWidget(order_height_label, 4, 0) grid_orders_layout.addWidget(self.height_line_edit, 5, 0) grid_orders_layout.addWidget(order_color_label, 2, 1) grid_orders_layout.addWidget(self.color_line_edit, 3, 1) grid_orders_layout.addWidget(order_grid_width_label, 4, 1) grid_orders_layout.addWidget(self.grid_width_line_edit, 5, 1) grid_orders_layout.addWidget(order_brand_label, 6, 1) grid_orders_layout.addWidget(self.brand_line_edit, 7, 1) grid_orders_groupbox.setLayout(grid_orders_layout) self.grid_orders_layout.addWidget(grid_orders_groupbox) self.unstacked_orders_group_box = QGroupBox("New orders") unstacked_order_width_label = QLabel("Width") unstacked_order_height_label = QLabel("Length") unstacked_order_color_label = QLabel("Type") unstacked_order_grid_width_label = QLabel("Grid width") unstacked_order_brand_label = QLabel("Brand") self.unstacked_orders_layout = QGridLayout() self.unstacked_orders_layout.addWidget(self.list_widget_new_orders, 0, 0) self.unstacked_order_width_line_edit = QLineEdit() self.unstacked_order_height_line_edit = QLineEdit() self.unstacked_order_color_line_edit = QLineEdit() self.unstacked_order_grid_width_line_edit = QLineEdit() self.unstacked_order_brand_line_edit = QLineEdit() self.unstacked_orders_layout.addWidget(unstacked_order_width_label, 1, 0) self.unstacked_orders_layout.addWidget( self.unstacked_order_width_line_edit, 2, 0) self.unstacked_orders_layout.addWidget(unstacked_order_height_label, 3, 0) self.unstacked_orders_layout.addWidget( self.unstacked_order_height_line_edit, 4, 0) self.unstacked_orders_layout.addWidget(unstacked_order_color_label, 1, 1) self.unstacked_orders_layout.addWidget( self.unstacked_order_color_line_edit, 2, 1) self.unstacked_orders_layout.addWidget( unstacked_order_grid_width_label, 3, 1) self.unstacked_orders_layout.addWidget( self.unstacked_order_grid_width_line_edit, 4, 1) self.unstacked_orders_layout.addWidget(unstacked_order_brand_label, 5, 1) self.unstacked_orders_layout.addWidget( self.unstacked_order_brand_line_edit, 6, 1) self.unstacked_orders_group_box.setLayout(self.unstacked_orders_layout) self.grid_orders_layout.addWidget(self.unstacked_orders_group_box) def createGridDrawing(self): self.grid_drawing = QtWidgets.QLabel() # TODO relative to window size self.canvas_width, self.canvas_height = 200, 1000 self.max_rectangle_width, self.max_rectangle_height = Rectangle.getMaximumSize( ) #cm self.previous_rectangle = None self.canvas = QPixmap(self.canvas_width, self.canvas_height) color = QColor(255, 255, 255) self.canvas.fill(color) self.grid_drawing.setPixmap(self.canvas) def createGridOrdersEvents(self): self.list_widget_orders.itemDoubleClicked.connect( self.onDoubleClickOrder) self.list_widget_new_orders.itemDoubleClicked.connect( self.onDoubleClickNewOrder) self.list_widget_grids.itemDoubleClicked.connect( self.onDoubleClickGrid) self.list_widget_cut_grids.itemDoubleClicked.connect( self.onDoubleClickCutGrid) def onDoubleClickOrder(self): self.updateOrder('stacked') def onDoubleClickNewOrder(self): self.updateOrder('unstacked') def updateOrder(self, order_state='stacked'): if order_state == 'stacked': list_widget = self.list_widget_orders elif order_state == 'unstacked': list_widget = self.list_widget_new_orders rectangle_number = str(list_widget.currentItem().text().split(' ')[1]) rectangle = self.db_manager.getRectangle(rectangle_number, for_cutting=True) if rectangle.isStacked(): if self.previous_rectangle is not None: self.drawRectangle(self.previous_rectangle) self.drawRectangle(rectangle, color=Qt.red) self.current_rectangle = rectangle_number self.previous_rectangle = rectangle self.updateWidthHeightColorGridWidthBrand(rectangle) def updateWidthHeightColorGridWidthBrand(self, rectangle): if rectangle.isStacked(): self.width_line_edit.setText(str(rectangle.getWidth() * 10) + 'mm') self.height_line_edit.setText( str(rectangle.getHeight() * 10) + 'mm') self.color_line_edit.setText(str(rectangle.getColor())) self.grid_width_line_edit.setText(str(rectangle.getGridWidth())) self.brand_line_edit.setText(str(rectangle.getBrand())) else: self.unstacked_order_width_line_edit.setText( str(rectangle.getWidth() * 10) + 'mm') self.unstacked_order_height_line_edit.setText( str(rectangle.getHeight() * 10) + 'mm') self.unstacked_order_color_line_edit.setText( str(rectangle.getColor())) self.unstacked_order_grid_width_line_edit.setText( str(rectangle.getGridWidth())) self.unstacked_order_brand_line_edit.setText( str(rectangle.getBrand())) def onDoubleClickGrid(self): grid_number = int( self.list_widget_grids.currentItem().text().split(' ')[1]) self.refreshGrid(grid_number) self.previous_rectangle = None self.width_line_edit.setText("") self.height_line_edit.setText("") def onDoubleClickCutGrid(self): self.refreshCutGrid() def refreshGrid(self, grid_number): grid = self.db_manager.getGrid(grid_number) stacked_rectangles = grid.getStackedRectangles() self.stacker.setGrid(grid) self.uncut_color_line_edit.setText(grid.getColor()) self.uncut_width_line_edit.setText(str(grid.getWidth())) self.uncut_height_line_edit.setText(str(grid.height)) self.uncut_brand_line_edit.setText(str(grid.getBrand())) self.drawGrid(grid) self.removeAllOrderItems() for rectangle in stacked_rectangles: list_widget_item = QListWidgetItem("Order " + str(rectangle.getName())) self.list_widget_orders.addItem(list_widget_item) quantity_orders_in_grid = len(stacked_rectangles) self.quantity_orders_in_grid_label_value.setText( str(quantity_orders_in_grid)) QApplication.processEvents() def refreshCutGrid(self): grid_number = int( self.list_widget_cut_grids.currentItem().text().split(' ')[1]) grid = self.db_manager.getGrid(grid_number) self.cut_color_line_edit.setText(grid.getColor()) self.cut_width_line_edit.setText(str(grid.getWidth())) self.cut_brand_line_edit.setText(str(grid.getBrand())) self.drawGrid(grid) self.removeAllOrderItems() for rectangle in grid.getStackedRectangles(): list_widget_item = QListWidgetItem("Order " + str(rectangle.getName())) self.list_widget_orders.addItem(list_widget_item) QApplication.processEvents() def drawGrid(self, grid): self.grid_drawing.setPixmap(self.canvas) rectangles = grid.getStackedRectangles() for rectangle in rectangles: print(rectangle) self.drawRectangle(rectangle) def drawRectangle(self, rectangle, color=Qt.green): painter = QPainter(self.grid_drawing.pixmap()) painter.setPen(QPen(Qt.black, 1, Qt.SolidLine)) painter.setBrush(QBrush(color, Qt.DiagCrossPattern)) x = rectangle.getTopLeft()[0] y = rectangle.getTopLeft()[1] width = rectangle.getWidth() height = rectangle.getHeight() y = self.max_rectangle_height - y x = int(x / self.max_rectangle_width * self.canvas_width) y = int(y / self.max_rectangle_height * self.canvas_height) width = int(width / self.max_rectangle_width * self.canvas_width) height = int(height / self.max_rectangle_height * self.canvas_height) painter.drawRect(x, y, width, height) painter.end() self.grid_drawing.update() QApplication.processEvents() def createMainLayout(self): # GUI is separated into three parts # Most left is the grid drawing # middle are all the buttons # right are the orders in the grids and unstacked orders self.main_layout = QHBoxLayout() self.main_layout.addWidget(self.grid_drawing) self.main_layout.addLayout(self.buttons_layout) self.main_layout.addLayout(self.grid_orders_layout)
class GUI(QMainWindow): FRAME_WIDTH = 700 FRAME_HEIGHT = 600 FRAME_BORDER = 20 def __init__(self, config_man: ConfigManager, updater: Updater): super(GUI, self).__init__() self._config_man = config_man self._updater = updater self._subreddit_list = QListWidget() self._subreddit_text_field = QLineEdit() self._subreddit_add_btn = QPushButton() self._subreddit_del_btn = QPushButton() self._filter_text_field = QLineEdit() self._filter_add_btn = QPushButton() self._filter_del_btn = QPushButton() self._filt_rb_include = QRadioButton("Include") self._filt_rb_exclude = QRadioButton("Exclude") self._filter_phrase_list = QListWidget() self._sound_checkbox = CheckBox("Sound", self._sound_notify) self._popup_checkbox = CheckBox("Popup", self._popup_notify) self._notification_checkboxes = [self._sound_checkbox, self._popup_checkbox] self._update_button = QPushButton("Update") self._notification_sound = QSound(self._config_man.properties['notification_sound_path']) self._thread_list = QListWidget() self._status_bar = QStatusBar() self._last_updated_label = QLabel() self._refresh_rate_select = QComboBox() self._popup = None self._init_properties() self._init_layout() self._init_bindings() def _init_layout(self): self.setBaseSize(self.FRAME_WIDTH, self.FRAME_HEIGHT) self.setGeometry(QRect(100, 100, self.FRAME_WIDTH, self.FRAME_HEIGHT)) self._subreddit_list.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) self._subreddit_text_field.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self._subreddit_add_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._subreddit_del_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._filter_text_field.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self._filter_add_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._filter_del_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._filt_rb_include.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._filt_rb_exclude.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self._filter_phrase_list.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) for checkbox in self._notification_checkboxes: checkbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self._refresh_rate_select.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self._update_button.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) subreddit_box = QHBoxLayout() subreddit_box.addWidget(self._subreddit_text_field) subreddit_box.addWidget(self._subreddit_add_btn) subreddit_box.addWidget(self._subreddit_del_btn) filter_box = QHBoxLayout() filter_box.addWidget(self._filter_text_field) filter_box.addWidget(self._filter_add_btn) filter_box.addWidget(self._filter_del_btn) refresh_rate_box = QHBoxLayout() label = QLabel("Refresh rate") label.setFixedSize(70, 20) refresh_rate_box.addWidget(label) refresh_rate_box.addWidget(self._refresh_rate_select) refresh_rate_box.addSpacing(5) label = QLabel("mins") label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) refresh_rate_box.addWidget(label) option_box = QVBoxLayout() label = QLabel("Subreddits") label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) option_box.addWidget(label) option_box.addWidget(self._subreddit_list) option_box.addItem(subreddit_box) option_box.addSpacing(self.FRAME_BORDER) label = QLabel("Filter phrases") label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) option_box.addWidget(label) option_box.addWidget(self._filter_phrase_list) option_box.addItem(filter_box) option_box.addWidget(self._filt_rb_include) option_box.addWidget(self._filt_rb_exclude) option_box.addSpacing(self.FRAME_BORDER) for checkbox in self._notification_checkboxes: option_box.addWidget(checkbox) option_box.addSpacing(self.FRAME_BORDER) option_box.addItem(refresh_rate_box) option_box.addSpacing(self.FRAME_BORDER) option_box.addWidget(self._update_button) self._thread_list.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self._thread_list.setIconSize(QSize(200, 200)) self._thread_list.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self._subreddit_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self._filter_phrase_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self._thread_list.setSelectionMode(QAbstractItemView.NoSelection) hbox = QHBoxLayout() hbox.addItem(option_box) hbox.addWidget(self._thread_list) main = QWidget() main.setLayout(hbox) self.setCentralWidget(main) self.setStatusBar(self._status_bar) self._status_bar.addWidget(self._last_updated_label) def _init_bindings(self): self._updater.updater_task.update.connect(self.update_reddit_posts) self._update_button.clicked.connect(self.update_reddit_posts) self._subreddit_text_field.returnPressed.connect(self._add_subreddit) self._filter_add_btn.pressed.connect(self._add_filter_phrase) self._filter_text_field.returnPressed.connect(self._add_filter_phrase) self._filter_del_btn.pressed.connect(self._del_filter_phrase) self._subreddit_add_btn.clicked.connect(self._add_subreddit) self._subreddit_del_btn.clicked.connect(self._del_subreddit) self._sound_checkbox.stateChanged.connect(lambda state: self._config_man.set('sound_notify', state)) self._popup_checkbox.stateChanged.connect(lambda state: self._config_man.set('popup_notify', state)) self._filt_rb_include.toggled.connect(self._change_filter_mode) self._filt_rb_exclude.toggled.connect(self._change_filter_mode) self._refresh_rate_select.currentIndexChanged.connect(lambda rate: self._updater.set_refresh_rate((rate+1)*60)) def _init_properties(self): for sub in self._config_man.properties['subreddits']: self._subreddit_list.addItem(QListWidgetItem(sub.lower())) for phrase in self._config_man.properties['filter_phrases']: self._filter_phrase_list.addItem(QListWidgetItem(phrase)) if self._config_man.properties['filter_mode'] == 'exclude': self._filt_rb_exclude.setChecked(True) else: self._filt_rb_include.setChecked(True) checked = True if self._config_man.properties['sound_notify'] == 2 else False self._sound_checkbox.setChecked(checked) checked = True if self._config_man.properties['popup_notify'] == 2 else False self._popup_checkbox.setChecked(checked) self._last_updated_label.setText("last updated: " + time.strftime("%d/%m/%y %I:%M%p", time.localtime(self._config_man.properties['last_updated']))) self._subreddit_add_btn.setIcon(QIcon("../resources/add_button.png")) self._subreddit_del_btn.setIcon(QIcon("../resources/del_button.png")) self._filter_add_btn.setIcon(QIcon("../resources/add_button.png")) self._filter_del_btn.setIcon(QIcon("../resources/del_button.png")) for i in range(1, 61): self._refresh_rate_select.addItem(str(i)) self._refresh_rate_select.setCurrentText(str(self._config_man.properties['refresh_rate']//60)) def update_reddit_posts(self): try: new_threads = self._updater.update() for thread in new_threads: item = ThreadItem(thread) self._thread_list.addItem(item.stub) self._thread_list.setItemWidget(item.stub, item.delegate) self._thread_list.scrollToBottom() if len(new_threads) != 0: for checkbox in self._notification_checkboxes: checkbox.execute_if_checked() self._last_updated_label.setText("last updated: " + time.strftime("%d/%m/%y %I:%M%p", time.localtime())) except UpdaterException: pass def _add_subreddit(self): entry = self._subreddit_text_field.text().lower().replace(" ", "") if not self._config_man.properties['subreddits'].__contains__(entry) and entry != "": self._subreddit_list.addItem(QListWidgetItem(entry)) self._config_man.properties['subreddits'].append(entry) self._subreddit_text_field.clear() def _add_filter_phrase(self): entry = self._filter_text_field.text().lower() if not self._config_man.properties['filter_phrases'].__contains__(entry) and entry != "": self._filter_phrase_list.addItem(QListWidgetItem(entry)) self._config_man.properties['filter_phrases'].append(entry) self._filter_text_field.clear() def _del_subreddit(self): items = self._subreddit_list.selectedItems() for item in items: row = self._subreddit_list.row(item) self._subreddit_list.takeItem(row) try: self._config_man.properties['subreddits'].remove(item.text()) except ValueError: pass def _del_filter_phrase(self): items = self._filter_phrase_list.selectedItems() for item in items: row = self._filter_phrase_list.row(item) self._filter_phrase_list.takeItem(row) try: self._config_man.properties['filter_phrases'].remove(item.text()) except ValueError: pass def closeEvent(self, a0): self._config_man.save() def _sound_notify(self): if self._config_man.properties['notification_sound_path'] == "": winsound.MessageBeep() else: self._notification_sound.play() def _popup_notify(self): self._popup = QMessageBox(QMessageBox.NoIcon, "Reddit Monitor", "") self._popup.show() self._popup.setWindowState(self._popup.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) self._popup.activateWindow() def _change_filter_mode(self): if self._filt_rb_exclude.isChecked(): self._config_man.set('filter_mode', 'exclude') else: self._config_man.set('filter_mode', 'include')