class ResultBlock(QWidget): def __init__(self, result, type, parent=None): super(ResultBlock, self).__init__(parent) self.result = result self.text_font = QFont('monospace', 16) if type == 'plain': self.result_block = QTextEdit() self.result_block.setFont(self.text_font) self.result_block.insertPlainText(result) self.result_block.setMinimumHeight(600) # Make sure scrollbar is always at the top self.result_block.moveCursor(QTextCursor().Start) self.result_block.ensureCursorVisible() self.result_block.setReadOnly(True) elif type == 'html': self.result_block = QTextEdit() self.result_block.setFont(self.text_font) self.result_block.insertHtml(result) self.result_block.setMinimumHeight(600) # Make sure scrollbar is always at the top self.result_block.moveCursor(QTextCursor().Start) self.result_block.ensureCursorVisible() self.result_block.setReadOnly(True) elif type == 'image': self.result_block = QScrollArea() self.image_preview = QWidget() image_preview_layout = QVBoxLayout() image_preview_layout.addWidget(result) print(result) self.image_preview.setLayout(image_preview_layout) self.result_block.setWidget(self.image_preview) self.result_block.setWidgetResizable(True) self.result_block.setMinimumHeight(600) # Create layout and add widgets layout = QVBoxLayout() layout.addWidget(self.result_block) # Set layout self.setLayout(layout)
class AdjustChunkBrightContrastDlg(QtWidgets.QDialog): # path = '' # image = Image def __init__(self, parent): QtWidgets.QDialog.__init__(self, parent) self.setWindowTitle( "ADJUST PHOTOS BRIGHTNESS - CONTRAST, CMG (MAROC)") # self.adjustSize() self.setMaximumHeight(880) self.createParamsGridLayout() self.createButtonsGridLayout() self.createProgressBar() self.createImageViewerLayout() vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.groupBoxParams) vbox.addWidget(self.groupBoxViewer) vbox.addWidget(self.groupBoxProgressBar) vbox.addWidget(self.groupBoxButtons) self.setLayout(vbox) self.exec() def createImageViewerLayout(self): self.groupBoxViewer = QtWidgets.QGroupBox() gridViewerLayout = QtWidgets.QGridLayout() self.scaleFactor = 0.0 self.imageLabel = QtWidgets.QLabel(self) self.imageLabel.setBackgroundRole(QtGui.QPalette.Base) self.imageLabel.setSizePolicy( QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored) self.imageLabel.setScaledContents(True) self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.imageLabel) self.scrollArea.setMinimumHeight(605) # self.scrollArea.setMaximumHeight(605) self.scrollArea.setMinimumWidth(830) self.scrollArea.setMaximumWidth(830) self.getChunk() self.getPaths() self.getImage(0) self.scrollArea.setWidgetResizable(False) self.normalSize() self.scaleImage(0.16) gridViewerLayout.addWidget(self.scrollArea, 1, 0) self.createViewerButtons() gridViewerLayout.addWidget(self.groupBoxViewerBtn, 0, 0) self.groupBoxViewer.setLayout(gridViewerLayout) def createViewerButtons(self): self.groupBoxViewerBtn = QtWidgets.QGroupBox() gridViewerBtnLayout = QtWidgets.QGridLayout() self.btnNextPhoto = QtWidgets.QPushButton("->") self.btnNextPhoto.setFixedSize(23, 23) self.btnPreviousPhoto = QtWidgets.QPushButton("<-") self.btnPreviousPhoto.setFixedSize(23, 23) self.btnZoomIn = QtWidgets.QPushButton("+") self.btnZoomIn.setFixedSize(23, 23) self.btnZoomOut = QtWidgets.QPushButton("-") self.btnZoomOut.setFixedSize(23, 23) # self.btnZoomOut = QtWidgets.QPushButton("-") # self.btnZoomOut.setFixedSize(23, 23) gridViewerBtnLayout.addWidget(self.btnZoomIn, 0, 0) gridViewerBtnLayout.addWidget(self.btnZoomOut, 0, 1) gridViewerBtnLayout.addWidget(self.btnPreviousPhoto, 0, 3) gridViewerBtnLayout.addWidget(self.btnNextPhoto, 0, 4) QtCore.QObject.connect( self.btnZoomIn, QtCore.SIGNAL("clicked()"), self.zoomIn) QtCore.QObject.connect( self.btnZoomOut, QtCore.SIGNAL("clicked()"), self.zoomOut) QtCore.QObject.connect( self.btnNextPhoto, QtCore.SIGNAL("clicked()"), self.nextPhoto) QtCore.QObject.connect( self.btnPreviousPhoto, QtCore.SIGNAL("clicked()"), self.previousPhoto) self.groupBoxViewerBtn.setLayout(gridViewerBtnLayout) def createButtonsGridLayout(self): self.groupBoxButtons = QtWidgets.QGroupBox() gridBtnLayout = QtWidgets.QGridLayout() self.btnQuit = QtWidgets.QPushButton("Cancel") self.btnQuit.setFixedSize(150, 23) self.btnSubmit = QtWidgets.QPushButton("OK") self.btnSubmit.setFixedSize(150, 23) gridBtnLayout.addWidget(self.btnSubmit, 0, 0) gridBtnLayout.addWidget(self.btnQuit, 0, 1) self.btnSubmit.setEnabled(False) QtCore.QObject.connect(self.btnQuit, QtCore.SIGNAL( "clicked()"), self, QtCore.SLOT("reject()")) QtCore.QObject.connect( self.btnSubmit, QtCore.SIGNAL("clicked()"), self.adjustChunkPhotos) self.groupBoxButtons.setLayout(gridBtnLayout) def createParamsGridLayout(self): self.groupBoxParams = QtWidgets.QGroupBox('Adjustment parameters') gridParamsLayout = QtWidgets.QGridLayout() gridParamsLayout.setHorizontalSpacing(50) self.label_chunk = QtWidgets.QLabel('Chunk : ') self.chunksBox = QtWidgets.QComboBox() self.chunksBox.resize(200, 23) self.getChunks() for chunk in self.chunks: self.chunksBox.addItem(chunk.label, chunk.key) self.label_brightness = QtWidgets.QLabel('Image brightness (%): ') self.brightness = QtWidgets.QSpinBox() self.brightness.setMaximum(500) self.brightness.setSingleStep(20) self.brightness.setMinimum(0) self.brightness.setValue(100) self.label_contrast = QtWidgets.QLabel('Image contrast (%): ') self.contrast = QtWidgets.QSpinBox() self.contrast.setMaximum(500) self.contrast.setSingleStep(20) self.contrast.setMinimum(0) self.contrast.setValue(100) self.label_folder = QtWidgets.QLabel('Select folder : ') self.btn_select_folder = QtWidgets.QPushButton("Select...") self.btn_select_folder.setFixedSize(150, 23) self.path_label = QtWidgets.QLabel('Selected Path : ...') self.space = QtWidgets.QLabel(' ') self.chunk_create_label = QtWidgets.QLabel("Create new Chunk") self.chkCreateChunk = QtWidgets.QCheckBox() self.chkCreateChunk.setChecked(True) # adding widget gridParamsLayout.addWidget(self.label_chunk, 0, 0) gridParamsLayout.addWidget(self.chunksBox, 0, 1) gridParamsLayout.addWidget(self.label_folder, 0, 2) gridParamsLayout.addWidget(self.btn_select_folder, 0, 3) gridParamsLayout.addWidget(self.label_brightness, 1, 0) gridParamsLayout.addWidget(self.brightness, 1, 1) gridParamsLayout.addWidget(self.path_label, 1, 2) gridParamsLayout.addWidget(self.label_contrast, 2, 0) gridParamsLayout.addWidget(self.contrast, 2, 1) gridParamsLayout.addWidget(self.chunk_create_label, 2, 2) gridParamsLayout.addWidget(self.chkCreateChunk, 2, 3) QtCore.QObject.connect( self.btn_select_folder, QtCore.SIGNAL("clicked()"), self.selectFolder) self.chunksBox.currentIndexChanged.connect(self.getChunk) self.brightness.valueChanged.connect(self.getPixmapFromEnhance) self.contrast.valueChanged.connect(self.getPixmapFromEnhance) self.groupBoxParams.setLayout(gridParamsLayout) def createProgressBar(self): self.groupBoxProgressBar = QtWidgets.QGroupBox() gridProgressBar = QtWidgets.QGridLayout() self.progressBar = QtWidgets.QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) gridProgressBar.addWidget(self.progressBar, 0, 0) self.groupBoxProgressBar.setLayout(gridProgressBar) def zoomIn(self): self.scaleImage(1.25) def zoomOut(self): self.scaleImage(0.8) def normalSize(self): self.imageLabel.adjustSize() self.scaleFactor = 1.0 def scaleImage(self, factor): self.scaleFactor *= factor self.imageLabel.resize( self.scaleFactor * self.imageLabel.pixmap().size()) self.adjustScrollBar(self.scrollArea.horizontalScrollBar(), factor) self.adjustScrollBar(self.scrollArea.verticalScrollBar(), factor) def adjustScrollBar(self, scrollBar, factor): scrollBar.setValue(int(factor * scrollBar.value() + ((factor - 1) * scrollBar.pageStep()/2))) def fitToWindow(self, fitToWindow): self.scrollArea.setWidgetResizable(fitToWindow) if not fitToWindow: self.normalSize() def getChunks(self): self.chunks = Metashape.app.document.chunks if len(self.chunks) == 0: Metashape.app.messageBox('No chunk in project') def getChunk(self): chunk_key = self.chunksBox.currentData() self.chunk = doc.findChunk(chunk_key) self.brightness.setValue(100) self.contrast.setValue(100) self.getPaths() self.getImage(0) def selectFolder(self): directoryPath = QtWidgets.QFileDialog.getExistingDirectory( self, "Select Directory") dossier = directoryPath.split('/')[-1] path = 'Selected Path : {}'.format(directoryPath) self.path_label.setText(path) self.btnSubmit.setEnabled(True) self.path_folder = directoryPath def getPaths(self): self.paths = [] for c in self.chunk.cameras: path = c.photo.path self.paths.append(path) if len(self.paths) == 0: Metashape.app.messageBox('No photos in this chunk') def getImage(self, index): self.path_photo = self.paths[index] self.image = QtGui.QPixmap(self.path_photo) self.imageLabel.setPixmap(self.image) def nextPhoto(self): index = self.paths.index(self.path_photo) if index == len(self.paths) - 1: index = 0 else: index = index + 1 self.path_photo = self.paths[index] self.getPixmapFromEnhance() def previousPhoto(self): index = self.paths.index(self.path_photo) if index == 0: index = len(self.paths) - 1 else: index = index - 1 self.path_photo = self.paths[index] self.getPixmapFromEnhance() def adjustImage(self, image): brghitness = self.brightness.value() / 100 contrast = self.contrast.value() / 100 imageEnhancer = ImageEnhance.Brightness(image) imgBright = imageEnhancer.enhance(brghitness) imageEnhancer = ImageEnhance.Contrast(imgBright) imgContrast = imageEnhancer.enhance(contrast) return imgContrast def getPixmapFromEnhance(self): image = Image.open(self.path_photo) img = self.adjustImage(image) self.image = img.toqimage() self.image = QtGui.QPixmap(self.image) self.imageLabel.setPixmap(self.image) image.close() def get_exif(self, image): exif = image._getexif() return exif def add_new_chunk(self, images): doc = Metashape.app.document new_chunk = doc.addChunk() new_chunk.label = 'Adjusted ' + self.chunk.label new_chunk.addPhotos(images) def copyPhots(self, c): self.i = self.i + 1 self.progressBar.setValue(self.i) source = c.photo.path destination = self.path_folder path_without_drive = os.path.splitdrive(source)[1] subfolder = os.path.splitext(path_without_drive)[0] path_to_photo = os.path.split(path_without_drive)[0] folders = path_to_photo.split('/') path_dist = destination + path_to_photo path_dist = path_dist.replace(self.commun_without_drive, '') try: if not os.path.exists(path_dist): os.makedirs(path_dist) image = Image.open(source) exif = self.get_exif(image) enhancer = self.adjustImage(image) path = path_dist + '/' + c.label + '.jpg' enhancer.save( path, exif=image.info["exif"]) self.imageList.append(path) image.close() except RuntimeError: Metashape.app.messageBox('error') def adjustChunkPhotos(self): print("Import Adjust Photos Script started...") self.imageList = [] commun = os.path.commonpath(self.paths) commun_without_drive = os.path.splitdrive(commun)[1] self.commun_without_drive = commun_without_drive.replace('\\', '/') total = len(self.chunk.cameras) self.progressBar.setMaximum(total) self.i = 0 # with concurrent.futures.ThreadPoolExecutor() as executor: # executor.map(self.copyPhots, self.chunk.cameras) for c in self.chunk.cameras: self.copyPhots(c) QtWidgets.QApplication.processEvents() if self.chkCreateChunk.isChecked(): self.add_new_chunk(self.imageList) self.close() print("Script finished!") # Metashape.app.messageBox('Adjusting and Copy successful !') return True
def executeProject(self, mainWindow, project_name): if project_name == "SmartGroceries": self.referenceItemsLabels = {} self.itemInHand = None self.itemsInCart = list() self.currentOrderReferenceItems = list() self.currentOrderUserId = 0 self.recommendedItemsButtons = list() self.previousRecommendations = list() self.numberOfGoodRecommendations = 0 self.supportedUsers = range(1, 1001) products = pd.read_csv( os.path.join( os.path.dirname(os.path.dirname( os.path.abspath(__file__))), "projects", "SmartGroceries", "data", "products.csv")) aisles = pd.read_csv( os.path.join( os.path.dirname(os.path.dirname( os.path.abspath(__file__))), "projects", "SmartGroceries", "data", "aisles.csv")) test_data = pd.read_csv( os.path.join( os.path.dirname(os.path.dirname( os.path.abspath(__file__))), "projects", "SmartGroceries", "data", "test_set.csv")) # print(products) # print(aisles) # print(test_data) aisle_name_to_id = { k: v for k, v in zip(aisles.aisle, aisles.aisle_id) } product_name_to_id = { k: v for k, v in zip(products.product_name, products.product_id) } product_id_to_name = { k: v for k, v in zip(products.product_id, products.product_name) } def changeCurrentitem(itemName): if itemName == "": self.itemInHand = None currentItemLabel.setText( f"<b>Select an item from the list or from the recommendations</b>s" ) addToCartButton.setEnabled(False) else: self.itemInHand = product_name_to_id[itemName] currentItemLabel.setText(f"Add <b>{itemName}</b> to Cart") addToCartButton.setEnabled(True) addToCartButton.setFocus() def handleNewOrderButtonClicked(): grouped = test_data.groupby('order_id') while True: order_number = random.sample(grouped.indices.keys(), 1)[0] currentOrder = grouped.get_group(order_number) self.currentOrderReferenceItems = currentOrder.product_id.tolist( ) self.currentOrderUserId = currentOrder.user_id.iloc[0] if len( self.currentOrderReferenceItems ) > 1 and self.currentOrderUserId in self.supportedUsers: break print(self.currentOrderReferenceItems) orderInfo = f"<b>Order ID: </b>{currentOrder.order_id.iloc[0]}<br>" orderInfo += f"<b>User ID: </b>{self.currentOrderUserId} | <b>DOW: </b>{calendar.day_name[currentOrder.order_dow.iloc[0]]} | <b>Hour of Day: </b>{currentOrder.order_hour_of_day.iloc[0]} | <b>Number of Items: </b>{len(self.currentOrderReferenceItems)}" orderInfo += "<br><b>Items in the Reference Order:</b>" for widget in self.referenceItemsLabels.values(): item = referenceItemsLayout.itemAt(0) widget.setVisible(False) referenceItemsLayout.removeItem(item) del item self.referenceItemsLabels.clear() currentCartItems.clear() self.itemsInCart.clear() self.previousRecommendations.clear() self.numberOfGoodRecommendations = 0 updateCurrentRecommendations(list()) for product in self.currentOrderReferenceItems: refItemName = product_id_to_name[product] refItemLabel = QPushButton(refItemName) refItemLabel.setContentsMargins(QMargins(0, 0, 0, 0)) refItemLabel.setStyleSheet("Text-align:left") refItemLabel.setFlat(False) refItemLabel.clicked.connect( partial(changeCurrentitem, refItemName)) self.referenceItemsLabels[product] = refItemLabel orderInfoLabel.setText( f"<b>Order Information</b><br>{orderInfo}") for referenceItemLabel in self.referenceItemsLabels.values(): referenceItemsLayout.addWidget(referenceItemLabel) runAutoButton.setFocus() def handleRunAutomatically(): for referenceItemLabel in self.referenceItemsLabels.values(): referenceItemLabel.click() addToCartButton.click() def updateCurrentRecommendations(recommendations): for widget in self.recommendedItemsButtons: item = recommendationsLayout.itemAt(0) widget.setVisible(False) recommendationsLayout.removeItem(item) del item self.recommendedItemsButtons.clear() for product in recommendations: recItemName = product_id_to_name[product] recItemButton = QPushButton(recItemName) recItemButton.setContentsMargins(QMargins(0, 0, 0, 0)) recItemButton.setStyleSheet("Text-align:left;") if product not in self.currentOrderReferenceItems: recItemButton.setFlat(True) recItemButton.clicked.connect( partial(changeCurrentitem, recItemName)) self.recommendedItemsButtons.append(recItemButton) for recItemButton in self.recommendedItemsButtons: recommendationsLayout.addWidget(recItemButton) if len(recommendations) > 0: currentRecommendationsLabel.setVisible(True) else: currentRecommendationsLabel.setVisible(False) self.previousRecommendations += recommendations def handleAddToCartButtonClicked(): print(self.currentOrderReferenceItems) print(self.itemInHand) if self.itemInHand not in self.currentOrderReferenceItems: QMessageBox( QMessageBox.Critical, "Error adding item to cart", "You can only add items that exists in the reference order" ).exec_() return elif self.itemInHand in self.itemsInCart: QMessageBox(QMessageBox.Critical, "Error adding item to cart", "This item is already in the cart").exec_() return self.referenceItemsLabels[self.itemInHand].setFlat(True) self.itemsInCart.append(self.itemInHand) currentCartItems.addItem(product_id_to_name[self.itemInHand]) if self.itemInHand in self.previousRecommendations: self.numberOfGoodRecommendations += 1 self.referenceItemsLabels[self.itemInHand].setStyleSheet( "Text-align:left; background-color:green;") self.referenceItemsLabels[self.itemInHand].setFlat(False) #update recommendations result = self._sendCommand( "PROCESS_PROJECT_GROUP_2", ";".join([ str(self.currentOrderUserId), ",".join([str(x) for x in self.itemsInCart]), ",".join([ str(x) for x in set(self.previousRecommendations) ]) ])) if result == FAILURE_CODE: self.log( "Processing Failed, error getting recommendations from the RPi" ) return else: try: recommendations = [int(id) for id in result.split(',')] except: recommendations = [] updateCurrentRecommendations(recommendations) if len(self.itemsInCart) == len( self.currentOrderReferenceItems): completionMessage = QMessageBox( QMessageBox.Information, "Order Completed", f"Order Completed with {self.numberOfGoodRecommendations} Good Recommendation(s)\nPress New Order to start a new order" ) if self.numberOfGoodRecommendations == 0: completionMessage.setIconPixmap( QPixmap('images/this_is_fine.jpg')) completionMessage.setWindowIcon(appIcon) completionMessage.exec_() newOrderButton.setFocus() def aisleChanged(): aisle_number = aisle_name_to_id[ selectAisleCombobox.currentText()] products_in_aisle = products[ products.aisle_id == aisle_number].product_name.tolist() selectproductCombobox.clear() selectproductCombobox.addItem("") selectproductCombobox.addItems(products_in_aisle) def itemChanged(): current_item = selectproductCombobox.currentText() changeCurrentitem(current_item) dialog = QDialog(mainWindow) appIcon = QIcon("images/this_is_fine.jpg") dialog.setWindowIcon(appIcon) dialog.setMinimumWidth(600) dialog.setWindowTitle("Smart Groceries Demo") layout = QVBoxLayout() newOrderButton = QPushButton("New Order") orderInfoLabel = QLabel() orderInfoLabel.setTextFormat(Qt.RichText) chooseItemLayout = QHBoxLayout() verticalSpacer = QSpacerItem(20, 20) currentCartItems = QListWidget() layoutWidget = QWidget() referenceItemsLayout = QVBoxLayout(layoutWidget) referenceItemsLayout.setSpacing(0) referenceItemsLayout.setMargin(0) scroll = QScrollArea(dialog) scroll.setWidgetResizable(True) scroll.setMinimumHeight(150) scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setWidget(layoutWidget) selectAisleLabel = QLabel("Aisle: ") selectProductLabel = QLabel("Product: ") selectAisleCombobox = QComboBox() selectproductCombobox = QComboBox() chooseItemLayout.addWidget(selectAisleLabel, 0, Qt.AlignLeft) chooseItemLayout.addWidget(selectAisleCombobox, 0, Qt.AlignLeft) chooseItemLayout.addWidget(selectProductLabel, 0, Qt.AlignLeft) chooseItemLayout.addWidget(selectproductCombobox, 0, Qt.AlignLeft) addToCartButton = QPushButton("Add to Cart") currentItemLabel = QLabel() currentItemLabel.setTextFormat(Qt.RichText) if self.itemInHand is None: currentItemLabel.setText( f"<b>Select an item from the list or from the recommendations</b>" ) addToCartButton.setDisabled(True) currentItemLayout = QHBoxLayout() currentItemLayout.addWidget(currentItemLabel) currentItemLayout.addWidget(addToCartButton) recommendationsLayout = QVBoxLayout() recommendationsLayout.setSpacing(0) recommendationsLayout.setMargin(0) newOrderButton.clicked.connect(handleNewOrderButtonClicked) addToCartButton.clicked.connect(handleAddToCartButtonClicked) selectproductCombobox.currentIndexChanged.connect(itemChanged) selectAisleCombobox.currentIndexChanged.connect(aisleChanged) selectAisleCombobox.addItems(aisles.aisle.tolist()) layout.addWidget(newOrderButton) layout.addSpacerItem(verticalSpacer) layout.addWidget(orderInfoLabel) layout.addWidget(scroll) layout.addSpacerItem(verticalSpacer) layout.addLayout(chooseItemLayout) layout.addSpacerItem(verticalSpacer) itemsInTheCartLabel = QLabel("<b>Items in the Cart<b>") layout.addWidget(itemsInTheCartLabel) itemsInTheCartLabel.setTextFormat(Qt.RichText) layout.addWidget(currentCartItems) layout.addSpacerItem(verticalSpacer) currentRecommendationsLabel = QLabel( "<b>Current Recommendations<b>") layout.addWidget(currentRecommendationsLabel) currentRecommendationsLabel.setTextFormat(Qt.RichText) currentRecommendationsLabel.setVisible(False) layout.addLayout(recommendationsLayout) layout.addSpacerItem(verticalSpacer) layout.addLayout(currentItemLayout) runAutoButton = QPushButton("Run and Watch. TRUST ME, IT IS FUN!") layout.addWidget(runAutoButton) runAutoButton.clicked.connect(handleRunAutomatically) dialog.setLayout(layout) handleNewOrderButtonClicked() dialog.exec_() return