예제 #1
0
파일: nompy.py 프로젝트: nyokinyoki/nompy
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.mainWindow = QtWidgets.QMainWindow
        self.about = AboutWindow()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.actionQuit.triggered.connect(QtCore.QCoreApplication.instance().quit)
        self.ui.actionAbout.triggered.connect(lambda: self.about.exec_())
        self.ui.buttonAddDish.clicked.connect(self.addDish)
        self.ui.buttonAddDish.setEnabled(False)
        self.ui.buttonPlusQty.clicked.connect(self.buttonPlusQtyClicked)
        self.ui.buttonPlusQty.setEnabled(False)
        self.ui.buttonMinusQty.clicked.connect(self.buttonMinusQtyClicked)
        self.ui.buttonMinusQty.setEnabled(False)
        self.ui.buttonRemoveDish.clicked.connect(self.removeDish)
        self.ui.buttonRemoveDish.setEnabled(False)
        self.ui.searchBox.textEdited["QString"].connect(self.search)
        self.ui.dishIngredientTabWidget.currentChanged.connect(self.tabChanged)

        # Fill Dish list with names from dishes.json
        self._translate = QtCore.QCoreApplication.translate
        for self.index, self.dishName in enumerate(nompy_core.getDishNames()):
            self.ui.item = QtWidgets.QListWidgetItem()
            self.ui.dishList.addItem(self.ui.item)
            self.ui.item = self.ui.dishList.item(self.index)
            self.ui.item.setText(self._translate("MainWindow", self.dishName))
        self.ui.dishList.sortItems()
        self.ui.dishList.itemClicked.connect(self.dishListClicked)

        # Fill Ingredient list with names from ingredients.json
        for self.index, self.ingredientName in enumerate(nompy_core.getIngredientNames()):
            self.ui.item = QtWidgets.QListWidgetItem()
            self.ui.ingredientList.addItem(self.ui.item)
            self.ui.item = self.ui.ingredientList.item(self.index)
            self.ui.item.setText(self._translate("MainWindow", self.ingredientName))
        self.ui.ingredientList.sortItems()
        self.ui.ingredientList.itemClicked.connect(self.ingredientListClicked)

        self.ui.dishAddedTable.cellDoubleClicked.connect(self.dishAddedTableDoubleclicked)
        #self.changeQuantity.connect(self.editQuantity)
        self.ui.dishAddedTable.cellClicked.connect(self.dishAddedTableCellClicked)
