def createEditor(self, parent, option, index): """ createEditor edit item at index Args: parent (QWidget): editor parent object option (QStyleOptionViewItem): item options index (QModelIndex): index of item in table Returns: QComboBox: editor is a ComboBox. Defaults to None if no list of items can be made. """ sourceIndex = self.model.mapToSource(index) row = sourceIndex.row() column = sourceIndex.column() status = self.model.sourceModel().dataset[row, column] self.comboItems = _comboBoxItems(status) if self.comboItems: editor = QComboBox(parent) editor.addItems(self.comboItems) editor.currentIndexChanged.connect(self.currentIndexChanged) editor.setEditable(True) editor.lineEdit().setReadOnly(True) editor.lineEdit().setAlignment(Qt.AlignCenter) return editor return None
class mainwidget(QWidget): def __init__(self): QWidget.__init__(self) self.items=0 with open('today_meal.pickle','rb') as f: self._data = pickle.load(f) self.nutrients_df = pd.read_csv('nutrients_table.csv',index_col=0) goal_value = np.load('goal.npy') self.goal_calorie = goal_value[0] self.goal_protein = goal_value[1] self.goal_fat = goal_value[2] self.goal_carbon = goal_value[3] self.total_calorie = 0 self.total_protein = 0 self.total_fat = 0 self.total_carbon = 0 #左側上部(食べたものリスト) self.table = QTableWidget() self.table.setColumnCount(6) self.table.setHorizontalHeaderLabels(['品目','量','カロリー','たんぱく質','脂質','炭水化物']) self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.fill_table() #左側下部(合計値) self.total_indicator = QVBoxLayout() self.tcal_indicator = QHBoxLayout() self.tp_indicator = QHBoxLayout() self.tf_indicator = QHBoxLayout() self.tc_indicator = QHBoxLayout() self.tcal_label = QLabel('カロリー') self.tcal_label.setFont(QtGui.QFont('Arial',20,QtGui.QFont.Black)) self.tcal_value = QLabel('') self.tp_label = QLabel('たんぱく質') self.tp_label.setFont(QtGui.QFont('Arial',20,QtGui.QFont.Black)) self.tp_value = QLabel('') self.tf_label = QLabel('脂質') self.tf_label.setFont(QtGui.QFont('Arial',20,QtGui.QFont.Black)) self.tf_value = QLabel('') self.tc_label = QLabel('炭水化物') self.tc_label.setFont(QtGui.QFont('Arial',20,QtGui.QFont.Black)) self.tc_value = QLabel('') self.tcal_label.setAlignment(Qt.AlignCenter) self.tp_label.setAlignment(Qt.AlignCenter) self.tf_label.setAlignment(Qt.AlignCenter) self.tc_label.setAlignment(Qt.AlignCenter) self.tcal_indicator.addWidget(self.tcal_label,3) self.tcal_indicator.addWidget(self.tcal_value,7) self.tp_indicator.addWidget(self.tp_label,3) self.tp_indicator.addWidget(self.tp_value,7) self.tf_indicator.addWidget(self.tf_label,3) self.tf_indicator.addWidget(self.tf_value,7) self.tc_indicator.addWidget(self.tc_label,3) self.tc_indicator.addWidget(self.tc_value,7) self.total_indicator.addLayout(self.tcal_indicator) self.total_indicator.addLayout(self.tp_indicator) self.total_indicator.addLayout(self.tf_indicator) self.total_indicator.addLayout(self.tc_indicator) self.refresh_total(mode='initialize') #右側 #入力フォーム model = QtGui.QStandardItemModel(self) for elm in self.nutrients_df.index.tolist(): name = QtGui.QStandardItem(elm) model.setItem(model.rowCount(),0,name) self.foodname = QComboBox(self) self.foodname.setLineEdit(QLineEdit()) self.foodname.setCompleter(QCompleter()) self.foodname.setModel(model) self.foodname.completer().setModel(model) self.foodname.lineEdit().setText('') self.foodamount = QLineEdit() #ボタン self.foodname_label = QLabel('品目') self.foodname_label.setFont(QtGui.QFont('Arial',14,QtGui.QFont.Black)) self.foodname_label.setAlignment(Qt.AlignCenter) self.foodamount_label = QLabel('分量') self.foodamount_label.setFont(QtGui.QFont('Arial',14,QtGui.QFont.Black)) self.foodamount_label.setAlignment(Qt.AlignCenter) self.add = QPushButton('+') self.add.setFont(QtGui.QFont('Arial',30,QtGui.QFont.Black)) self.add.clicked.connect(self.add_data) self.delete = QPushButton('末尾のデータを削除') self.delete.setFont(QtGui.QFont('Arial',14,QtGui.QFont.Black)) self.delete.clicked.connect(self.delete_data) self.delete_all = QPushButton('全てのデータを削除') self.delete_all.setFont(QtGui.QFont('Arial',14,QtGui.QFont.Black)) self.delete_all.clicked.connect(self.delete_all_func) # self.plot = QPushButton('プロット') # self.plot.setFont(QtGui.QFont('Arial',26,QtGui.QFont.Black)) # self.plot.clicked.connect(self.plot_data) self.save = QPushButton('保存') self.save.setFont(QtGui.QFont('Arial',14,QtGui.QFont.Black)) # self.save.setStyleSheet('border : 2px solid black;\ # border-radius : 20px;') self.save.clicked.connect(self.save_data) #チャート self.chartview = QtCharts.QChartView() self.chartview.setRenderHint(QPainter.Antialiasing) #ウィジェットの追加 #左側 self.left = QVBoxLayout() self.left.addWidget(self.table,7) self.left.addLayout(self.total_indicator,3) #右側 self.right = QVBoxLayout() self.right.setMargin(10) self.input_form = QHBoxLayout() self.input_form_labels = QVBoxLayout() self.input_form_editor = QVBoxLayout() self.input_form_labels.addWidget(self.foodname_label) self.input_form_labels.addWidget(self.foodamount_label) self.input_form_editor.addWidget(self.foodname) self.input_form_editor.addWidget(self.foodamount) self.input_form.addSpacing(1) self.input_form.addLayout(self.input_form_labels,1) self.input_form.addLayout(self.input_form_editor,5) self.input_form.addWidget(self.add,2) # self.input_form.addWidget(self.plot,1.5) self.input_form.addSpacing(1) self.right.addLayout(self.input_form) self.right.addWidget(self.chartview) self.delete_save_button = QHBoxLayout() self.delete_save_button.addWidget(self.delete) self.delete_save_button.addWidget(self.delete_all) self.delete_save_button.addWidget(self.save) self.right.addLayout(self.delete_save_button) #レイアウト self.layout = QHBoxLayout() self.layout.addLayout(self.left,6) self.layout.addLayout(self.right,4) self.setLayout(self.layout) self.plot_data() @Slot() def add_data(self): ref = self.nutrients_df name = self.foodname.lineEdit().text() amount = float(self.foodamount.text()) self._data.append([name,amount]) self.table.insertRow(self.items) cal = amount*ref.at[name,'calorie'] p = amount*ref.at[name,'protein'] f = amount*ref.at[name,'fat'] c = amount*ref.at[name,'carbon'] self.total_calorie+=cal self.total_protein+=p self.total_fat+=f self.total_carbon+=c name_item = QTableWidgetItem(name) amount_item = QTableWidgetItem(str(amount)) cal_item = QTableWidgetItem(str(int(cal))) p_item = QTableWidgetItem(str(round(p,2))) f_item = QTableWidgetItem(str(round(f,2))) c_item = QTableWidgetItem(str(round(c,2))) name_item.setTextAlignment(Qt.AlignCenter) amount_item.setTextAlignment(Qt.AlignCenter) cal_item.setTextAlignment(Qt.AlignCenter) p_item.setTextAlignment(Qt.AlignCenter) f_item.setTextAlignment(Qt.AlignCenter) c_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(self.items,0,name_item) self.table.setItem(self.items,1,amount_item) self.table.setItem(self.items,2,cal_item) self.table.setItem(self.items,3,p_item) self.table.setItem(self.items,4,f_item) self.table.setItem(self.items,5,c_item) self.foodname.lineEdit().setText(''); self.foodamount.setText('') self.items+=1 self.refresh_total() self.plot_data() @Slot() def delete_all_func(self): self.items=0 self.table.setRowCount(0) self._data = [] self.total_calorie=0; self.total_protein=0 self.total_fat=0; self.total_carbon=0 self.refresh_total() self.plot_data() @Slot() def delete_data(self): self.items-=1 self.table.setRowCount(self.items) name = self._data[-1][0] amount = self._data[-1][1] ref = self.nutrients_df cal = amount*ref.at[name,'calorie'] p = amount*ref.at[name,'protein'] f = amount*ref.at[name,'fat'] c = amount*ref.at[name,'carbon'] self.total_calorie-=cal self.total_protein-=p self.total_fat-=f self.total_carbon-=c self._data.pop(-1) self.refresh_total() self.plot_data() @Slot() def save_data(self): with open('today_meal.pickle','wb') as f: pickle.dump(self._data,f) @Slot() def plot_data(self): presence = QtCharts.QBarSet('現在') goal = QtCharts.QBarSet('目標') presence.append([self.total_calorie/self.goal_calorie,self.total_protein/self.goal_protein,\ self.total_fat/self.goal_fat,self.total_carbon/self.goal_carbon]) goal.append([1,1,1,1]) series = QtCharts.QBarSeries() series.append(presence); series.append(goal) chart = QtCharts.QChart() chart.addSeries(series) chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations) labels = ['カロリー','たんぱく質','脂質','炭水化物'] axisX = QtCharts.QBarCategoryAxis() axisX.append(labels) chart.addAxis(axisX,Qt.AlignBottom) chart.legend().setVisible(True) chart.legend().setFont(QtGui.QFont('Arial',10,QtGui.QFont.Bold)) chart.setTheme(QtCharts.QChart.ChartThemeHighContrast) self.chartview.setChart(chart) @Slot() def refresh_total(self,mode=None): cal_diff = str(round(self.total_calorie-self.goal_calorie,2)) p_diff = str(round(self.total_protein-self.goal_protein,2)) f_diff = str(round(self.total_fat-self.goal_fat,2)) c_diff = str(round(self.total_carbon-self.goal_carbon,2)) if self.total_calorie>self.goal_calorie: cal_diff='+'+cal_diff if self.total_protein>self.goal_protein: p_diff='+'+p_diff if self.total_fat>self.goal_fat: f_diff='+'+f_diff if self.total_carbon>self.goal_carbon: c_diff='+'+c_diff tcal = str(int(self.total_calorie))+' kcal / '+str(self.goal_calorie)+' kcal ('+cal_diff+' kcal)' tp = str(round(self.total_protein,2))+' g / '+str(self.goal_protein)+' g ('+p_diff+' g)' tf = str(round(self.total_fat,2))+' g / '+str(self.goal_fat)+' g ('+f_diff+' g)' tc = str(round(self.total_carbon,2))+' g / '+str(self.goal_carbon)+' g ('+c_diff+' g)' self.tcal_value.setText(tcal) self.tp_value.setText(tp) self.tf_value.setText(tf) self.tc_value.setText(tc) self.tcal_value.setFont(QtGui.QFont('Arial',24,QtGui.QFont.Bold)) self.tp_value.setFont(QtGui.QFont('Arial',24,QtGui.QFont.Bold)) self.tf_value.setFont(QtGui.QFont('Arial',24,QtGui.QFont.Bold)) self.tc_value.setFont(QtGui.QFont('Arial',24,QtGui.QFont.Bold)) self.tcal_value.setAlignment(Qt.AlignCenter) self.tp_value.setAlignment(Qt.AlignCenter) self.tf_value.setAlignment(Qt.AlignCenter) self.tc_value.setAlignment(Qt.AlignCenter) @Slot() def register_food_ok_button(self,name,unit,calorie,protein,fat,carbon): self.nutrients_df.loc[name] = [unit,calorie,protein,fat,carbon] self.nutrients_df.to_csv('nutrients_table.csv') def fill_table(self,data=None): ref = self.nutrients_df data = self._data if not data else data for food in data: cal = food[1]*ref.at[food[0],'calorie'] p = food[1]*ref.at[food[0],'protein'] f = food[1]*ref.at[food[0],'fat'] c = food[1]*ref.at[food[0],'carbon'] self.total_calorie+=cal self.total_protein+=p self.total_fat+=f self.total_carbon+=c name_item = QTableWidgetItem(food[0]) amount_item = QTableWidgetItem(str(food[1])) cal_item = QTableWidgetItem(str(int(cal))) p_item = QTableWidgetItem(str(round(p,2))) f_item = QTableWidgetItem(str(round(f,2))) c_item = QTableWidgetItem(str(round(c,2))) name_item.setTextAlignment(Qt.AlignCenter) amount_item.setTextAlignment(Qt.AlignCenter) cal_item.setTextAlignment(Qt.AlignCenter) p_item.setTextAlignment(Qt.AlignCenter) f_item.setTextAlignment(Qt.AlignCenter) c_item.setTextAlignment(Qt.AlignCenter) self.table.insertRow(self.items) self.table.setItem(self.items,0,name_item) self.table.setItem(self.items,1,amount_item) self.table.setItem(self.items,2,cal_item) self.table.setItem(self.items,3,p_item) self.table.setItem(self.items,4,f_item) self.table.setItem(self.items,5,c_item) self.items+=1
class LocationDialog(QDialog): def __init__(self, parent=None): super(LocationDialog, self).__init__(parent) self.format_combo = QComboBox() self.format_combo.addItem("Native") self.format_combo.addItem("INI") self.scope_cCombo = QComboBox() self.scope_cCombo.addItem("User") self.scope_cCombo.addItem("System") self.organization_combo = QComboBox() self.organization_combo.addItem("Trolltech") self.organization_combo.setEditable(True) self.application_combo = QComboBox() self.application_combo.addItem("Any") self.application_combo.addItem("Application Example") self.application_combo.addItem("Assistant") self.application_combo.addItem("Designer") self.application_combo.addItem("Linguist") self.application_combo.setEditable(True) self.application_combo.setCurrentIndex(3) format_label = QLabel("&Format:") format_label.setBuddy(self.format_combo) scope_label = QLabel("&Scope:") scope_label.setBuddy(self.scope_cCombo) organization_label = QLabel("&Organization:") organization_label.setBuddy(self.organization_combo) application_label = QLabel("&Application:") application_label.setBuddy(self.application_combo) self.locations_groupbox = QGroupBox("Setting Locations") self.locations_table = QTableWidget() self.locations_table.setSelectionMode(QAbstractItemView.SingleSelection) self.locations_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.locations_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.locations_table.setColumnCount(2) self.locations_table.setHorizontalHeaderLabels(("Location", "Access")) self.locations_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.locations_table.horizontalHeader().resizeSection(1, 180) self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.format_combo.activated.connect(self.update_locations) self.scope_cCombo.activated.connect(self.update_locations) self.organization_combo.lineEdit().editingFinished.connect(self.update_locations) self.application_combo.lineEdit().editingFinished.connect(self.update_locations) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) locations_layout = QVBoxLayout(self.locations_groupbox) locations_layout.addWidget(self.locations_table) mainLayout = QGridLayout(self) mainLayout.addWidget(format_label, 0, 0) mainLayout.addWidget(self.format_combo, 0, 1) mainLayout.addWidget(scope_label, 1, 0) mainLayout.addWidget(self.scope_cCombo, 1, 1) mainLayout.addWidget(organization_label, 2, 0) mainLayout.addWidget(self.organization_combo, 2, 1) mainLayout.addWidget(application_label, 3, 0) mainLayout.addWidget(self.application_combo, 3, 1) mainLayout.addWidget(self.locations_groupbox, 4, 0, 1, 2) mainLayout.addWidget(self.button_box, 5, 0, 1, 2) self.update_locations() self.setWindowTitle("Open Application Settings") self.resize(650, 400) def format(self): if self.format_combo.currentIndex() == 0: return QSettings.NativeFormat else: return QSettings.IniFormat def scope(self): if self.scope_cCombo.currentIndex() == 0: return QSettings.UserScope else: return QSettings.SystemScope def organization(self): return self.organization_combo.currentText() def application(self): if self.application_combo.currentText() == "Any": return '' return self.application_combo.currentText() def update_locations(self): self.locations_table.setUpdatesEnabled(False) self.locations_table.setRowCount(0) for i in range(2): if i == 0: if self.scope() == QSettings.SystemScope: continue actualScope = QSettings.UserScope else: actualScope = QSettings.SystemScope for j in range(2): if j == 0: if not self.application(): continue actualApplication = self.application() else: actualApplication = '' settings = QSettings(self.format(), actualScope, self.organization(), actualApplication) row = self.locations_table.rowCount() self.locations_table.setRowCount(row + 1) item0 = QTableWidgetItem() item0.setText(settings.fileName()) item1 = QTableWidgetItem() disable = not (settings.childKeys() or settings.childGroups()) if row == 0: if settings.isWritable(): item1.setText("Read-write") disable = False else: item1.setText("Read-only") self.button_box.button(QDialogButtonBox.Ok).setDisabled(disable) else: item1.setText("Read-only fallback") if disable: item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled) item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled) self.locations_table.setItem(row, 0, item0) self.locations_table.setItem(row, 1, item1) self.locations_table.setUpdatesEnabled(True)