예제 #2
0
파일: nompy.py 프로젝트: nyokinyoki/nompy
class Interface(QtWidgets.QMainWindow):

    #changeQuantity = QtCore.pyqtSignal(int, int)

    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.mainWindow = QtWidgets.QMainWindow
        self.about = AboutWindow()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.actionQuit.triggered.connect(QtCore.QCoreApplication.instance().quit)
        self.ui.actionAbout.triggered.connect(lambda: self.about.exec_())
        self.ui.buttonAddDish.clicked.connect(self.addDish)
        self.ui.buttonAddDish.setEnabled(False)
        self.ui.buttonPlusQty.clicked.connect(self.buttonPlusQtyClicked)
        self.ui.buttonPlusQty.setEnabled(False)
        self.ui.buttonMinusQty.clicked.connect(self.buttonMinusQtyClicked)
        self.ui.buttonMinusQty.setEnabled(False)
        self.ui.buttonRemoveDish.clicked.connect(self.removeDish)
        self.ui.buttonRemoveDish.setEnabled(False)
        self.ui.searchBox.textEdited["QString"].connect(self.search)
        self.ui.dishIngredientTabWidget.currentChanged.connect(self.tabChanged)

        # Fill Dish list with names from dishes.json
        self._translate = QtCore.QCoreApplication.translate
        for self.index, self.dishName in enumerate(nompy_core.getDishNames()):
            self.ui.item = QtWidgets.QListWidgetItem()
            self.ui.dishList.addItem(self.ui.item)
            self.ui.item = self.ui.dishList.item(self.index)
            self.ui.item.setText(self._translate("MainWindow", self.dishName))
        self.ui.dishList.sortItems()
        self.ui.dishList.itemClicked.connect(self.dishListClicked)

        # Fill Ingredient list with names from ingredients.json
        for self.index, self.ingredientName in enumerate(nompy_core.getIngredientNames()):
            self.ui.item = QtWidgets.QListWidgetItem()
            self.ui.ingredientList.addItem(self.ui.item)
            self.ui.item = self.ui.ingredientList.item(self.index)
            self.ui.item.setText(self._translate("MainWindow", self.ingredientName))
        self.ui.ingredientList.sortItems()
        self.ui.ingredientList.itemClicked.connect(self.ingredientListClicked)

        self.ui.dishAddedTable.cellDoubleClicked.connect(self.dishAddedTableDoubleclicked)
        #self.changeQuantity.connect(self.editQuantity)
        self.ui.dishAddedTable.cellClicked.connect(self.dishAddedTableCellClicked)
        #self.dishAddedTableItemColumnDelegate = dishAddedTableItemDelegate()
        #self.ui.dishAddedTable.setItemDelegateForColumn(1, self.dishAddedTableItemColumnDelegate)


    def tabChanged(self, tabIndex):
        # Dish Tab
        if tabIndex == 0:
            self.ui.buttonAddDish.setText(self._translate("MainWindow", "Add Dish"))
        # Ingredient Tab
        if tabIndex == 1:
            self.ui.buttonAddDish.setText(self._translate("MainWindow", "Add Ingredient"))

    def dishAddedTableCellClicked(self):
        self.ui.buttonRemoveDish.setEnabled(True)
        self.ui.buttonPlusQty.setEnabled(True)
        self.ui.buttonMinusQty.setEnabled(True)

    def dishListClicked(self):
        self.ui.buttonAddDish.setEnabled(True)
        self.clickedDish = nompy_core.Dish(self.ui.dishList.currentItem().text())
        print(self.clickedDish.dishStats)

        # Dish stat output
        self.ui.dishBrowser.setHtml(self._translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">Dish stats</span></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt;\">Calories: " + str(round(self.clickedDish.dishStats["calories"],1)) + "<br>Fat: " + str(round(self.clickedDish.dishStats["fat"],1)) + "<br>Sat. Fat: " + str(round(self.clickedDish.dishStats["saturatedFat"],1)) + "<br>Carbs: " + str(round(self.clickedDish.dishStats["carbs"],1)) + "<br>Fiber: " + str(round(self.clickedDish.dishStats["fiber"],1)) + "<br>Protein: " + str(round(self.clickedDish.dishStats["protein"],1)) + "<br>Salt: " + str(round(self.clickedDish.dishStats["salt"],1)) + "<br>Iron: " + str(round(self.clickedDish.dishStats["iron"],1)) + "</span></p></body></html>"))

    def unitAbbreviation(self):
        self.unitAbbreviationDict = {"gram": "g", "deciliter": "dl", "milliliter": "ml", "piece": "pc"}
        if self.clickedIngredient.stats["unit"] in self.unitAbbreviationDict.keys():
            return str(round(self.clickedIngredient.stats["amount"],1)) + self.unitAbbreviationDict[self.clickedIngredient.stats["unit"]]
        else:
            return str(round(self.clickedIngredient.stats["amount"],1)) + " " + self.clickedIngredient.stats["unit"]


    def ingredientListClicked(self):
        #self.ui.buttonAddDish.setEnabled(True)
        self.clickedIngredient = nompy_core.Ingredient(self.ui.ingredientList.currentItem().text())
        print(self.clickedIngredient.stats)

        unitOutput = self.unitAbbreviation()


        # Ingredient stat output
        self.ui.dishBrowser.setHtml(self._translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">Ingredient stats</span></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt;\">Amount: " + unitOutput + "<br>Calories: " + str(round(self.clickedIngredient.stats["calories"],1)) + "<br>Fat: " + str(round(self.clickedIngredient.stats["fat"],1)) + "<br>Sat. Fat: " + str(round(self.clickedIngredient.stats["saturatedFat"],1)) + "<br>Carbs: " + str(round(self.clickedIngredient.stats["carbs"],1)) + "<br>Fiber: " + str(round(self.clickedIngredient.stats["fiber"],1)) + "<br>Protein: " + str(round(self.clickedIngredient.stats["protein"],1)) + "<br>Salt: " + str(round(self.clickedIngredient.stats["salt"],1)) + "<br>Iron: " + str(round(self.clickedIngredient.stats["iron"],1)) + "</span></p></body></html>"))

    def search(self):
        self.searchString = self.ui.searchBox.text()
        # making the string lowercase for case insensitivity
        self.searchString = self.searchString.lower()
        self.ui.dishList.clear()
        self.ui.buttonAddDish.setEnabled(False)
        # http://stackoverflow.com/questions/4843158/check-if-a-python-list-item-contains-a-string-inside-another-string
        self.matchingDishes = [s for s in nompy_core.getDishNames() if self.searchString in s.lower()]
        self.ui.dishList.addItems(self.matchingDishes)

    def getDishAddedTableItemCoordinates(self, searchString):
        matchingItems = self.ui.dishAddedTable.findItems(searchString, QtCore.Qt.MatchExactly)
        #print(self.ui.dishAddedTable.row(matchingItem))
        #print(self.ui.dishAddedTable.column(matchingItem))
        for item in matchingItems:
            row = self.ui.dishAddedTable.row(item)
            col = self.ui.dishAddedTable.column(item)
        return row, col

    def addDish(self):
        # If the dish is already in dishAddedTable, change its quantity instead
        if self.ui.dishAddedTable.findItems(self.ui.dishList.currentItem().text(), QtCore.Qt.MatchExactly):
            print("Dish already added to table, increasing Quantity instead.")
            self.increaseDishQuantity(self.ui.dishList.currentItem().text())
        else:
            # Add a dish to dishAddedTable
            self.ui.dishAddedTable.setRowCount(self.ui.dishAddedTable.rowCount() + 1)
            # Quantity first
            self.ui.item = QtWidgets.QTableWidgetItem()
            self.ui.item.setText("1x")
            self.ui.item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.ui.dishAddedTable.setItem(self.ui.dishAddedTable.rowCount() -1, 0,  self.ui.item)
            # Dish or ingredient name next
            self.ui.item = QtWidgets.QTableWidgetItem()
            self.ui.item.setText(self.ui.dishList.currentItem().text())
            self.ui.item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsEnabled)
            self.ui.dishAddedTable.setItem(self.ui.dishAddedTable.rowCount() -1, 1, self.ui.item)

        self.calculate()

    def increaseDishQuantity(self, dishName):
        row, col = self.getDishAddedTableItemCoordinates(dishName)
        newQuantity = int(self.numbersOnly(self.ui.dishAddedTable.item(row, col - 1).text()) + 1)
        self.ui.dishAddedTable.item(row, col - 1).setText(str(newQuantity) + "x")

    def decreaseDishQuantity(self, dishName):
        row, col = self.getDishAddedTableItemCoordinates(dishName)
        if int(self.numbersOnly(self.ui.dishAddedTable.item(row, col - 1).text())) == 1:
            self.removeDish()
        else:
            newQuantity = int(self.numbersOnly(self.ui.dishAddedTable.item(row, col - 1).text()) - 1)
            self.ui.dishAddedTable.item(row, col - 1).setText(str(newQuantity) + "x")
            self.calculate()

    def buttonPlusQtyClicked(self):
        self.increaseDishQuantity(self.ui.dishAddedTable.item(self.ui.dishAddedTable.currentRow(), 1).text())
        self.calculate()

    def buttonMinusQtyClicked(self):
        self.decreaseDishQuantity(self.ui.dishAddedTable.item(self.ui.dishAddedTable.currentRow(), 1).text())

    def dishAddedTableDoubleclicked(self, row, col):
        #row = self.ui.dishAddedTable.currentRow()
        #col = self.ui.dishAddedTable.currentCol()
        # When user doubleclicks Qty col
        if col == 0:
            print("User doubleclicked row col.")
            #print(self.ui.dishAddedTable.item(row, col).text() + " new qty value")
            #self.changeQuantity.emit(row, col)
            self.ui.dishAddedTable.cellChanged.connect(self.editQuantity)
        else:
            pass

    def editQuantity(self, row, col):
        self.ui.dishAddedTable.cellChanged.disconnect()
        if self.ui.dishAddedTable.item(row,col).text() == "":
            if self.ui.dishAddedTable.item(row, col + 1).text() in nompy_core.getDishNames():
                self.ui.dishAddedTable.item(row, col).setText("1x")
            else:
                pass
        else:
            # Cleans up everything but digits and dots. TODO: Alert dialogue if it contains more than one dot.
            self.newQuantity = re.sub("[^0123456789\.]", "", self.ui.dishAddedTable.item(row, col).text())
            print("Cleaned up Qty value " + self.ui.dishAddedTable.item(row, col).text() + " to " + self.newQuantity)
            if int(self.newQuantity) > 999:
                # Input greater than 999 will reset the value to 1 to avoid MemoryError
                # TODO: Alert Dialogue
                if self.ui.dishAddedTable.item(row, col + 1).text() in nompy_core.getDishNames():
                    self.ui.dishAddedTable.item(row, col).setText("1x")
                    self.calculate()
                else:
                    pass
            elif self.newQuantity == "0":
                self.removeDish()
            else:
                if self.ui.dishAddedTable.item(row, col + 1).text() in nompy_core.getDishNames():
                    self.ui.dishAddedTable.item(row, col).setText(self.newQuantity + "x")
                    self.calculate()
                else:
                    pass

    def removeDish(self):
        self.ui.dishAddedTable.removeRow(self.ui.dishAddedTable.currentRow())
        if self.ui.dishAddedTable.rowCount() == 0:
            self.ui.buttonRemoveDish.setEnabled(False)
            self.ui.buttonPlusQty.setEnabled(False)
            self.ui.buttonMinusQty.setEnabled(False)
            self.ui.outputBrowser.clear()
        else:
            self.calculate()

    # Cleans up everything but digits and dots. TODO: Alert dialogue if it contains more than one dot.
    def numbersOnly(self, content):
        self.cleanQuantity = float(re.sub("[^0123456789\.]", "", content))
        print("Cleaned up Qty value " + content + " to " + str(self.cleanQuantity) + " in numbersOnly function")
        return self.cleanQuantity

    def calculate(self):
        dishAddedItems = []
        for index in range(self.ui.dishAddedTable.rowCount()):
            if self.numbersOnly(self.ui.dishAddedTable.item(index, 0).text()) == 1:
                dishAddedItems.append(self.ui.dishAddedTable.item(index, 1).text())
            else:
                # TODO: Change this to avoid MemoryError when appending dishes in larger quantities
                # Current workaround this issue is in editQuantity function
                for quantity in range(int(self.numbersOnly(self.ui.dishAddedTable.item(index, 0).text()))):
                    dishAddedItems.append(self.ui.dishAddedTable.item(index, 1).text())
        print(str(dishAddedItems) + " Dishes Added")
        finalSum = nompy_core.getMultipleDishStats(dishAddedItems)

        # Output format
        self.ui.outputBrowser.setHtml(self._translate("MainWindow", "<b>Selected dishes contain:</b>" \
        " <p>Calories: {calories}<br> Fat: {fat}g <br> Saturated Fat: {saturatedFat}g <br>" \
        "Carbohydrates: {carbs}g <br> Fiber: {fiber}g <br> Protein: {protein}g <br> Salt: {salt}g " \
        "<br> Iron: {iron}g </p>".format(calories=str(round(finalSum["calories"],1)), fat=str(round(finalSum["fat"],1)),
        saturatedFat=str(round(finalSum["saturatedFat"],1)), carbs=str(round(finalSum["carbs"],1)),
        fiber=str(round(finalSum["fiber"],1)), protein=str(round(finalSum["protein"],1)),
        salt=str(round(finalSum["salt"],1)), iron=str(round(finalSum["iron"],1)))))