class Window(QWidget): def __init__(self): super().__init__() # Make widgets ################# self.edit1 = QDateEdit() self.edit2 = QDateEdit() self.edit3 = QDateEdit() self.edit1.setMinimumDate(datetime.date(year=2017, month=9, day=1)) self.edit2.setMinimumDate(datetime.date(year=2017, month=9, day=1)) self.edit3.setMinimumDate(datetime.date(year=2017, month=9, day=1)) self.edit1.setMaximumDate(datetime.date(year=2020, month=9, day=1)) self.edit2.setMaximumDate(datetime.date(year=2020, month=9, day=1)) self.edit3.setMaximumDate(datetime.date(year=2020, month=9, day=1)) self.edit1.setDate(datetime.datetime.now().date()) self.edit2.setDate(datetime.datetime.now().date()) self.edit3.setDate(datetime.datetime.now().date()) self.edit1.setCalendarPopup(True) self.edit2.setCalendarPopup(True) self.edit3.setCalendarPopup(True) # Format: see http://doc.qt.io/qt-5/qdatetime.html#toString-2 self.edit1.setDisplayFormat("yyyy-MM-dd") self.edit2.setDisplayFormat("dd/MM/yyyy") self.edit3.setDisplayFormat("dddd d MMMM yyyy") self.btn = QPushButton("Print") # Set button slot ############## self.btn.clicked.connect(self.printText) # Set the layout ############### vbox = QVBoxLayout() vbox.addWidget(self.edit1) vbox.addWidget(self.edit2) vbox.addWidget(self.edit3) vbox.addWidget(self.btn) self.setLayout(vbox) def printText(self): print(self.edit1.text()) print(self.edit2.text()) print(self.edit3.text())
class HydroprintGUI(myqt.DialogWindow): ConsoleSignal = QSignal(str) def __init__(self, datamanager, parent=None): super(HydroprintGUI, self).__init__(parent, maximize=True) self.__updateUI = True # Child widgets: self.dmngr = datamanager self.dmngr.wldsetChanged.connect(self.wldset_changed) self.dmngr.wxdsetChanged.connect(self.wxdset_changed) self.page_setup_win = PageSetupWin(self) self.page_setup_win.newPageSetupSent.connect(self.layout_changed) self.color_palette_win = ColorsSetupWin(self) self.color_palette_win.newColorSetupSent.connect(self.update_colors) # Memory path variable: self.save_fig_dir = self.workdir # Generate UI: self.__initUI__() def __initUI__(self): # ---- Toolbar self.btn_save = btn_save = QToolButtonNormal(icons.get_icon('save')) btn_save.setToolTip('Save the well hydrograph') # btn_draw is usefull for debugging purposes btn_draw = QToolButtonNormal(icons.get_icon('refresh')) btn_draw.setToolTip('Force a refresh of the well hydrograph') btn_draw.hide() self.btn_load_layout = QToolButtonNormal( icons.get_icon('load_graph_config')) self.btn_load_layout.setToolTip( "<p>Load graph layout for the current water level " " datafile if it exists</p>") self.btn_load_layout.clicked.connect(self.load_layout_isClicked) self.btn_save_layout = QToolButtonNormal( icons.get_icon('save_graph_config')) self.btn_save_layout.setToolTip('Save current graph layout') self.btn_save_layout.clicked.connect(self.save_layout_isClicked) btn_bestfit_waterlvl = QToolButtonNormal(icons.get_icon('fit_y')) btn_bestfit_waterlvl.setToolTip('Best fit the water level scale') btn_bestfit_time = QToolButtonNormal(icons.get_icon('fit_x')) btn_bestfit_time.setToolTip('Best fit the time scale') self.btn_page_setup = QToolButtonNormal(icons.get_icon('page_setup')) self.btn_page_setup.setToolTip('Show the page setup window') self.btn_page_setup.clicked.connect(self.page_setup_win.show) btn_color_pick = QToolButtonNormal(icons.get_icon('color_picker')) btn_color_pick.setToolTip('<p>Show a window to setup the color palette' ' used to draw the hydrograph</p.') btn_color_pick.clicked.connect(self.color_palette_win.show) self.btn_language = LangToolButton() self.btn_language.setToolTip( "Set the language of the text shown in the graph.") self.btn_language.sig_lang_changed.connect(self.layout_changed) self.btn_language.setIconSize(icons.get_iconsize('normal')) # ---- Zoom Panel btn_zoom_out = QToolButtonSmall(icons.get_icon('zoom_out')) btn_zoom_out.setToolTip('Zoom out (ctrl + mouse-wheel-down)') btn_zoom_out.clicked.connect(self.zoom_out) btn_zoom_in = QToolButtonSmall(icons.get_icon('zoom_in')) btn_zoom_in.setToolTip('Zoom in (ctrl + mouse-wheel-up)') btn_zoom_in.clicked.connect(self.zoom_in) self.zoom_disp = QSpinBox() self.zoom_disp.setAlignment(Qt.AlignCenter) self.zoom_disp.setButtonSymbols(QAbstractSpinBox.NoButtons) self.zoom_disp.setReadOnly(True) self.zoom_disp.setSuffix(' %') self.zoom_disp.setRange(0, 9999) self.zoom_disp.setValue(100) zoom_pan = myqt.QFrameLayout() zoom_pan.setSpacing(3) zoom_pan.addWidget(btn_zoom_out, 0, 0) zoom_pan.addWidget(btn_zoom_in, 0, 1) zoom_pan.addWidget(self.zoom_disp, 0, 2) # LAYOUT : btn_list = [btn_save, btn_draw, self.btn_load_layout, self.btn_save_layout, VSep(), btn_bestfit_waterlvl, btn_bestfit_time, VSep(), self.btn_page_setup, btn_color_pick, self.btn_language, VSep(), zoom_pan] subgrid_toolbar = QGridLayout() toolbar_widget = QWidget() row = 0 for col, btn in enumerate(btn_list): subgrid_toolbar.addWidget(btn, row, col) subgrid_toolbar.setSpacing(5) subgrid_toolbar.setContentsMargins(0, 0, 0, 0) subgrid_toolbar.setColumnStretch(col + 1, 100) toolbar_widget.setLayout(subgrid_toolbar) # ---- LEFT PANEL # SubGrid Hydrograph Frame : self.hydrograph = hydrograph.Hydrograph() self.hydrograph_scrollarea = mplFigViewer.ImageViewer() self.hydrograph_scrollarea.zoomChanged.connect(self.zoom_disp.setValue) grid_hydrograph = QGridLayout() grid_hydrograph.addWidget(self.hydrograph_scrollarea, 0, 0) grid_hydrograph.setRowStretch(0, 500) grid_hydrograph.setColumnStretch(0, 500) grid_hydrograph.setContentsMargins(0, 0, 0, 0) # (L, T, R, B) # ASSEMBLING SubGrids : grid_layout = QGridLayout() self.grid_layout_widget = QFrame() row = 0 grid_layout.addWidget(toolbar_widget, row, 0) row += 1 grid_layout.addLayout(grid_hydrograph, row, 0) grid_layout.setContentsMargins(0, 0, 0, 0) # (L, T, R, B) grid_layout.setSpacing(5) grid_layout.setColumnStretch(0, 500) grid_layout.setRowStretch(1, 500) self.grid_layout_widget.setLayout(grid_layout) # ---- Right Panel self.tabscales = self.__init_scalesTabWidget__() self.right_panel = myqt.QFrameLayout() self.right_panel.addWidget(self.dmngr, 0, 0) self.right_panel.addWidget(self.tabscales, 1, 0) self.right_panel.setRowStretch(2, 100) self.right_panel.setSpacing(15) # ---- MAIN GRID mainGrid = QGridLayout() mainGrid.addWidget(self.grid_layout_widget, 0, 0) mainGrid.addWidget(VSep(), 0, 1) mainGrid.addWidget(self.right_panel, 0, 2) mainGrid.setContentsMargins(10, 10, 10, 10) # (L, T, R, B) mainGrid.setSpacing(15) mainGrid.setColumnStretch(0, 500) mainGrid.setColumnMinimumWidth(2, 250) self.setLayout(mainGrid) # ---- EVENTS # Toolbox Layout : btn_bestfit_waterlvl.clicked.connect(self.best_fit_waterlvl) btn_bestfit_time.clicked.connect(self.best_fit_time) btn_draw.clicked.connect(self.draw_hydrograph) btn_save.clicked.connect(self.select_save_path) # Hydrograph Layout : self.Ptot_scale.valueChanged.connect(self.layout_changed) self.qweather_bin.currentIndexChanged.connect(self.layout_changed) # ---- Init Image self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def __init_scalesTabWidget__(self): class QRowLayout(QGridLayout): def __init__(self, items, parent=None): super(QRowLayout, self).__init__(parent) for col, item in enumerate(items): self.addWidget(item, 0, col) self.setContentsMargins(0, 0, 0, 0) self.setColumnStretch(0, 100) # ---- Time axis properties # Generate the widgets : self.date_start_widget = QDateEdit() self.date_start_widget.setDisplayFormat('01 / MM / yyyy') self.date_start_widget.setAlignment(Qt.AlignCenter) self.date_start_widget.dateChanged.connect(self.layout_changed) self.date_end_widget = QDateEdit() self.date_end_widget.setDisplayFormat('01 / MM / yyyy') self.date_end_widget.setAlignment(Qt.AlignCenter) self.date_end_widget.dateChanged.connect(self.layout_changed) self.time_scale_label = QComboBox() self.time_scale_label.setEditable(False) self.time_scale_label.setInsertPolicy(QComboBox.NoInsert) self.time_scale_label.addItems(['Month', 'Year']) self.time_scale_label.setCurrentIndex(0) self.time_scale_label.currentIndexChanged.connect(self.layout_changed) self.dateDispFreq_spinBox = QSpinBox() self.dateDispFreq_spinBox.setSingleStep(1) self.dateDispFreq_spinBox.setMinimum(1) self.dateDispFreq_spinBox.setMaximum(100) self.dateDispFreq_spinBox.setValue( self.hydrograph.date_labels_pattern) self.dateDispFreq_spinBox.setAlignment(Qt.AlignCenter) self.dateDispFreq_spinBox.setKeyboardTracking(False) self.dateDispFreq_spinBox.valueChanged.connect(self.layout_changed) # Setting up the layout : widget_time_scale = QFrame() widget_time_scale.setFrameStyle(0) grid_time_scale = QGridLayout() GRID = [[QLabel('From :'), self.date_start_widget], [QLabel('To :'), self.date_end_widget], [QLabel('Scale :'), self.time_scale_label], [QLabel('Date Disp. Pattern:'), self.dateDispFreq_spinBox]] for i, ROW in enumerate(GRID): grid_time_scale.addLayout(QRowLayout(ROW), i, 1) grid_time_scale.setVerticalSpacing(5) grid_time_scale.setContentsMargins(10, 10, 10, 10) widget_time_scale.setLayout(grid_time_scale) # ----- Water level axis properties # Widget : self.waterlvl_scale = QDoubleSpinBox() self.waterlvl_scale.setSingleStep(0.05) self.waterlvl_scale.setMinimum(0.05) self.waterlvl_scale.setSuffix(' m') self.waterlvl_scale.setAlignment(Qt.AlignCenter) self.waterlvl_scale.setKeyboardTracking(False) self.waterlvl_scale.valueChanged.connect(self.layout_changed) self.waterlvl_scale.setFixedWidth(100) self.waterlvl_max = QDoubleSpinBox() self.waterlvl_max.setSingleStep(0.1) self.waterlvl_max.setSuffix(' m') self.waterlvl_max.setAlignment(Qt.AlignCenter) self.waterlvl_max.setMinimum(-1000) self.waterlvl_max.setMaximum(1000) self.waterlvl_max.setKeyboardTracking(False) self.waterlvl_max.valueChanged.connect(self.layout_changed) self.waterlvl_max.setFixedWidth(100) self.NZGridWL_spinBox = QSpinBox() self.NZGridWL_spinBox.setSingleStep(1) self.NZGridWL_spinBox.setMinimum(1) self.NZGridWL_spinBox.setMaximum(50) self.NZGridWL_spinBox.setValue(self.hydrograph.NZGrid) self.NZGridWL_spinBox.setAlignment(Qt.AlignCenter) self.NZGridWL_spinBox.setKeyboardTracking(False) self.NZGridWL_spinBox.valueChanged.connect(self.layout_changed) self.NZGridWL_spinBox.setFixedWidth(100) self.datum_widget = QComboBox() self.datum_widget.addItems(['Ground Surface', 'Sea Level']) self.datum_widget.currentIndexChanged.connect(self.layout_changed) # Layout : subgrid_WLScale = QGridLayout() GRID = [[QLabel('Minimum :'), self.waterlvl_max], [QLabel('Scale :'), self.waterlvl_scale], [QLabel('Grid Divisions :'), self.NZGridWL_spinBox], [QLabel('Datum :'), self.datum_widget]] for i, ROW in enumerate(GRID): subgrid_WLScale.addLayout(QRowLayout(ROW), i, 1) subgrid_WLScale.setVerticalSpacing(5) subgrid_WLScale.setContentsMargins(10, 10, 10, 10) # (L, T, R, B) WLScale_widget = QFrame() WLScale_widget.setFrameStyle(0) WLScale_widget.setLayout(subgrid_WLScale) # ---- Weather Axis # Widgets : self.Ptot_scale = QSpinBox() self.Ptot_scale.setSingleStep(5) self.Ptot_scale.setMinimum(5) self.Ptot_scale.setMaximum(500) self.Ptot_scale.setValue(20) self.Ptot_scale.setSuffix(' mm') self.Ptot_scale.setAlignment(Qt.AlignCenter) self.qweather_bin = QComboBox() self.qweather_bin.setEditable(False) self.qweather_bin.setInsertPolicy(QComboBox.NoInsert) self.qweather_bin.addItems(['day', 'week', 'month']) self.qweather_bin.setCurrentIndex(1) # Layout : layout = QGridLayout() GRID = [[QLabel('Precip. Scale :'), self.Ptot_scale], [QLabel('Resampling :'), self.qweather_bin]] for i, row in enumerate(GRID): layout.addLayout(QRowLayout(row), i, 1) layout.setVerticalSpacing(5) layout.setContentsMargins(10, 10, 10, 10) # (L,T,R,B) layout.setRowStretch(i+1, 100) widget_weather_scale = QFrame() widget_weather_scale.setFrameStyle(0) widget_weather_scale.setLayout(layout) # ---- ASSEMBLING TABS tabscales = QTabWidget() tabscales.addTab(widget_time_scale, 'Time') tabscales.addTab(WLScale_widget, 'Water Level') tabscales.addTab(widget_weather_scale, 'Weather') return tabscales @property def workdir(self): return self.dmngr.workdir # ---- Utilities def zoom_in(self): self.hydrograph_scrollarea.zoomIn() def zoom_out(self): self.hydrograph_scrollarea.zoomOut() def update_colors(self): self.hydrograph.update_colors() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) # ---- Datasets Handlers @property def wldset(self): return self.dmngr.get_current_wldset() @property def wxdset(self): return self.dmngr.get_current_wxdset() def wldset_changed(self): """Handle when the water level dataset of the datamanager changes.""" if self.wldset is None: self.clear_hydrograph() return else: self.hydrograph.set_wldset(self.wldset) self.hydrograph.gluedf = self.wldset.get_glue_at(-1) # Load the manual measurements. fname = os.path.join( self.workdir, "Water Levels", 'waterlvl_manual_measurements') tmeas, wlmeas = load_waterlvl_measures(fname, self.wldset['Well']) self.wldset.set_wlmeas(tmeas, wlmeas) # Setup the layout of the hydrograph. layout = self.wldset.get_layout() if layout is not None: msg = ("Loading existing graph layout for well %s." % self.wldset['Well']) print(msg) self.ConsoleSignal.emit('<font color=black>%s</font>' % msg) self.load_graph_layout(layout) else: print('No graph layout exists for well %s.' % self.wldset['Well']) # Fit Water Level in Layout : self.__updateUI = False self.best_fit_waterlvl() self.best_fit_time() if self.dmngr.set_closest_wxdset() is None: self.draw_hydrograph() self.__updateUI = True def wxdset_changed(self): """Handle when the weather dataset of the datamanager changes.""" if self.wldset is None: self.clear_hydrograph() else: self.hydrograph.set_wxdset(self.wxdset) QCoreApplication.processEvents() self.draw_hydrograph() # ---- Draw Hydrograph Handlers def best_fit_waterlvl(self): wldset = self.dmngr.get_current_wldset() if wldset is not None: WLscale, WLmin = self.hydrograph.best_fit_waterlvl() self.waterlvl_scale.setValue(WLscale) self.waterlvl_max.setValue(WLmin) def best_fit_time(self): wldset = self.dmngr.get_current_wldset() if wldset is not None: date0, date1 = self.hydrograph.best_fit_time(wldset.xldates) self.date_start_widget.setDate(QDate(date0[0], date0[1], date0[2])) self.date_end_widget.setDate(QDate(date1[0], date1[1], date1[2])) @QSlot() def mrc_wl_changed(self): """ Force a redraw of the MRC water levels after the results have changed for the dataset. """ self.hydrograph.draw_mrc_wl() self.hydrograph.setup_legend() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) @QSlot(GLUEDataFrameBase) def glue_wl_changed(self, gluedf): """ Force a redraw of the GLUE water levels after the results have changed for the dataset. """ self.hydrograph.set_gluedf(gluedf) self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def layout_changed(self): """ When an element of the graph layout is changed in the UI. """ if self.__updateUI is False: return self.update_graph_layout_parameter() if self.hydrograph.isHydrographExists is False: return sender = self.sender() if sender == self.btn_language: self.hydrograph.draw_ylabels() self.hydrograph.setup_xticklabels() self.hydrograph.setup_legend() elif sender in [self.waterlvl_max, self.waterlvl_scale]: self.hydrograph.setup_waterlvl_scale() self.hydrograph.draw_ylabels() elif sender == self.NZGridWL_spinBox: self.hydrograph.setup_waterlvl_scale() self.hydrograph.update_precip_scale() self.hydrograph.draw_ylabels() elif sender == self.Ptot_scale: self.hydrograph.update_precip_scale() self.hydrograph.draw_ylabels() elif sender == self.datum_widget: yoffset = int(self.wldset['Elevation']/self.hydrograph.WLscale) yoffset *= self.hydrograph.WLscale self.hydrograph.WLmin = (yoffset - self.hydrograph.WLmin) self.waterlvl_max.blockSignals(True) self.waterlvl_max.setValue(self.hydrograph.WLmin) self.waterlvl_max.blockSignals(False) # This is calculated so that trailing zeros in the altitude of the # well is not carried to the y axis labels, so that they remain a # int multiple of *WLscale*. self.hydrograph.setup_waterlvl_scale() self.hydrograph.draw_waterlvl() self.hydrograph.draw_ylabels() elif sender in [self.date_start_widget, self.date_end_widget]: self.hydrograph.set_time_scale() self.hydrograph.draw_weather() self.hydrograph.draw_figure_title() elif sender == self.dateDispFreq_spinBox: self.hydrograph.set_time_scale() self.hydrograph.setup_xticklabels() elif sender == self.page_setup_win: self.hydrograph.update_fig_size() # Implicitly call : set_margins() # draw_ylabels() # set_time_scale() # draw_figure_title self.hydrograph.draw_waterlvl() self.hydrograph.setup_legend() elif sender == self.qweather_bin: self.hydrograph.resample_bin() self.hydrograph.draw_weather() self.hydrograph.draw_ylabels() elif sender == self.time_scale_label: self.hydrograph.set_time_scale() self.hydrograph.draw_weather() else: print('No action for this widget yet.') # !!!! temporary fix until I can find a better solution !!!! # sender.blockSignals(True) if type(sender) in [QDoubleSpinBox, QSpinBox]: sender.setReadOnly(True) for i in range(10): QCoreApplication.processEvents() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) for i in range(10): QCoreApplication.processEvents() if type(sender) in [QDoubleSpinBox, QSpinBox]: sender.setReadOnly(False) # sender.blockSignals(False) def update_graph_layout_parameter(self): # language : self.hydrograph.language = self.btn_language.language # Scales : self.hydrograph.WLmin = self.waterlvl_max.value() self.hydrograph.WLscale = self.waterlvl_scale.value() self.hydrograph.RAINscale = self.Ptot_scale.value() self.hydrograph.NZGrid = self.NZGridWL_spinBox.value() # WL Datum : self.hydrograph.WLdatum = self.datum_widget.currentIndex() # Dates : self.hydrograph.datemode = self.time_scale_label.currentText() year = self.date_start_widget.date().year() month = self.date_start_widget.date().month() self.hydrograph.TIMEmin = xldate_from_date_tuple((year, month, 1), 0) year = self.date_end_widget.date().year() month = self.date_end_widget.date().month() self.hydrograph.TIMEmax = xldate_from_date_tuple((year, month, 1), 0) self.hydrograph.date_labels_pattern = self.dateDispFreq_spinBox.value() # Page Setup : self.hydrograph.fwidth = self.page_setup_win.pageSize[0] self.hydrograph.fheight = self.page_setup_win.pageSize[1] self.hydrograph.va_ratio = self.page_setup_win.va_ratio self.hydrograph.trend_line = self.page_setup_win.isTrendLine self.hydrograph.isLegend = self.page_setup_win.isLegend self.hydrograph.isGraphTitle = self.page_setup_win.isGraphTitle self.hydrograph.set_meteo_on(self.page_setup_win.is_meteo_on) self.hydrograph.set_glue_wl_on(self.page_setup_win.is_glue_wl_on) self.hydrograph.set_mrc_wl_on(self.page_setup_win.is_mrc_wl_on) self.hydrograph.set_figframe_lw(self.page_setup_win.figframe_lw) # Weather bins : self.hydrograph.bwidth_indx = self.qweather_bin.currentIndex() def clear_hydrograph(self): """Clear the hydrograph figure to show only a blank canvas.""" self.hydrograph.clf() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def draw_hydrograph(self): if self.dmngr.wldataset_count() == 0: msg = 'Please import a valid water level data file first.' self.ConsoleSignal.emit('<font color=red>%s</font>' % msg) self.emit_warning(msg) return self.update_graph_layout_parameter() # Generate and Display Graph : for i in range(5): QCoreApplication.processEvents() QApplication.setOverrideCursor(Qt.WaitCursor) self.hydrograph.set_wldset(self.dmngr.get_current_wldset()) self.hydrograph.set_wxdset(self.dmngr.get_current_wxdset()) self.hydrograph.generate_hydrograph() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) QApplication.restoreOverrideCursor() def select_save_path(self): """ Open a dialog where the user can select a file name to save the hydrograph. """ if self.wldset is None: return ffmat = "*.pdf;;*.svg;;*.png" fname = find_unique_filename(osp.join( self.save_fig_dir, 'hydrograph_%s.pdf' % self.wldset['Well'])) fname, ftype = QFileDialog.getSaveFileName( self, "Save Figure", fname, ffmat) if fname: ftype = ftype.replace('*', '') fname = fname if fname.endswith(ftype) else fname + ftype self.save_fig_dir = os.path.dirname(fname) try: self.save_figure(fname) except PermissionError: msg = "The file is in use by another application or user." QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) self.select_save_path() def save_figure(self, fname): """Save the hydrograph figure in a file.""" self.hydrograph.generate_hydrograph() self.hydrograph.savefig(fname) # ---- Graph Layout Handlers def load_layout_isClicked(self): """Handle when the button to load the graph layout is clicked.""" if self.wldset is None: self.emit_warning( "Please import a valid water level data file first.") return layout = self.wldset.get_layout() if layout is None: self.emit_warning( "No graph layout exists for well %s." % self.wldset['Well']) else: self.load_graph_layout(layout) def load_graph_layout(self, layout): """Load the graph layout into the GUI.""" self.__updateUI = False # Scales : date = layout['TIMEmin'] date = xldate_as_tuple(date, 0) self.date_start_widget.setDate(QDate(date[0], date[1], date[2])) date = layout['TIMEmax'] date = xldate_as_tuple(date, 0) self.date_end_widget.setDate(QDate(date[0], date[1], date[2])) self.dateDispFreq_spinBox.setValue(layout['date_labels_pattern']) self.waterlvl_scale.setValue(layout['WLscale']) self.waterlvl_max.setValue(layout['WLmin']) self.NZGridWL_spinBox.setValue(layout['NZGrid']) self.Ptot_scale.setValue(layout['RAINscale']) x = ['mbgs', 'masl'].index(layout['WLdatum']) self.datum_widget.setCurrentIndex(x) self.qweather_bin.setCurrentIndex(layout['bwidth_indx']) self.time_scale_label.setCurrentIndex( self.time_scale_label.findText(layout['datemode'])) # ---- Language and colors self.btn_language.set_language(layout['language']) self.color_palette_win.load_colors() # ---- Page Setup self.page_setup_win.pageSize = (layout['fwidth'], layout['fheight']) self.page_setup_win.va_ratio = layout['va_ratio'] self.page_setup_win.isLegend = layout['legend_on'] self.page_setup_win.isGraphTitle = layout['title_on'] self.page_setup_win.isTrendLine = layout['trend_line'] self.page_setup_win.is_meteo_on = layout['meteo_on'] self.page_setup_win.is_glue_wl_on = layout['glue_wl_on'] self.page_setup_win.is_mrc_wl_on = layout['mrc_wl_on'] self.page_setup_win.figframe_lw = layout['figframe_lw'] self.page_setup_win.legend_on.set_value(layout['legend_on']) self.page_setup_win.title_on.set_value(layout['title_on']) self.page_setup_win.wltrend_on.set_value(layout['trend_line']) self.page_setup_win.meteo_on.set_value(layout['meteo_on']) self.page_setup_win.glue_wl_on.set_value(layout['glue_wl_on']) self.page_setup_win.mrc_wl_on.set_value(layout['mrc_wl_on']) self.page_setup_win.fframe_lw_widg.setValue(layout['figframe_lw']) self.page_setup_win.fwidth.setValue(layout['fwidth']) self.page_setup_win.fheight.setValue(layout['fheight']) self.page_setup_win.va_ratio_spinBox.setValue(layout['va_ratio']) # Check if Weather Dataset : if layout['wxdset'] in self.dmngr.wxdsets: self.dmngr.set_current_wxdset(layout['wxdset']) else: if self.dmngr.set_closest_wxdset() is None: self.draw_hydrograph() self.__updateUI = True def save_layout_isClicked(self): wldset = self.wldset if wldset is None: self.emit_warning( "Please import a valid water level data file first.") return layout = wldset.get_layout() if layout is not None: msg = ('A graph layout already exists for well %s.Do you want to' ' you want to replace it?') % wldset['Well'] reply = QMessageBox.question(self, 'Save Graph Layout', msg, QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.save_graph_layout() elif reply == QMessageBox.No: msg = "Graph layout not saved for well %s." % wldset['Well'] self.ConsoleSignal.emit('<font color=black>%s' % msg) else: self.save_graph_layout() def save_graph_layout(self): """Save the graph layout in the project hdf5 file.""" print("Saving the graph layout for well %s..." % self.wldset['Well'], end=" ") layout = {'WLmin': self.waterlvl_max.value(), 'WLscale': self.waterlvl_scale.value(), 'RAINscale': self.Ptot_scale.value(), 'fwidth': self.page_setup_win.pageSize[0], 'fheight': self.page_setup_win.pageSize[1], 'va_ratio': self.page_setup_win.va_ratio, 'NZGrid': self.NZGridWL_spinBox.value(), 'bwidth_indx': self.qweather_bin.currentIndex(), 'date_labels_pattern': self.dateDispFreq_spinBox.value(), 'datemode': self.time_scale_label.currentText()} layout['wxdset'] = None if self.wxdset is None else self.wxdset.name year = self.date_start_widget.date().year() month = self.date_start_widget.date().month() layout['TIMEmin'] = xldate_from_date_tuple((year, month, 1), 0) year = self.date_end_widget.date().year() month = self.date_end_widget.date().month() layout['TIMEmax'] = xldate_from_date_tuple((year, month, 1), 0) if self.datum_widget.currentIndex() == 0: layout['WLdatum'] = 'mbgs' else: layout['WLdatum'] = 'masl' # ---- Page Setup layout['title_on'] = bool(self.page_setup_win.isGraphTitle) layout['legend_on'] = bool(self.page_setup_win.isLegend) layout['language'] = self.btn_language.language layout['trend_line'] = bool(self.page_setup_win.isTrendLine) layout['meteo_on'] = bool(self.page_setup_win.is_meteo_on) layout['glue_wl_on'] = bool(self.page_setup_win.is_glue_wl_on) layout['mrc_wl_on'] = bool(self.page_setup_win.is_mrc_wl_on) layout['figframe_lw'] = self.page_setup_win.figframe_lw # Save the colors : cdb = ColorsReader() cdb.load_colors_db() layout['colors'] = cdb.RGB # Save the layout : self.wldset.save_layout(layout) msg = 'Layout saved successfully for well %s.' % self.wldset['Well'] self.ConsoleSignal.emit('<font color=black>%s</font>' % msg) print("done")
def createEditor(self, parent, option, index): editor = QDateEdit(parent=parent) editor.setMinimumDate(datetime.datetime(year=2017, month=9, day=1)) editor.setMaximumDate(datetime.datetime(year=2020, month=9, day=1)) editor.setDisplayFormat("yyyy-MM-dd") editor.setCalendarPopup(True) # setFrame(): tell whether the line edit draws itself with a frame. # If enabled (the default) the line edit draws itself inside a frame, otherwise the line edit draws itself without any frame. editor.setFrame(False) return editor
class Calendar(QWidget): key = 'calendar' showLayout = pyqtSignal(str, str) def __init__(self, parent=None): super(Calendar, self).__init__(parent) self.setWindowIcon(IconPth(32, 'Calendar')) self.layout = QGridLayout() self.buildUI() self.setLayout(self.layout) def buildUI(self): self.createPreviewGroupBox() self.createGeneralOptionsGroupBox() self.createDatesGroupBox() self.createTextFormatsGroupBox() self.layout.addWidget(self.previewGroupBox, 0, 0) self.layout.addWidget(self.generalOptionsGroupBox, 0, 1) self.layout.addWidget(self.datesGroupBox, 1, 0) self.layout.addWidget(self.textFormatsGroupBox, 1, 1) self.applySetting() def localeChanged(self, index): self.calendar.setLocale(self.localeCombo.itemData(index)) def firstDayChanged(self, index): self.calendar.setFirstDayOfWeek( Qt.DayOfWeek(self.firstDayCombo.itemData(index))) def selectionModeChanged(self, index): self.calendar.setSelectionMode( QCalendarWidget.SelectionMode( self.selectionModeCombo.itemData(index))) def horizontalHeaderChanged(self, index): self.calendar.setHorizontalHeaderFormat( QCalendarWidget.HorizontalHeaderFormat( self.horizontalHeaderCombo.itemData(index))) def verticalHeaderChanged(self, index): self.calendar.setVerticalHeaderFormat( QCalendarWidget.VerticalHeaderFormat( self.verticalHeaderCombo.itemData(index))) def selectedDateChanged(self): self.currentDateEdit.setDate(self.calendar.selectedDate()) def minimumDateChanged(self, date): self.calendar.setMinimumDate(date) self.maximumDateEdit.setDate(self.calendar.maximumDate()) def maximumDateChanged(self, date): self.calendar.setMaximumDate(date) self.minimumDateEdit.setDate(self.calendar.minimumDate()) def weekdayFormatChanged(self): format = QTextCharFormat() format.setForeground( Qt.GlobalColor( self.weekdayColorCombo.itemData( self.weekdayColorCombo.currentIndex()))) self.calendar.setWeekdayTextFormat(Qt.Monday, format) self.calendar.setWeekdayTextFormat(Qt.Tuesday, format) self.calendar.setWeekdayTextFormat(Qt.Wednesday, format) self.calendar.setWeekdayTextFormat(Qt.Thursday, format) self.calendar.setWeekdayTextFormat(Qt.Friday, format) def weekendFormatChanged(self): format = QTextCharFormat() format.setForeground( Qt.GlobalColor( self.weekendColorCombo.itemData( self.weekendColorCombo.currentIndex()))) self.calendar.setWeekdayTextFormat(Qt.Saturday, format) self.calendar.setWeekdayTextFormat(Qt.Sunday, format) def reformatHeaders(self): text = self.headerTextFormatCombo.currentText() format = QTextCharFormat() if text == "Bold": format.setFontWeight(QFont.Bold) elif text == "Italic": format.setFontItalic(True) elif text == "Green": format.setForeground(Qt.green) self.calendar.setHeaderTextFormat(format) def reformatCalendarPage(self): if self.firstFridayCheckBox.isChecked(): firstFriday = QDate(self.calendar.yearShown(), self.calendar.monthShown(), 1) while firstFriday.dayOfWeek() != Qt.Friday: firstFriday = firstFriday.addDays(1) firstFridayFormat = QTextCharFormat() firstFridayFormat.setForeground(Qt.blue) self.calendar.setDateTextFormat(firstFriday, firstFridayFormat) # May 1st in Red takes precedence. if self.mayFirstCheckBox.isChecked(): mayFirst = QDate(self.calendar.yearShown(), 5, 1) mayFirstFormat = QTextCharFormat() mayFirstFormat.setForeground(Qt.red) self.calendar.setDateTextFormat(mayFirst, mayFirstFormat) def createPreviewGroupBox(self): self.previewGroupBox = QGroupBox("Preview") self.calendar = QCalendarWidget() self.calendar.setMinimumDate(QDate(1900, 1, 1)) self.calendar.setMaximumDate(QDate(3000, 1, 1)) self.calendar.setGridVisible(True) self.calendar.currentPageChanged.connect(self.reformatCalendarPage) self.previewLayout = QGridLayout() self.previewLayout.addWidget(self.calendar, 0, 0, Qt.AlignCenter) self.previewGroupBox.setLayout(self.previewLayout) def createGeneralOptionsGroupBox(self): self.generalOptionsGroupBox = QGroupBox("General Options") self.localeCombo = QComboBox() curLocaleIndex = -1 lang_country = {} for lid in range(QLocale.C, QLocale.LastLanguage + 1): lang = (QLocale(lid).nativeLanguageName()) country = u' '.join( QLocale(lid).nativeCountryName()).encode('utf-8').strip() lang_country[country] = [lang, lid] lid += 1 countries = sorted(list(set([c for c in lang_country]))) countries.remove(countries[0]) for country in countries: lang = lang_country[country][0] label = "%s - %s" % ( (u' '.join(lang).encode('Utf-8').strip()), country) locale = QLocale(lang_country[country][1]) if self.locale().language() == lang and self.locale().country( ) == country: curLocaleIndex = lang_country[country][1] self.localeCombo.addItem(label, locale) if curLocaleIndex != -1: self.localeCombo.setCurrentIndex(curLocaleIndex) self.localeLabel = QLabel("&Locale") self.localeLabel.setBuddy(self.localeCombo) self.firstDayCombo = QComboBox() self.firstDayCombo.addItem("Sunday", Qt.Sunday) self.firstDayCombo.addItem("Monday", Qt.Monday) self.firstDayCombo.addItem("Tuesday", Qt.Tuesday) self.firstDayCombo.addItem("Wednesday", Qt.Wednesday) self.firstDayCombo.addItem("Thursday", Qt.Thursday) self.firstDayCombo.addItem("Friday", Qt.Friday) self.firstDayCombo.addItem("Saturday", Qt.Saturday) self.firstDayLabel = QLabel("Wee&k starts on:") self.firstDayLabel.setBuddy(self.firstDayCombo) self.selectionModeCombo = QComboBox() self.selectionModeCombo.addItem("Single selection", QCalendarWidget.SingleSelection) self.selectionModeCombo.addItem("None", QCalendarWidget.NoSelection) self.selectionModeLabel = QLabel("&Selection fm:") self.selectionModeLabel.setBuddy(self.selectionModeCombo) self.gridCheckBox = QCheckBox("&Grid") self.gridCheckBox.setChecked(self.calendar.isGridVisible()) self.navigationCheckBox = QCheckBox("&Navigation bar") self.navigationCheckBox.setChecked(True) self.horizontalHeaderCombo = QComboBox() self.horizontalHeaderCombo.addItem( "Single letter day names", QCalendarWidget.SingleLetterDayNames) self.horizontalHeaderCombo.addItem("Short day names", QCalendarWidget.ShortDayNames) self.horizontalHeaderCombo.addItem("Long day names", QCalendarWidget.LongDayNames) self.horizontalHeaderCombo.addItem("None", QCalendarWidget.NoHorizontalHeader) self.horizontalHeaderCombo.setCurrentIndex(1) self.horizontalHeaderLabel = QLabel("&Horizontal header:") self.horizontalHeaderLabel.setBuddy(self.horizontalHeaderCombo) self.verticalHeaderCombo = QComboBox() self.verticalHeaderCombo.addItem("ISO week numbers", QCalendarWidget.ISOWeekNumbers) self.verticalHeaderCombo.addItem("None", QCalendarWidget.NoVerticalHeader) self.verticalHeaderLabel = QLabel("&Vertical header:") self.verticalHeaderLabel.setBuddy(self.verticalHeaderCombo) self.localeCombo.currentIndexChanged.connect(self.localeChanged) self.firstDayCombo.currentIndexChanged.connect(self.firstDayChanged) self.selectionModeCombo.currentIndexChanged.connect( self.selectionModeChanged) self.gridCheckBox.toggled.connect(self.calendar.setGridVisible) self.navigationCheckBox.toggled.connect( self.calendar.setNavigationBarVisible) self.horizontalHeaderCombo.currentIndexChanged.connect( self.horizontalHeaderChanged) self.verticalHeaderCombo.currentIndexChanged.connect( self.verticalHeaderChanged) checkBoxLayout = QHBoxLayout() checkBoxLayout.addWidget(self.gridCheckBox) checkBoxLayout.addStretch() checkBoxLayout.addWidget(self.navigationCheckBox) outerLayout = QGridLayout() outerLayout.addWidget(self.localeLabel, 0, 0, 1, 1) outerLayout.addWidget(self.localeCombo, 0, 1, 1, 1) outerLayout.addWidget(self.firstDayLabel, 1, 0, 1, 1) outerLayout.addWidget(self.firstDayCombo, 1, 1, 1, 1) outerLayout.addWidget(self.selectionModeLabel, 2, 0, 1, 1) outerLayout.addWidget(self.selectionModeCombo, 2, 1, 1, 1) outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) outerLayout.addWidget(self.horizontalHeaderLabel, 5, 0, 1, 1) outerLayout.addWidget(self.horizontalHeaderCombo, 5, 1, 1, 1) outerLayout.addWidget(self.verticalHeaderLabel, 6, 0, 1, 1) outerLayout.addWidget(self.verticalHeaderCombo, 6, 1, 1, 1) self.generalOptionsGroupBox.setLayout(outerLayout) self.firstDayChanged(self.firstDayCombo.currentIndex()) self.selectionModeChanged(self.selectionModeCombo.currentIndex()) self.horizontalHeaderChanged(self.horizontalHeaderCombo.currentIndex()) self.verticalHeaderChanged(self.verticalHeaderCombo.currentIndex()) def createDatesGroupBox(self): self.datesGroupBox = QGroupBox(self.tr("Dates")) self.minimumDateEdit = QDateEdit() self.minimumDateEdit.setDisplayFormat('MMM d yyyy') self.minimumDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.minimumDateEdit.setDate(self.calendar.minimumDate()) self.minimumDateLabel = QLabel("&Minimum Date:") self.minimumDateLabel.setBuddy(self.minimumDateEdit) self.currentDateEdit = QDateEdit() self.currentDateEdit.setDisplayFormat('MMM d yyyy') self.currentDateEdit.setDate(self.calendar.selectedDate()) self.currentDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.currentDateLabel = QLabel("&Current Date:") self.currentDateLabel.setBuddy(self.currentDateEdit) self.maximumDateEdit = QDateEdit() self.maximumDateEdit.setDisplayFormat('MMM d yyyy') self.maximumDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.maximumDateEdit.setDate(self.calendar.maximumDate()) self.maximumDateLabel = QLabel("Ma&ximum Date:") self.maximumDateLabel.setBuddy(self.maximumDateEdit) self.currentDateEdit.dateChanged.connect(self.calendar.setSelectedDate) self.calendar.selectionChanged.connect(self.selectedDateChanged) self.minimumDateEdit.dateChanged.connect(self.minimumDateChanged) self.maximumDateEdit.dateChanged.connect(self.maximumDateChanged) dateBoxLayout = QGridLayout() dateBoxLayout.addWidget(self.currentDateLabel, 1, 0) dateBoxLayout.addWidget(self.currentDateEdit, 1, 1) dateBoxLayout.addWidget(self.minimumDateLabel, 0, 0) dateBoxLayout.addWidget(self.minimumDateEdit, 0, 1) dateBoxLayout.addWidget(self.maximumDateLabel, 2, 0) dateBoxLayout.addWidget(self.maximumDateEdit, 2, 1) dateBoxLayout.setRowStretch(3, 1) self.datesGroupBox.setLayout(dateBoxLayout) def createTextFormatsGroupBox(self): self.textFormatsGroupBox = QGroupBox("Text Formats") self.weekdayColorCombo = self.createColorComboBox() self.weekdayColorCombo.setCurrentIndex( self.weekdayColorCombo.findText("Black")) self.weekdayColorLabel = QLabel("&Weekday color:") self.weekdayColorLabel.setBuddy(self.weekdayColorCombo) self.weekendColorCombo = self.createColorComboBox() self.weekendColorCombo.setCurrentIndex( self.weekendColorCombo.findText("Red")) self.weekendColorLabel = QLabel("Week&end color:") self.weekendColorLabel.setBuddy(self.weekendColorCombo) self.headerTextFormatCombo = QComboBox() self.headerTextFormatCombo.addItem("Bold") self.headerTextFormatCombo.addItem("Italic") self.headerTextFormatCombo.addItem("Plain") self.headerTextFormatLabel = QLabel("&Header text:") self.headerTextFormatLabel.setBuddy(self.headerTextFormatCombo) self.firstFridayCheckBox = QCheckBox("&First Friday in blue") self.mayFirstCheckBox = QCheckBox("May &1 in red") self.weekdayColorCombo.currentIndexChanged.connect( self.weekdayFormatChanged) self.weekendColorCombo.currentIndexChanged.connect( self.weekendFormatChanged) self.headerTextFormatCombo.currentIndexChanged.connect( self.reformatHeaders) self.firstFridayCheckBox.toggled.connect(self.reformatCalendarPage) self.mayFirstCheckBox.toggled.connect(self.reformatCalendarPage) checkBoxLayout = QHBoxLayout() checkBoxLayout.addWidget(self.firstFridayCheckBox) checkBoxLayout.addStretch() checkBoxLayout.addWidget(self.mayFirstCheckBox) outerLayout = QGridLayout() outerLayout.addWidget(self.weekdayColorLabel, 0, 0, 1, 1) outerLayout.addWidget(self.weekdayColorCombo, 0, 1, 1, 1) outerLayout.addWidget(self.weekendColorLabel, 1, 0, 1, 1) outerLayout.addWidget(self.weekendColorCombo, 1, 1, 1, 1) outerLayout.addWidget(self.headerTextFormatLabel, 2, 0, 1, 1) outerLayout.addWidget(self.headerTextFormatCombo, 2, 1, 1, 1) outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) self.textFormatsGroupBox.setLayout(outerLayout) self.weekdayFormatChanged() self.weekendFormatChanged() self.reformatHeaders() self.reformatCalendarPage() def createColorComboBox(self): comboBox = QComboBox() comboBox.addItem("Red", Qt.red) comboBox.addItem("Blue", Qt.blue) comboBox.addItem("Black", Qt.black) comboBox.addItem("Magenta", Qt.magenta) return comboBox def applySetting(self): self.layout.setSpacing(2) self.layout.setSizeConstraint(QLayout.SetFixedSize) self.setSizePolicy(SiPoMin, SiPoMin) def hideEvent(self, event): # self.specs.showState.emit(False) pass def closeEvent(self, event): self.showLayout.emit(self.key, 'hide') event.ignore()
class BuildingServicesClient(QWidget): def __init__(self, parent=None): super(BuildingServicesClient, self).__init__(parent) self.socket = QTcpSocket() self.nextBlockSize = 0 self.request = None roomLabel = QLabel("&Room") self.roomEdit = QLineEdit() roomLabel.setBuddy(self.roomEdit) regex = QRegExp(r"[0-9](?:0[1-9]|[12][0-9]|3[0-4])") self.roomEdit.setValidator(QRegExpValidator(regex, self)) self.roomEdit.setAlignment(Qt.AlignRight | Qt.AlignVCenter) dateLabel = QLabel("&Date") self.dateEdit = QDateEdit() dateLabel.setBuddy(self.dateEdit) self.dateEdit.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.dateEdit.setDate(QDate.currentDate().addDays(1)) self.dateEdit.setDisplayFormat("yyyy-MM-dd") responseLabel = QLabel("Response") self.responseLabel = QLabel() self.responseLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.bookButton = QPushButton("&Book") self.bookButton.setEnabled(False) self.unBookButton = QPushButton("&Unbook") self.unBookButton.setEnabled(False) quitButton = QPushButton("&Quit") if not MAC: self.bookButton.setFocusPolicy(Qt.NoFocus) self.unBookButton.setFocusPolicy(Qt.NoFocus) buttonLayout = QHBoxLayout() buttonLayout.addWidget(self.bookButton) buttonLayout.addWidget(self.unBookButton) buttonLayout.addStretch() buttonLayout.addWidget(quitButton) layout = QGridLayout() layout.addWidget(roomLabel, 0, 0) layout.addWidget(self.roomEdit, 0, 1) layout.addWidget(dateLabel, 0, 2) layout.addWidget(self.dateEdit, 0, 3) layout.addWidget(responseLabel, 1, 0) layout.addWidget(self.responseLabel, 1, 1, 1, 3) layout.addLayout(buttonLayout, 2, 1, 1, 4) self.setLayout(layout) self.socket.connected.connect(self.sendRequest) self.socket.readyRead.connect(self.readResponse) self.socket.disconnected.connect(self.serverHasStopped) #self.connect(self.socket, # SIGNAL("error(QAbstractSocket::SocketError)"), # self.serverHasError) self.socket.error.connect(self.serverHasError) self.roomEdit.textEdited.connect(self.updateUi) self.dateEdit.dateChanged.connect(self.updateUi) self.bookButton.clicked.connect(self.book) self.unBookButton.clicked.connect(self.unBook) quitButton.clicked.connect(self.close) self.setWindowTitle("Building Services") def updateUi(self): enabled = False if (self.roomEdit.text() and self.dateEdit.date() > QDate.currentDate()): enabled = True if self.request is not None: enabled = False self.bookButton.setEnabled(enabled) self.unBookButton.setEnabled(enabled) def closeEvent(self, event): self.socket.close() event.accept() def book(self): self.issueRequest("BOOK", self.roomEdit.text(), self.dateEdit.date()) def unBook(self): self.issueRequest("UNBOOK", self.roomEdit.text(), self.dateEdit.date()) def issueRequest(self, action, room, date): self.request = QByteArray() stream = QDataStream(self.request, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_5_7) stream.writeUInt16(0) stream.writeQString(action) stream.writeQString(room) stream << date stream.device().seek(0) stream.writeUInt16(self.request.size() - SIZEOF_UINT16) #overwrite seek(0) self.updateUi() if self.socket.isOpen(): self.socket.close() self.responseLabel.setText("Connecting to server...") self.socket.connectToHost("localhost", PORT) def sendRequest(self): self.responseLabel.setText("Sending request...") self.nextBlockSize = 0 self.socket.write(self.request) self.request = None def readResponse(self): stream = QDataStream(self.socket) stream.setVersion(QDataStream.Qt_5_7) while True: if self.nextBlockSize == 0: if self.socket.bytesAvailable() < SIZEOF_UINT16: break self.nextBlockSize = stream.readUInt16() if self.socket.bytesAvailable() < self.nextBlockSize: break action = "" room = "" date = QDate() #stream >> action >> room action = stream.readQString() room = stream.readQString() if action != "ERROR": stream >> date if action == "ERROR": msg = "Error: {0}".format(room) elif action == "BOOK": msg = "Booked room {0} for {1}".format( room, date.toString(Qt.ISODate)) elif action == "UNBOOK": msg = "Unbooked room {0} for {1}".format( room, date.toString(Qt.ISODate)) self.responseLabel.setText(msg) self.updateUi() self.nextBlockSize = 0 def serverHasStopped(self): self.responseLabel.setText("Error: Connection closed by server") self.socket.close() def serverHasError(self, error): self.responseLabel.setText("Error: {0}".format( self.socket.errorString())) self.socket.close()
class WidgetGallery(QDialog): def __init__(self, parent=None, submit_icon=None): super(WidgetGallery, self).__init__(parent) appctx = ApplicationContext() spreadsheet_hdl = SpreadsheetHandler() categories = spreadsheet_hdl.read_categories() self.tabsWidget = QTabWidget() # Add 'Expenses' tab to main widget self.createExpensesLayout() self.tabsWidget.addTab(self.expensesWidget, QIcon(appctx.get_resource("submit.ico")), "Expenses") # Add 'Incomes' tab to main widget self.createIncomesLayout() self.tabsWidget.addTab(self.incomesWidget, QIcon(appctx.get_resource("submit.ico")), "Incomes") # Add 'Latest Uploads' tab to main widget self.createLatestUploads() self.tabsWidget.addTab(self.latestUploadsWidget, QIcon(appctx.get_resource("sheets.ico")), "Latest Uploads") # Add 'Spreadsheet Actions' tab to main widget self.createSpreadsheetActionsLayout() self.tabsWidget.addTab(self.spreadsheetActionsWidget, QIcon(appctx.get_resource("sheets.ico")), "Spreadsheet Actions") # Set the current available expenses categories self.addCategories(categories) # Set main window size self.resize(570, 320) self.tabsWidget.currentChanged.connect(self.adjustTabWidgetSize) self.layout = QVBoxLayout() self.layout.addWidget(self.tabsWidget) self.setLayout(self.layout) self.setWindowTitle("Expenses Tracker") QApplication.setStyle(QStyleFactory.create("Fusion")) def createExpensesLayout(self): self.expensesWidget = QWidget() self.expensesWidget.setGeometry(QRect(10, 10, 550, 300)) self.expensesWidget.size = (570, 320) expenseDoubleSpinBox_label = QLabel("Value", self.expensesWidget) expenseDoubleSpinBox_label.setGeometry(QRect(30, 80, 40, 20)) expenseDoubleSpinBox_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.expenseDoubleSpinBox = QDoubleSpinBox(self.expensesWidget) self.expenseDoubleSpinBox.setMaximum(10000) self.expenseDoubleSpinBox.setDecimals(2) self.expenseDoubleSpinBox.setMinimum(0) self.expenseDoubleSpinBox.setGeometry(QRect(10, 100, 80, 20)) expenseDateEdit_label = QLabel("Date", self.expensesWidget) expenseDateEdit_label.setGeometry(QRect(120, 80, 40, 20)) expenseDateEdit_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.expenseDateEdit = QDateEdit(self.expensesWidget) self.expenseDateEdit.setCalendarPopup(True) self.expenseDateEdit.setDisplayFormat("dd/MM/yy") self.expenseDateEdit.setDate(QDate.currentDate()) self.expenseDateEdit.setGeometry(QRect(100, 100, 80, 20)) expenseCategoriesComboBox_label = QLabel("Category", self.expensesWidget) expenseCategoriesComboBox_label.setGeometry(QRect(210, 80, 60, 20)) expenseCategoriesComboBox_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.expenseCategoriesComboBox = QComboBox(self.expensesWidget) self.expenseCategoriesComboBox.setGeometry(QRect(190, 100, 100, 20)) expenseSpecificationLine_label = QLabel("Specification", self.expensesWidget) expenseSpecificationLine_label.setGeometry(QRect(320, 80, 70, 20)) expenseSpecificationLine_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.expenseSpecificationLine = QLineEdit(self.expensesWidget) self.expenseSpecificationLine.setGeometry(QRect(300, 100, 115, 20)) expenseObservationLine_label = QLabel("Observation", self.expensesWidget) expenseObservationLine_label.setGeometry(QRect(440, 80, 80, 20)) expenseObservationLine_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.expenseObservationLine = QLineEdit(self.expensesWidget) self.expenseObservationLine.setGeometry(QRect(420, 100, 115, 20)) self.nonRecurringExpenseBox = QCheckBox("Non-recurring expense", self.expensesWidget) self.nonRecurringExpenseBox.setGeometry(QRect(10, 140, 130, 20)) submitbutton = QPushButton("Submit Expense", self.expensesWidget) submitbutton.clicked.connect(self.submitExpenseButtonClicked) submitbutton.setGeometry(QRect(10, 170, 520, 25)) def createLatestUploads(self): self.latestUploadsWidget = QWidget() self.latestUploadsWidget.setGeometry(QRect(10, 10, 550, 300)) self.latestUploadsWidget.size = (824, 403) # Construct Latest Expenses Group expenses_group = QGroupBox("Latest Expenses", self.latestUploadsWidget) self.expensesTable = QTableWidget(expenses_group) self.expensesTable.setColumnCount(4) self.expensesTable.verticalHeader().setVisible(False) self.expensesTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.expensesTable.setSelectionMode(QAbstractItemView.NoSelection) self.expensesTable.setFixedSize(415, 265) self.expensesTable.setHorizontalHeaderLabels(["Date", "Value", "Category", "Specification"]) self.fillExpensesTableData() update_expenses_table_button = QPushButton("Update Expenses Table") update_expenses_table_button.clicked.connect(self.updateExpensesTableButtonClicked) layout = QVBoxLayout() layout.addWidget(self.expensesTable) layout.addWidget(update_expenses_table_button) expenses_group.setLayout(layout) expenses_group.move(10, 5) expenses_group.setStyleSheet("QGroupBox { font-weight: bold; } ") # Construct Latest Incomes Group incomes_group = QGroupBox("Latest Incomes", self.latestUploadsWidget) self.incomesTable = QTableWidget(incomes_group) self.incomesTable.setColumnCount(3) self.incomesTable.verticalHeader().setVisible(False) self.incomesTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.incomesTable.setSelectionMode(QAbstractItemView.NoSelection) self.incomesTable.setFixedSize(301, 265) self.incomesTable.setHorizontalHeaderLabels(["Date", "Value", "Category"]) self.fillIncomesTableData() update_incomes_table_button = QPushButton("Update Incomes Table") update_incomes_table_button.clicked.connect(self.updateIncomesTableButtonClicked) layout = QVBoxLayout() layout.addWidget(self.incomesTable) layout.addWidget(update_incomes_table_button) incomes_group.setLayout(layout) incomes_group.move(460, 5) incomes_group.setStyleSheet("QGroupBox { font-weight: bold; } ") def createIncomesLayout(self): self.incomesWidget = QWidget() self.incomesWidget.setGeometry(QRect(10, 10, 460, 300)) self.incomesWidget.size = (480, 320) incomesDoubleSpinBox_label = QLabel("Value", self.incomesWidget) incomesDoubleSpinBox_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) incomesDoubleSpinBox_label.setGeometry(QRect(40, 80, 40, 20)) self.incomesDoubleSpinBox = QDoubleSpinBox(self.incomesWidget) self.incomesDoubleSpinBox.setMaximum(10000) self.incomesDoubleSpinBox.setDecimals(2) self.incomesDoubleSpinBox.setMinimum(0) self.incomesDoubleSpinBox.setGeometry(QRect(20, 100, 80, 20)) incomesDateEdit_label = QLabel("Date", self.incomesWidget) incomesDateEdit_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) incomesDateEdit_label.setGeometry(QRect(130, 80, 40, 20)) self.incomesDateEdit = QDateEdit(self.incomesWidget) self.incomesDateEdit.setCalendarPopup(True) self.incomesDateEdit.setDisplayFormat("dd/MM/yy") self.incomesDateEdit.setDate(QDate.currentDate()) self.incomesDateEdit.setGeometry(QRect(110, 100, 80, 20)) incomesSpecificationLine_label = QLabel("Specification", self.incomesWidget) incomesSpecificationLine_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) incomesSpecificationLine_label.setGeometry(QRect(220, 80, 70, 20)) self.incomesSpecificationLine = QLineEdit(self.incomesWidget) self.incomesSpecificationLine.setGeometry(QRect(200, 100, 115, 20)) incomesObservationLine_label = QLabel("Observation", self.incomesWidget) incomesObservationLine_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) incomesObservationLine_label.setGeometry(QRect(340, 80, 80, 20)) self.incomesObservationLine = QLineEdit(self.incomesWidget) self.incomesObservationLine.setGeometry(QRect(320, 100, 115, 20)) submitbutton = QPushButton("Submit Income", self.incomesWidget) submitbutton.setGeometry(QRect(10, 170, 430, 25)) submitbutton.clicked.connect(self.submitIncomeButtonClicked) def createSpreadsheetActionsLayout(self): self.spreadsheetActionsWidget = QWidget() self.spreadsheetActionsWidget.setGeometry(QRect(10, 10, 550, 300)) self.spreadsheetActionsWidget.size = (570, 320) access_spreadsheet_button = QPushButton("Access Spreadsheet", self.spreadsheetActionsWidget) access_spreadsheet_button.clicked.connect(self.accessSpreadsheetButtonClicked) access_spreadsheet_button.setGeometry(QRect(10, 10, 525, 25)) create_and_maintain_button = QPushButton("Create New Spreadsheet Maintaining the Old One", self.spreadsheetActionsWidget) create_and_maintain_button.clicked.connect(self.createAndMaintainButtonClicked) create_and_maintain_button.setGeometry(QRect(10, 40, 525, 25)) create_and_delete_button = QPushButton("Create New Spreadsheet Deleting the Old One", self.spreadsheetActionsWidget) create_and_delete_button.clicked.connect(self.createAndDeleteButtonClicked) create_and_delete_button.setGeometry(QRect(10, 70, 525, 25)) categories_group = QGroupBox("Expenses Categories", self.spreadsheetActionsWidget) categories_group.setGeometry(QRect(10, 110, 525, 140)) categories_group.setStyleSheet("QGroupBox { font-weight: bold; } ") categories_layout = QHBoxLayout() self.addCategoryLine = QLineEdit() add_category_button = QPushButton("Add New Category") add_category_button.clicked.connect(self.addCategoryButtonClicked) self.delCategoryComboBox = QComboBox() del_category_button = QPushButton("Delete Category") del_category_button.clicked.connect(self.delCategoryButtonClicked) add_categories_layout = QVBoxLayout() del_categories_layout = QVBoxLayout() add_categories_layout.addWidget(self.addCategoryLine) add_categories_layout.addWidget(add_category_button) del_categories_layout.addWidget(self.delCategoryComboBox) del_categories_layout.addWidget(del_category_button) add_categories_widget = QWidget() del_categories_widget = QWidget() add_categories_widget.setLayout(add_categories_layout) del_categories_widget.setLayout(del_categories_layout) categories_layout.addWidget(add_categories_widget) categories_layout.addWidget(del_categories_widget) categories_group.setLayout(categories_layout) def fillExpensesTableData(self): latest_expenses = SpreadsheetHandler().get_latest_upload("expenses") self.expensesTable.setRowCount(len(latest_expenses)) for row_index, row in enumerate(latest_expenses): for column_index, cell_content in enumerate(row): self.expensesTable.setItem(row_index, column_index, QTableWidgetItem(cell_content)) def fillIncomesTableData(self): latest_incomes = SpreadsheetHandler().get_latest_upload("incomes") self.incomesTable.setRowCount(len(latest_incomes)) for row_index, row in enumerate(latest_incomes): for column_index, cell_content in enumerate(row): self.incomesTable.setItem(row_index, column_index, QTableWidgetItem(cell_content)) def addCategories(self, new_items): self.expenseCategoriesComboBox.insertItems(0, new_items) self.delCategoryComboBox.insertItems(0, new_items) def resetCategoriesComboBox(self): spreadsheet_hdl = SpreadsheetHandler() categories = spreadsheet_hdl.read_categories() self.expenseCategoriesComboBox.clear() self.delCategoryComboBox.clear() self.addCategories(categories) def submitExpenseButtonClicked(self): spreadsheet_hdl = SpreadsheetHandler() appctx = ApplicationContext() if self.nonRecurringExpenseBox.checkState() == 2: recurring_status = "Non-Recurring" else: recurring_status = "Recurring" data = [ ["=MONTH(\""+self.expenseDateEdit.date().toString("MM/dd/yyyy")+"\")", self.expenseDateEdit.date().toString("MM/dd/yyyy"), str(self.expenseDoubleSpinBox.value()), self.expenseCategoriesComboBox.currentText(), self.expenseSpecificationLine.text(), recurring_status, self.expenseObservationLine.text() ] ] for index in range(len(data[0])): if data[0][index] == "": data[0][index] = "-" spreadsheet_hdl.append_data(data, range="Expenses") spreadsheet_hdl.expenses_sort_by_date() alert = QMessageBox() alert.setWindowTitle("Expense Submitted") alert.setWindowIcon(QIcon(appctx.get_resource("submit.ico"))) alert.setText("The expense was submitted!") alert.exec_() def submitIncomeButtonClicked(self): spreadsheet_hdl = SpreadsheetHandler() appctx = ApplicationContext() data = [ ["=MONTH(\""+self.incomesDateEdit.date().toString("MM/dd/yyyy")+"\")", self.incomesDateEdit.date().toString("MM/dd/yyyy"), str(self.incomesDoubleSpinBox.value()), self.incomesSpecificationLine.text(), self.incomesObservationLine.text() ] ] for index in range(len(data[0])): if data[0][index] == "": data[0][index] = "-" spreadsheet_hdl.append_data(data, range="Incomes") spreadsheet_hdl.income_sort_by_date() alert = QMessageBox() alert.setWindowTitle("Income Submitted") alert.setWindowIcon(QIcon(appctx.get_resource("submit.ico"))) alert.setText("The income was submitted!") alert.exec_() def updateExpensesTableButtonClicked(self): self.expensesTable.clearContents() self.fillExpensesTableData() def updateIncomesTableButtonClicked(self): self.incomesTable.clearContents() self.fillIncomesTableData() def accessSpreadsheetButtonClicked(self): spreadsheet_hdl = SpreadsheetHandler() webbrowser.open("https://docs.google.com/spreadsheets/d/" + spreadsheet_hdl.spreadsheet_id) def createAndMaintainButtonClicked(self): appctx = ApplicationContext() spreadsheet_hdl = SpreadsheetHandler() spreadsheet_hdl.rename_spreadsheet(spreadsheet_hdl.file_name + '_OLD') spreadsheet_hdl.create_spreadsheet() self.resetCategoriesComboBox() alert = QMessageBox() alert.setWindowTitle("Spreadsheet Reset") alert.setWindowIcon(QIcon(appctx.get_resource("sheets.ico"))) alert.setText("A new spreadsheet was created! To access the old " "spreadsheet, look for Expenses Tracker_OLD in your Drive.") alert.exec_() def createAndDeleteButtonClicked(self): appctx = ApplicationContext() alert = QMessageBox() alert.setIcon(QMessageBox.Question) alert.setText("All information present " "on the current spreadsheet " "will be lost. " "Are you sure you wish to continue?") alert.setWindowTitle("Spreadsheet Reset Confirmation") alert.setWindowIcon(QIcon(appctx.get_resource("sheets.ico"))) alert.setStandardButtons(QMessageBox.Yes | QMessageBox.No) alert.setDefaultButton(QMessageBox.No) reply = alert.exec_() if reply == alert.Yes: spreadsheet_hdl = SpreadsheetHandler() spreadsheet_hdl.delete_spreadsheet() spreadsheet_hdl.create_spreadsheet() self.resetCategoriesComboBox() alert = QMessageBox() alert.setWindowTitle("Spreadsheet Reset") alert.setWindowIcon(QIcon(appctx.get_resource("sheets.ico"))) alert.setText("A new spreadsheet was created!") alert.exec_() def addCategoryButtonClicked(self): spreadsheet_hdl = SpreadsheetHandler() appctx = ApplicationContext() new_category = self.addCategoryLine.text() categories = spreadsheet_hdl.read_categories() if new_category in categories: alert = QMessageBox() alert.setWindowTitle("Category Adding") alert.setWindowIcon(QIcon(appctx.get_resource("sheets.ico"))) alert.setText("The category " + new_category + " already exists.") alert.exec_() return spreadsheet_hdl.add_category(new_category) self.resetCategoriesComboBox() alert = QMessageBox() alert.setWindowTitle("Category Adding") alert.setWindowIcon(QIcon(appctx.get_resource("sheets.ico"))) alert.setText("The category " + new_category + " was succesfully added!") alert.exec_() def delCategoryButtonClicked(self): spreadsheet_hdl = SpreadsheetHandler() appctx = ApplicationContext() category_to_be_del = self.delCategoryComboBox.currentText() spreadsheet_hdl.delete_category(category_to_be_del) self.resetCategoriesComboBox() alert = QMessageBox() alert.setWindowTitle("Category Deleting") alert.setWindowIcon(QIcon(appctx.get_resource("sheets.ico"))) alert.setText("The category " + category_to_be_del + " was succesfully deleted!") alert.exec_() def adjustTabWidgetSize(self): current_tab = self.tabsWidget.currentWidget() self.resize(current_tab.size[0], current_tab.size[1])
class finance_entry(QWidget): def __init__(self, home_button: QPushButton, parent=None): super().__init__(parent) intValidator = QIntValidator() self.setStyleSheet(QSS) self.current_pending_months = [] self.current_advance_months = [] self.home_button = home_button # -- LEVEL TWO GRID self.grid = QGridLayout() self.grid.setSpacing(20) self.setLayout(self.grid) # -- CELL ZERO self.receipt_label = QLabel("RECEIPT ID :") self.receipt_label.setWordWrap(True) self.receipt_id = QLabel() self.receipt_id.setStyleSheet("font: bold") self.receipt_id.setAlignment(Qt.AlignCenter) currentMonth = datetime.now().month currentYear = datetime.now().year currentReceipt = db_tools.generate_receipt_id(str(currentMonth), str(currentYear)) self.receipt_id.setText(currentReceipt) # --- self.flat_label = QLabel("FLAT NO. :") self.flat_combo = QComboBox() model = self.flat_combo.model() for flat in flats: model.appendRow(QStandardItem(flat)) self.flat_combo.setStyleSheet( 'text-color: black; selection-background-color: rgb(215,215,215)') self.flat_combo.currentIndexChanged['QString'].connect(self.set_name) # --- self.name_label = QLabel("NAME :") self.name_value = QLabel("Mr D. S. Patil") self.name_value.setFixedWidth(200) # --- self.finance_entry_layout0 = QFormLayout() self.finance_entry_layout0.addRow(self.receipt_label, self.receipt_id) self.finance_entry_layout0.addRow(self.flat_label, self.flat_combo) self.finance_entry_layout0.addRow(self.name_label, self.name_value) self.finance_entry_layout0.setVerticalSpacing(90) # -- CELL ONE self.date_label = QLabel("DATE OF TRANSACTION :") self.date_label.setWordWrap(True) self.date_line = QDateEdit() self.date_line.setCalendarPopup(True) self.date_line.setDate(QDate.currentDate()) self.date_line.setDisplayFormat("dd MMMM, yyyy") self.single_radio = QRadioButton("Single Month") self.multiple_radio = QRadioButton("Multiple Months") self.single_radio.setChecked(True) self.single_radio.toggled.connect( lambda: self.months(button=self.single_radio)) self.multiple_radio.toggled.connect( lambda: self.months(button=self.multiple_radio)) self.finance_entry_layout1_h1 = QHBoxLayout() self.finance_entry_layout1_h1.addWidget(self.date_line) self.finance_entry_layout1_h1.addWidget(self.single_radio) self.finance_entry_layout1_h1.addWidget(self.multiple_radio) self.finance_entry_layout1_h1.setSpacing(90) # --- self.month_label = QLabel("FEES FOR :") self.month_combo = QComboBox() self.set_pending_months() self.month_combo.setStyleSheet( 'text-color: black; selection-background-color: rgb(215,215,215)') # --- self.month_till_label = QLabel("FEES TILL :") self.month_till_label.setAlignment(Qt.AlignCenter) self.month_till_combo = QComboBox() self.set_advance_months() self.month_till_combo.setStyleSheet( 'text-color: black; selection-background-color: rgb(215,215,215)') self.finance_entry_layout1_h2 = QHBoxLayout() self.finance_entry_layout1_h2.addWidget(self.month_combo) self.finance_entry_layout1_h2.addWidget(self.month_till_label) self.finance_entry_layout1_h2.addWidget(self.month_till_combo) self.finance_entry_layout1_h2.setSpacing(90) self.month_till_label.setEnabled(False) self.month_till_combo.setEnabled(False) # --- self.amount_label = QLabel("AMOUNT :") self.amount_label.setAlignment(Qt.AlignCenter) self.amount_line = QLineEdit() self.amount_line.setText("1500") self.amount_line.setValidator(intValidator) # --- self.fine_label = QLabel("FINE :") self.fine_label.setAlignment(Qt.AlignCenter) self.fine_line = QLineEdit() if int(self.date_line.text().split(" ")[0]) <= 5: self.fine_line.setText("0") else: self.fine_line.setText("50") self.fine_line.setValidator(intValidator) self.fine_line.setStyleSheet("border: 1px solid red; color: red") self.finance_entry_layout1_h3 = QHBoxLayout() self.finance_entry_layout1_h3.addWidget(self.amount_line) self.finance_entry_layout1_h3.addWidget(self.fine_label) self.finance_entry_layout1_h3.addWidget(self.fine_line) self.finance_entry_layout1_h3.setSpacing(90) # --- self.finance_entry_layout1 = QFormLayout() self.finance_entry_layout1.addRow(self.date_label, self.finance_entry_layout1_h1) self.finance_entry_layout1.addRow(self.month_label, self.finance_entry_layout1_h2) self.finance_entry_layout1.addRow(self.amount_label, self.finance_entry_layout1_h3) self.finance_entry_layout1.setVerticalSpacing(90) # -- CELL TWO self.mode_label = QLabel("PAYMENT MODE :") self.mode_label.setWordWrap(True) # --- self.mode_combo = QComboBox() self.mode_combo.addItem("Cash") self.mode_combo.addItem("Online Funds Transfer") self.mode_combo.addItem("Cheque") self.mode_combo.setStyleSheet( 'text-color: black; selection-background-color: rgb(215,215,215)') self.mode_combo.currentIndexChanged['QString'].connect( self.mode_selection) # --- self.ref_label = QLabel("REFERENCE ID :") self.ref_label.setWordWrap(True) self.ref_line = QLineEdit() self.ref_label.setDisabled(True) self.ref_line.setDisabled(True) self.total_label = QLabel( f"TOTAL PAYABLE AMOUNT : {int(self.amount_line.text()) + int(self.fine_line.text())}" ) self.total_label.setWordWrap(True) self.total_label.setAlignment(Qt.AlignCenter) self.save_button = QPushButton("SAVE") self.save_button.setStyleSheet("font: bold") self.save_button.clicked.connect(lambda: self.check_form()) self.status = QLabel("Ready") self.status.setStyleSheet("font: 8pt") self.status.setAlignment(Qt.AlignCenter) self.bar = QProgressBar(self) self.bar.setMaximum(100) self.bar.setValue(0) self.bar.setToolTip("Please wait until the process is completed.") # --- self.finance_entry_layout2 = QFormLayout() self.finance_entry_layout2.addRow(self.mode_label, self.mode_combo) self.finance_entry_layout2.addRow(self.ref_label, self.ref_line) self.finance_entry_layout2.addItem(create_spacer_item(w=5, h=30)) self.finance_entry_layout2.addRow(self.total_label) self.finance_entry_layout2.addRow(self.save_button) self.finance_entry_layout2.addRow(self.status) self.finance_entry_layout2.addRow(self.bar) self.finance_entry_layout2.setVerticalSpacing(50) self.finance_entry_group0 = QGroupBox() self.finance_entry_group0.setLayout(self.finance_entry_layout0) self.finance_entry_group1 = QGroupBox() self.finance_entry_group1.setLayout(self.finance_entry_layout1) self.finance_entry_group2 = QGroupBox() self.finance_entry_group2.setLayout(self.finance_entry_layout2) self.finance_entry_group2.setFixedWidth(550) # -- FUNCTIONALITY: self.date_line.dateChanged.connect(lambda: self.set_pending_months( date=str(self.date_line.date().toPyDate()))) self.month_combo.currentIndexChanged['QString'].connect( self.set_advance_months) self.month_combo.currentIndexChanged['QString'].connect( lambda ind: self.calculate_fine('from', ind)) self.month_till_combo.currentIndexChanged['QString'].connect( lambda ind: self.calculate_fine('till', ind)) self.month_combo.currentTextChanged.connect(self.calculate_amount) self.month_till_combo.currentTextChanged.connect(self.calculate_amount) self.amount_line.textChanged.connect(self.set_total) self.fine_line.textChanged.connect(self.set_total) # -- FINANCE ENTRY GRID self.grid.addWidget(self.finance_entry_group0, 0, 0, 2, 1) self.grid.addWidget(self.finance_entry_group1, 0, 1, 2, 1) self.grid.addWidget(self.finance_entry_group2, 0, 2, 2, 1) def months(self, button): if button.isChecked(): if button.text() == "Single Month": self.month_till_label.setEnabled(False) self.month_till_combo.setEnabled(False) elif button.text() == "Multiple Months": self.month_till_label.setEnabled(True) self.month_till_combo.setEnabled(True) self.calculate_amount() def mode_selection(self, selection): if selection == "Cash": self.ref_label.setText("REFERENCE ID :") self.ref_label.setDisabled(True) self.ref_line.setDisabled(True) elif selection == "Cheque": self.ref_label.setText("CHEQUE NO. :") self.ref_label.setDisabled(False) self.ref_line.setDisabled(False) elif selection == "Online Funds Transfer": self.ref_label.setText("REFERENCE ID :") self.ref_label.setDisabled(False) self.ref_line.setDisabled(False) def check_form(self): reply = QMessageBox() if len(self.amount_line.text()) == 0: reply.setIcon(QMessageBox.Warning) reply.setText("AMOUNTS field cannot be left empty.") reply.setStandardButtons(QMessageBox.Retry) reply.setWindowTitle("INVALID ENTRY") reply.exec_() elif len(self.fine_line.text()) == 0: reply.setIcon(QMessageBox.Warning) reply.setText("FINE field cannot be left empty.") reply.setStandardButtons(QMessageBox.Retry) reply.setWindowTitle("INVALID ENTRY") reply.exec_() elif self.ref_line.isEnabled() and len(self.ref_line.text()) == 0: reply.setIcon(QMessageBox.Warning) reply.setText( "Please enter the REFERENCE INFORMATION for the transaction.") reply.setStandardButtons(QMessageBox.Retry) reply.setWindowTitle("INVALID ENTRY") reply.exec_() elif payment_exists(flat=self.flat_combo.currentText(), month=self.month_combo.currentText()): reply.setIcon(QMessageBox.Warning) reply.setText( f"This member ({self.flat_combo.currentText()}) has already paid the fees for the month of {self.month_combo.currentText()}" ) reply.setStandardButtons(QMessageBox.Retry) reply.setWindowTitle("INVALID ENTRY") reply.exec_() else: if self.month_till_combo.isEnabled(): fee_till = f" - {self.month_till_combo.currentText()}" else: fee_till = '' if self.ref_line.isEnabled(): ref = f" - ({self.ref_line.text()})" else: ref = '' detailed_text = f"Date : {fix_date(str(self.date_line.date().toPyDate()))}\n" \ f"Fee for : {str(self.month_combo.currentText())}{fee_till}\n" \ f"Flat No : {str(self.flat_combo.currentText())}\n" \ f"Amount : {float(self.amount_line.text())}\n" \ f"Fine : {float(self.fine_line.text())}\n" \ f" -> TOTAL : {str(int(self.amount_line.text()) + int(self.fine_line.text()))} <-\n" \ f"Payment Mode : {str(self.mode_combo.currentText())}{ref}" reply.setWindowTitle("SUCCESSFUL ENTRY") reply.setIcon(QMessageBox.Information) reply.setText("ENTRY HAS BEEN RECORDED.\n") reply.setInformativeText("Please confirm the details below.") reply.setDetailedText(detailed_text) confirm_button = reply.addButton('Confirm', QMessageBox.AcceptRole) edit_button = reply.addButton('Edit', QMessageBox.RejectRole) confirm_button.clicked.connect( lambda: self.final_clicked(button=confirm_button)) edit_button.clicked.connect( lambda: self.final_clicked(button=edit_button)) reply.exec_() def set_name(self, flat): name = get_name(flat) self.name_value.setText(str(name)) def add_entry(self): receipt_id = self.receipt_id.text() date = str(self.date_line.date().toPyDate()) fee_month = self.month_combo.currentText() if self.month_till_combo.isEnabled(): fee_till = self.month_till_combo.currentText() month = f"{fee_month}-{fee_till}" else: fee_till = '' month = fee_month flat = str(self.flat_combo.currentText()) amount = float(self.amount_line.text()) fine = float(self.fine_line.text()) mode = str(self.mode_combo.currentText()) if self.ref_line.isEnabled(): ref = self.ref_line.text() else: ref = '' print(fee_month) new_receipt = receipt.receipt(date=fix_date(date), flat=flat, month=fee_month, month_till=fee_till, amount=amount, fine=fine, mode=mode, ref=ref) self.disable() self.total_label.setText( "Confirming.. PLEASE DO NOT PERFORM ANY OTHER OPERATIONS.") new_receipt.add_to_db() self.status.setText("Adding to databse & Generating receipt") self.bar.setValue(40) design_receipt(receipt_id=f"0{receipt_id}") self.status.setText( "Sending the receipt to the member. (Depends on your internet connection)" ) self.bar.setValue(75) email_status = send_receipt(flat=flat, month=month) self.enable() self.set_total() if email_status: self.bar.setValue(100) else: reply = QMessageBox() reply.setIcon(QMessageBox.Warning) reply.setText( "The system cannot access the internet. Make sure you have an active connection, or any firewall" "feature blocking the access.") reply.setStandardButtons(QMessageBox.Retry) reply.setWindowTitle("INTERNET") reply.exec_() def final_clicked(self, button): if button.text() == "Confirm": self.add_entry() currentReceipt = db_tools.generate_receipt_id( str(datetime.now().month), str(datetime.now().year)) self.receipt_id.setText(currentReceipt) self.flat_combo.setCurrentIndex(0) self.name_value.setText("Mr D. S. Patil") self.amount_line.setText('1500') if int(self.date_line.text().split(" ")[0]) <= 5: self.fine_line.setText("0") else: self.fine_line.setText("50") self.bar.setValue(0) self.status.setText("Done !") self.ref_line.clear() def set_pending_months(self, date: str = None): if date is None: date = str(self.date_line.date().toPyDate()) months = calculate_months(month=date, pending=True, advance=False) self.current_pending_months = months self.month_combo.clear() model = self.month_combo.model() for month in months: model.appendRow(QStandardItem(month)) def set_advance_months(self, date: str = None): if date is None or date == '': date = fix_date_back(self.current_pending_months[0]) else: date = fix_date_back(date) months = calculate_months(month=date, pending=False, advance=True) self.current_advance_months = months self.month_till_combo.clear() model = self.month_till_combo.model() for month in months: model.appendRow(QStandardItem(month)) def calculate_amount(self): if self.month_combo.count() == 0 or self.month_till_combo.count() == 0: self.amount_line.setText('0') return else: all_possible_months = self.current_advance_months.copy() all_possible_months = all_possible_months[::-1] all_possible_months.extend([ x for x in self.current_pending_months if x not in self.current_advance_months ]) if self.month_till_combo.isEnabled(): from_index = all_possible_months.index( self.month_combo.currentText()) till_index = all_possible_months.index( self.month_till_combo.currentText()) amount = (from_index - till_index + 1) * 1500 else: amount = 1500 self.amount_line.setText(str(amount)) self.amount_line.setToolTip(f"Total months : {amount//1500}") def calculate_fine(self, from_where: str, month): if month == '' and self.month_combo.count( ) == 0 or self.month_till_combo.count() == 0: self.fine_line.setText('0') return else: if self.month_till_combo.isEnabled(): try: till_index = self.current_pending_months.index( str(self.month_till_combo.currentText())) except ValueError: till_index = 0 else: try: till_index = self.current_pending_months.index( str(self.month_combo.currentText())) except ValueError: self.fine_line.setText('0') return try: from_index = self.current_pending_months.index( str(self.month_combo.currentText())) except ValueError: self.fine_line.setText('0') return all_fine_months = [] for month in self.current_pending_months[till_index:from_index + 1]: all_fine_months.append([month]) transact_date = str(self.date_line.date().toPyDate()) total_fine = 0 for month in all_fine_months: fine = calculate_fine(month=month[0], transact_date=fix_date(transact_date)) month = month.append(fine) total_fine += fine * 50 self.fine_line.setText(str(total_fine)) self.set_fine_tip(all_fine_months=all_fine_months) def set_fine_tip(self, all_fine_months: list): tool_line = '' for month in all_fine_months: tool_line += f"{month[0]} x {month[1]}\n" self.fine_line.setToolTip(tool_line) def set_total(self): if len(self.amount_line.text()) > 0: amount = float(self.amount_line.text()) else: amount = 0 if len(self.fine_line.text()) > 0: fine = int(self.fine_line.text()) else: fine = 0 self.total_label.setText(f"TOTAL PAYABLE AMOUNT : {amount + fine}") def disable(self): self.finance_entry_group0.setEnabled(False) self.finance_entry_group1.setEnabled(False) self.home_button.setEnabled(False) self.mode_label.setEnabled(False) self.mode_combo.setEnabled(False) self.ref_label.setEnabled(False) self.ref_line.setEnabled(False) self.save_button.setEnabled(False) def enable(self): self.finance_entry_group0.setEnabled(True) self.finance_entry_group1.setEnabled(True) self.home_button.setEnabled(True) self.home_button.setEnabled(True) self.mode_label.setEnabled(True) self.mode_combo.setEnabled(True) self.ref_label.setEnabled(True) self.ref_line.setEnabled(True) self.save_button.setEnabled(True)
class comic_meta_data_editor(QDialog): configGroup = "ComicsProjectManagementTools" # Translatable genre dictionary that has it's translated entries added to the genrelist and from which the untranslated items are taken. acbfGenreList = { "science_fiction": str(i18n("Science Fiction")), "fantasy": str(i18n("Fantasy")), "adventure": str(i18n("Adventure")), "horror": str(i18n("Horror")), "mystery": str(i18n("Mystery")), "crime": str(i18n("Crime")), "military": str(i18n("Military")), "real_life": str(i18n("Real Life")), "superhero": str(i18n("Superhero")), "humor": str(i18n("Humor")), "western": str(i18n("Western")), "manga": str(i18n("Manga")), "politics": str(i18n("Politics")), "caricature": str(i18n("Caricature")), "sports": str(i18n("Sports")), "history": str(i18n("History")), "biography": str(i18n("Biography")), "education": str(i18n("Education")), "computer": str(i18n("Computer")), "religion": str(i18n("Religion")), "romance": str(i18n("Romance")), "children": str(i18n("Children")), "non-fiction": str(i18n("Non Fiction")), "adult": str(i18n("Adult")), "alternative": str(i18n("Alternative")), "other": str(i18n("Other")) } acbfAuthorRolesList = { "Writer": str(i18n("Writer")), "Adapter": str(i18n("Adapter")), "Artist": str(i18n("Artist")), "Penciller": str(i18n("Penciller")), "Inker": str(i18n("Inker")), "Colorist": str(i18n("Colorist")), "Letterer": str(i18n("Letterer")), "Cover Artist": str(i18n("Cover Artist")), "Photographer": str(i18n("Photographer")), "Editor": str(i18n("Editor")), "Assistant Editor": str(i18n("Assistant Editor")), "Translator": str(i18n("Translator")), "Other": str(i18n("Other")) } def __init__(self): super().__init__() # Get the keys for the autocompletion. self.genreKeysList = [] self.characterKeysList = [] self.ratingKeysList = {} self.formatKeysList = [] self.otherKeysList = [] self.authorRoleList = [] for g in self.acbfGenreList.values(): self.genreKeysList.append(g) for r in self.acbfAuthorRolesList.values(): self.authorRoleList.append(r) mainP = Path(os.path.abspath(__file__)).parent self.get_auto_completion_keys(mainP) extraKeyP = Path(QDir.homePath()) / Application.readSetting( self.configGroup, "extraKeysLocation", str()) self.get_auto_completion_keys(extraKeyP) # Setup the dialog. self.setLayout(QVBoxLayout()) mainWidget = QTabWidget() self.layout().addWidget(mainWidget) self.setWindowTitle(i18n("Comic Metadata")) buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.layout().addWidget(buttons) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) # Title, concept, summary, genre, characters, format, rating, language, series, other keywords metadataPage = QWidget() mformLayout = QFormLayout() metadataPage.setLayout(mformLayout) self.lnTitle = QLineEdit() self.lnTitle.setToolTip(i18n("The proper title of the comic.")) self.teSummary = QPlainTextEdit() self.teSummary.setToolTip( i18n("What will you tell others to entice them to read your comic?" )) self.lnGenre = QLineEdit() genreCompletion = multi_entry_completer() genreCompletion.setModel(QStringListModel(self.genreKeysList)) self.lnGenre.setCompleter(genreCompletion) genreCompletion.setCaseSensitivity(False) self.lnGenre.setToolTip( i18n( "The genre of the work. Prefilled values are from the ACBF, but you can fill in your own. Separate genres with commas. Try to limit the amount to about two or three" )) self.lnCharacters = QLineEdit() characterCompletion = multi_entry_completer() characterCompletion.setModel(QStringListModel(self.characterKeysList)) characterCompletion.setCaseSensitivity(False) characterCompletion.setFilterMode( Qt.MatchContains ) # So that if there is a list of names with last names, people can type in a last name. self.lnCharacters.setCompleter(characterCompletion) self.lnCharacters.setToolTip( i18n( "The names of the characters that this comic revolves around. Comma-separated." )) self.lnFormat = QLineEdit() formatCompletion = multi_entry_completer() formatCompletion.setModel(QStringListModel(self.formatKeysList)) formatCompletion.setCaseSensitivity(False) self.lnFormat.setCompleter(formatCompletion) ratingLayout = QHBoxLayout() self.cmbRatingSystem = QComboBox() self.cmbRatingSystem.addItems(self.ratingKeysList.keys()) self.cmbRatingSystem.setEditable(True) self.cmbRating = QComboBox() self.cmbRating.setEditable(True) self.cmbRatingSystem.currentIndexChanged.connect( self.slot_refill_ratings) ratingLayout.addWidget(self.cmbRatingSystem) ratingLayout.addWidget(self.cmbRating) self.lnSeriesName = QLineEdit() self.lnSeriesName.setToolTip( i18n( "If this is part of a series, enter the name of the series and the number." )) self.spnSeriesNumber = QSpinBox() self.spnSeriesNumber.setPrefix("No. ") self.spnSeriesVol = QSpinBox() self.spnSeriesVol.setPrefix("Vol. ") seriesLayout = QHBoxLayout() seriesLayout.addWidget(self.lnSeriesName) seriesLayout.addWidget(self.spnSeriesVol) seriesLayout.addWidget(self.spnSeriesNumber) otherCompletion = multi_entry_completer() otherCompletion.setModel(QStringListModel(self.otherKeysList)) otherCompletion.setCaseSensitivity(False) otherCompletion.setFilterMode(Qt.MatchContains) self.lnOtherKeywords = QLineEdit() self.lnOtherKeywords.setCompleter(otherCompletion) self.lnOtherKeywords.setToolTip( i18n( "Other keywords that don't fit in the previously mentioned sets. As always, comma-separated" )) self.cmbLanguage = language_combo_box() self.cmbReadingMode = QComboBox() self.cmbReadingMode.addItem(i18n("Left to Right")) self.cmbReadingMode.addItem(i18n("Right to Left")) self.cmbCoverPage = QComboBox() self.cmbCoverPage.setToolTip( i18n( "Which page is the cover page? This will be empty if there's no pages." )) mformLayout.addRow(i18n("Title:"), self.lnTitle) mformLayout.addRow(i18n("Cover Page:"), self.cmbCoverPage) mformLayout.addRow(i18n("Summary:"), self.teSummary) mformLayout.addRow(i18n("Language:"), self.cmbLanguage) mformLayout.addRow(i18n("Reading Direction:"), self.cmbReadingMode) mformLayout.addRow(i18n("Genre:"), self.lnGenre) mformLayout.addRow(i18n("Characters:"), self.lnCharacters) mformLayout.addRow(i18n("Format:"), self.lnFormat) mformLayout.addRow(i18n("Rating:"), ratingLayout) mformLayout.addRow(i18n("Series:"), seriesLayout) mformLayout.addRow(i18n("Other:"), self.lnOtherKeywords) mainWidget.addTab(metadataPage, i18n("Work")) # The page for the authors. authorPage = QWidget() authorPage.setLayout(QVBoxLayout()) explanation = QLabel( i18n( "The following is a table of the authors that contributed to this comic. You can set their nickname, proper names (first, middle, last), Role (Penciller, Inker, etc), email and homepage." )) explanation.setWordWrap(True) self.authorModel = QStandardItemModel(0, 7) labels = [ i18n("Nick Name"), i18n("Given Name"), i18n("Middle Name"), i18n("Family Name"), i18n("Role"), i18n("Email"), i18n("Homepage"), i18n("Language") ] self.authorModel.setHorizontalHeaderLabels(labels) self.authorTable = QTableView() self.authorTable.setModel(self.authorModel) self.authorTable.verticalHeader().setDragEnabled(True) self.authorTable.verticalHeader().setDropIndicatorShown(True) self.authorTable.verticalHeader().setSectionsMovable(True) self.authorTable.verticalHeader().sectionMoved.connect( self.slot_reset_author_row_visual) delegate = author_delegate() delegate.setCompleterData(self.authorRoleList, 4) delegate.setLanguageData(len(labels) - 1) self.authorTable.setItemDelegate(delegate) author_button_layout = QWidget() author_button_layout.setLayout(QHBoxLayout()) btn_add_author = QPushButton(i18n("Add Author")) btn_add_author.clicked.connect(self.slot_add_author) btn_remove_author = QPushButton(i18n("Remove Author")) btn_remove_author.clicked.connect(self.slot_remove_author) author_button_layout.layout().addWidget(btn_add_author) author_button_layout.layout().addWidget(btn_remove_author) authorPage.layout().addWidget(explanation) authorPage.layout().addWidget(self.authorTable) authorPage.layout().addWidget(author_button_layout) mainWidget.addTab(authorPage, i18n("Authors")) # The page with publisher information. publisherPage = QWidget() publisherLayout = QFormLayout() publisherPage.setLayout(publisherLayout) self.publisherName = QLineEdit() self.publisherName.setToolTip( i18n( "The name of the company, group or person who is responsible for the final version the reader gets." )) publishDateLayout = QHBoxLayout() self.publishDate = QDateEdit() self.publishDate.setDisplayFormat(QLocale().system().dateFormat()) currentDate = QPushButton(i18n("Set Today")) currentDate.setToolTip( i18n("Sets the publish date to the current date.")) currentDate.clicked.connect(self.slot_set_date) publishDateLayout.addWidget(self.publishDate) publishDateLayout.addWidget(currentDate) self.publishCity = QLineEdit() self.publishCity.setToolTip( i18n( "Traditional publishers are always mentioned in source with the city they are located." )) self.isbn = QLineEdit() self.license = license_combo_box( ) # Maybe ought to make this a QLineEdit... self.license.setEditable(True) self.license.completer().setCompletionMode(QCompleter.PopupCompletion) publisherLayout.addRow(i18n("Name:"), self.publisherName) publisherLayout.addRow(i18n("City:"), self.publishCity) publisherLayout.addRow(i18n("Date:"), publishDateLayout) publisherLayout.addRow(i18n("ISBN:"), self.isbn) publisherLayout.addRow(i18n("License:"), self.license) mainWidget.addTab(publisherPage, i18n("Publisher")) """ Ensure that the drag and drop of authors doesn't mess up the labels. """ def slot_reset_author_row_visual(self): headerLabelList = [] for i in range(self.authorTable.verticalHeader().count()): headerLabelList.append(str(i)) for i in range(self.authorTable.verticalHeader().count()): logicalI = self.authorTable.verticalHeader().logicalIndex(i) headerLabelList[logicalI] = str(i + 1) self.authorModel.setVerticalHeaderLabels(headerLabelList) """ Set the publish date to the current date. """ def slot_set_date(self): self.publishDate.setDate(QDate().currentDate()) """ Append keys to autocompletion lists from the directory mainP. """ def get_auto_completion_keys(self, mainP=Path()): genre = Path(mainP / "key_genre") characters = Path(mainP / "key_characters") rating = Path(mainP / "key_rating") format = Path(mainP / "key_format") keywords = Path(mainP / "key_other") authorRole = Path(mainP / "key_author_roles") if genre.exists(): for t in list(genre.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.genreKeysList: self.genreKeysList.append(str(l).strip("\n")) file.close() if characters.exists(): for t in list(characters.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.characterKeysList: self.characterKeysList.append(str(l).strip("\n")) file.close() if format.exists(): for t in list(format.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.formatKeysList: self.formatKeysList.append(str(l).strip("\n")) file.close() if rating.exists(): for t in list(rating.glob('**/*.csv')): file = open(str(t), "r", newline="", encoding="utf-8") ratings = csv.reader(file) title = os.path.basename(str(t)) r = 0 for row in ratings: listItem = [] if r is 0: title = row[1] else: listItem = self.ratingKeysList[title] item = [] item.append(row[0]) item.append(row[1]) listItem.append(item) self.ratingKeysList[title] = listItem r += 1 file.close() if keywords.exists(): for t in list(keywords.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.otherKeysList: self.otherKeysList.append(str(l).strip("\n")) file.close() if authorRole.exists(): for t in list(authorRole.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.authorRoleList: self.authorRoleList.append(str(l).strip("\n")) file.close() """ Refill the ratings box. This is called whenever the rating system changes. """ def slot_refill_ratings(self): if self.cmbRatingSystem.currentText() in self.ratingKeysList.keys(): self.cmbRating.clear() model = QStandardItemModel() for i in self.ratingKeysList[self.cmbRatingSystem.currentText()]: item = QStandardItem() item.setText(i[0]) item.setToolTip(i[1]) model.appendRow(item) self.cmbRating.setModel(model) """ Add an author with default values initialised. """ def slot_add_author(self): listItems = [] listItems.append(QStandardItem(i18n("Anon"))) # Nick name listItems.append(QStandardItem(i18n("John"))) # First name listItems.append(QStandardItem()) # Middle name listItems.append(QStandardItem(i18n("Doe"))) # Last name listItems.append(QStandardItem()) # role listItems.append(QStandardItem()) # email listItems.append(QStandardItem()) # homepage language = QLocale.system().name().split("_")[0] if language == "C": language = "en" listItems.append(QStandardItem(language)) # Language self.authorModel.appendRow(listItems) """ Remove the selected author from the author list. """ def slot_remove_author(self): self.authorModel.removeRow(self.authorTable.currentIndex().row()) """ Load the UI values from the config dictionary given. """ def setConfig(self, config): if "title" in config.keys(): self.lnTitle.setText(config["title"]) self.teSummary.clear() if "pages" in config.keys(): self.cmbCoverPage.clear() for page in config["pages"]: self.cmbCoverPage.addItem(page) if "cover" in config.keys(): if config["cover"] in config["pages"]: self.cmbCoverPage.setCurrentText(config["cover"]) if "summary" in config.keys(): self.teSummary.appendPlainText(config["summary"]) if "genre" in config.keys(): genreList = [] for genre in config["genre"]: if genre in self.acbfGenreList.keys(): genreList.append(self.acbfGenreList[genre]) else: genreList.append(genre) self.lnGenre.setText(", ".join(genreList)) if "characters" in config.keys(): self.lnCharacters.setText(", ".join(config["characters"])) if "format" in config.keys(): self.lnFormat.setText(", ".join(config["format"])) if "rating" in config.keys(): self.cmbRating.setCurrentText(config["rating"]) else: self.cmbRating.setCurrentText("") if "ratingSystem" in config.keys(): self.cmbRatingSystem.setCurrentText(config["ratingSystem"]) else: self.cmbRatingSystem.setCurrentText("") if "otherKeywords" in config.keys(): self.lnOtherKeywords.setText(", ".join(config["otherKeywords"])) if "seriesName" in config.keys(): self.lnSeriesName.setText(config["seriesName"]) if "seriesVolume" in config.keys(): self.spnSeriesVol.setValue(config["seriesVolume"]) if "seriesNumber" in config.keys(): self.spnSeriesNumber.setValue(config["seriesNumber"]) if "language" in config.keys(): code = config["language"] if "_" in code: code = code.split("_")[0] self.cmbLanguage.setEntryToCode(code) if "readingDirection" in config.keys(): if config["readingDirection"] is "leftToRight": self.cmbReadingMode.setCurrentIndex(0) else: self.cmbReadingMode.setCurrentIndex(1) else: self.cmbReadingMode.setCurrentIndex( QLocale( self.cmbLanguage.codeForCurrentEntry()).textDirection()) if "publisherName" in config.keys(): self.publisherName.setText(config["publisherName"]) if "publisherCity" in config.keys(): self.publishCity.setText(config["publisherCity"]) if "publishingDate" in config.keys(): self.publishDate.setDate( QDate.fromString(config["publishingDate"], Qt.ISODate)) if "isbn-number" in config.keys(): self.isbn.setText(config["isbn-number"]) if "license" in config.keys(): self.license.setCurrentText(config["license"]) else: self.license.setCurrentText( "" ) # I would like to keep it ambiguous whether the artist has thought about the license or not. if "authorList" in config.keys(): authorList = config["authorList"] for i in range(len(authorList)): author = authorList[i] if len(author.keys()) > 0: listItems = [] authorNickName = QStandardItem() if "nickname" in author.keys(): authorNickName.setText(author["nickname"]) listItems.append(authorNickName) authorFirstName = QStandardItem() if "first-name" in author.keys(): authorFirstName.setText(author["first-name"]) listItems.append(authorFirstName) authorMiddleName = QStandardItem() if "initials" in author.keys(): authorMiddleName.setText(author["initials"]) listItems.append(authorMiddleName) authorLastName = QStandardItem() if "last-name" in author.keys(): authorLastName.setText(author["last-name"]) listItems.append(authorLastName) authorRole = QStandardItem() if "role" in author.keys(): role = author["role"] if author["role"] in self.acbfAuthorRolesList.keys(): role = self.acbfAuthorRolesList[author["role"]] authorRole.setText(role) listItems.append(authorRole) authorEMail = QStandardItem() if "email" in author.keys(): authorEMail.setText(author["email"]) listItems.append(authorEMail) authorHomePage = QStandardItem() if "homepage" in author.keys(): authorHomePage.setText(author["homepage"]) listItems.append(authorHomePage) authorLanguage = QStandardItem() if "language" in author.keys(): authorLanguage.setText(author["language"]) pass listItems.append(authorLanguage) self.authorModel.appendRow(listItems) else: self.slot_add_author() """ Store the GUI values into the config dictionary given. @return the config diactionary filled with new values. """ def getConfig(self, config): text = self.lnTitle.text() if len(text) > 0 and text.isspace() is False: config["title"] = text elif "title" in config.keys(): config.pop("title") config["cover"] = self.cmbCoverPage.currentText() listkeys = self.lnGenre.text() if len(listkeys) > 0 and listkeys.isspace() is False: genreList = [] for genre in self.lnGenre.text().split(", "): if genre in self.acbfGenreList.values(): i = list(self.acbfGenreList.values()).index(genre) genreList.append(list(self.acbfGenreList.keys())[i]) else: genreList.append(genre) config["genre"] = genreList elif "genre" in config.keys(): config.pop("genre") listkeys = self.lnCharacters.text() if len(listkeys) > 0 and listkeys.isspace() is False: config["characters"] = self.lnCharacters.text().split(", ") elif "characters" in config.keys(): config.pop("characters") listkeys = self.lnFormat.text() if len(listkeys) > 0 and listkeys.isspace() is False: config["format"] = self.lnFormat.text().split(", ") elif "format" in config.keys(): config.pop("format") config["ratingSystem"] = self.cmbRatingSystem.currentText() config["rating"] = self.cmbRating.currentText() listkeys = self.lnOtherKeywords.text() if len(listkeys) > 0 and listkeys.isspace() is False: config["otherKeywords"] = self.lnOtherKeywords.text().split(", ") elif "characters" in config.keys(): config.pop("otherKeywords") text = self.teSummary.toPlainText() if len(text) > 0 and text.isspace() is False: config["summary"] = text elif "summary" in config.keys(): config.pop("summary") if len(self.lnSeriesName.text()) > 0: config["seriesName"] = self.lnSeriesName.text() config["seriesNumber"] = self.spnSeriesNumber.value() if self.spnSeriesVol.value() > 0: config["seriesVolume"] = self.spnSeriesVol.value() config["language"] = str(self.cmbLanguage.codeForCurrentEntry()) if self.cmbReadingMode is Qt.LeftToRight: config["readingDirection"] = "leftToRight" else: config["readingDirection"] = "rightToLeft" authorList = [] for row in range(self.authorTable.verticalHeader().count()): logicalIndex = self.authorTable.verticalHeader().logicalIndex(row) listEntries = [ "nickname", "first-name", "initials", "last-name", "role", "email", "homepage", "language" ] author = {} for i in range(len(listEntries)): entry = self.authorModel.data( self.authorModel.index(logicalIndex, i)) if entry is None: entry = " " if entry.isspace() is False and len(entry) > 0: if listEntries[i] == "role": if entry in self.acbfAuthorRolesList.values(): entryI = list( self.acbfAuthorRolesList.values()).index(entry) entry = list( self.acbfAuthorRolesList.keys())[entryI] author[listEntries[i]] = entry elif listEntries[i] in author.keys(): author.pop(listEntries[i]) authorList.append(author) config["authorList"] = authorList config["publisherName"] = self.publisherName.text() config["publisherCity"] = self.publishCity.text() config["publishingDate"] = self.publishDate.date().toString(Qt.ISODate) config["isbn-number"] = self.isbn.text() config["license"] = self.license.currentText() return config
class IPFDSNWidget(QWidget): sigTracesReplaced = pyqtSignal(obspy.core.stream.Stream, obspy.core.inventory.inventory.Inventory) sigTracesAppended = pyqtSignal(obspy.core.stream.Stream, obspy.core.inventory.inventory.Inventory) stream = None inventory = None def __init__(self, parent=None): super().__init__() self.parent = parent # this is for managing the event populated form elements # self.eventInfoPopulated = False # self.currentEvent = None self.__buildUI__() self.show() def __buildUI__(self): # Put together the options container gridLayout = QGridLayout() optionsContainer = QWidget() optionsContainer.setLayout(gridLayout) # First lets populate the client drop down self.cb = QComboBox() label_service_name = QLabel(self.tr('Service:')) fdsn_dictionary = URL_MAPPINGS fdsn_dictionary.update( {'RaspShake': 'https://fdsnws.rasberryshakedata.com'}) for key in sorted(URL_MAPPINGS.keys()): self.cb.addItem(key) self.cb.setCurrentText('IRIS') self.cb.currentIndexChanged[str].connect(self.onActivated_cb) validator = IPValidator(self) label_network_name = QLabel(self.tr('Network: ')) self.networkNameBox = QLineEdit() self.networkNameBox.setToolTip( 'Wildcards OK \nCan be SEED network codes or data center defined codes. \nMultiple codes are comma-separated (e.g. "IU,TA").' ) self.networkNameBox.setValidator(validator) label_station_name = QLabel(self.tr('Station: ')) self.stationNameBox = QLineEdit() self.stationNameBox.setToolTip( 'Wildcards OK \nOne or more SEED station codes. \nMultiple codes are comma-separated (e.g. "ANMO,PFO")' ) self.stationNameBox.setValidator(validator) label_location_str = QLabel(self.tr('Location:')) self.location_Box = QLineEdit('*') self.location_Box.setToolTip( 'Wildcards OK \nOne or more SEED location identifiers. \nMultiple identifiers are comma-separated (e.g. "00,01"). \nAs a special case “--“ (two dashes) will be translated to a string of two space characters to match blank location IDs.' ) self.location_Box.setValidator(validator) label_channel_str = QLabel(self.tr('Channel:')) self.channel_Box = QLineEdit('*') self.channel_Box.setToolTip( 'Wildcards OK \nOne or more SEED channel codes. \nMultiple codes are comma-separated (e.g. "BHZ,HHZ")' ) self.channel_Box.setValidator(validator) label_startDate = QLabel(self.tr('Start Date (UTC):')) self.startDate_edit = QDateEdit() self.startDate_edit.setMinimumDate(QDate(1900, 1, 1)) self.startDate_edit.setDisplayFormat('yyyy-MM-dd') self.startDate_edit.setDate(self.startDate_edit.minimumDate()) label_startTime = QLabel(self.tr('Start Time (UTC):')) self.startTime_edit = QTimeEdit() self.startTime_edit.setDisplayFormat('HH:mm:ss.zzz') label_traceLength = QLabel(self.tr('Trace Length (s)')) self.traceLength_t = QSpinBox() self.traceLength_t.setMinimum(1) self.traceLength_t.setMaximum(999999999) self.traceLength_t.setValue(3600) replaceWaveButton = QPushButton('Replace') replaceWaveButton.clicked.connect(self.onClicked_replace) appendWaveButton = QPushButton('Append') appendWaveButton.clicked.connect(self.onClicked_append) self.stationListWidget = QListWidget() self.stationListWidget.setSelectionMode( QAbstractItemView.ExtendedSelection) self.stationListWidget.itemSelectionChanged.connect( self.populateStationInfoFromStationList) self.browserButton = QPushButton('Station Browser') self.browserButton.clicked.connect(self.onClicked_browserButton) gridLayout.addWidget(label_service_name, 0, 0) gridLayout.addWidget(self.cb, 0, 1) gridLayout.addWidget(label_network_name, 1, 0) gridLayout.addWidget(self.networkNameBox, 1, 1) gridLayout.addWidget(label_station_name, 2, 0) gridLayout.addWidget(self.stationNameBox, 2, 1) gridLayout.addWidget(label_location_str, 3, 0) gridLayout.addWidget(self.location_Box, 3, 1) gridLayout.addWidget(label_channel_str, 4, 0) gridLayout.addWidget(self.channel_Box, 4, 1) gridLayout.addWidget(label_startDate, 5, 0) gridLayout.addWidget(self.startDate_edit, 5, 1) gridLayout.addWidget(label_startTime, 6, 0) gridLayout.addWidget(self.startTime_edit, 6, 1) gridLayout.addWidget(label_traceLength, 7, 0) gridLayout.addWidget(self.traceLength_t, 7, 1) # gridLayout.addWidget(importEventButton, 8, 1, 1, 2) horzLayout = QHBoxLayout(self) horzLayout.addWidget(replaceWaveButton) horzLayout.addWidget(appendWaveButton) addGroupBox = QGroupBox("Get Waveform(s)") addGroupBox.setLayout(horzLayout) vertlayout = QVBoxLayout(self) vertlayout.addWidget(optionsContainer) vertlayout.addWidget(addGroupBox) vertlayout.addWidget(self.stationListWidget) vertlayout.addWidget(self.browserButton) self.setLayout(vertlayout) # create stationdialog here so that you only create it once, from here on you just run exec_() to make it pop up self.stationDialog = IPStationBrowser.IPStationDialog() def onClicked_browserButton(self): if self.stationDialog.exec_(self.startDate_edit.date(), network=self.networkNameBox.text(), station=self.stationNameBox.text(), location=self.location_Box.text(), channel=self.channel_Box.text()): self.inventory = self.stationDialog.getInventory() inv_contents = self.inventory.get_contents() stationList = [] # fill up the stationList with stations for item in inv_contents['stations']: stationList.append(item.strip()) self.stationListWidget.clear() self.stationListWidget.addItems(stationList) if self.stationDialog.getStartDate() is not None: self.startDate_edit.setDate(self.stationDialog.getStartDate()) # def populateWithEventInfo(self): # if self.parent.eventWidget.hasValidEvent(): # self.currentEvent = self.parent.eventWidget.Dict() # else: # msgBox = QMessageBox() # msgBox.setIcon(QMessageBox.Warning) # msgBox.setText('There is not a valid event in the Event Tab') # msgBox.setWindowTitle("Oops...") # msgBox.exec_() # return # if self.currentEvent is not None: # date = self.currentEvent['UTC Date'] # time = self.currentEvent['UTC Time'][0:5] # qdate = QDate.fromString(date, 'yyyy-MM-dd') # qtime = QTime.fromString(time, 'HH:mm') # qtime.addSecs(-5*60) # start about 5 minutes before event # self.startDate_edit.setDate(qdate) # self.startTime_edit.setTime(qtime) # self.eventInfoPopulated = True # # if someone edits the event info, reflect the changes here # @QtCore.pyqtSlot(dict) # def updateEventInfo(self, event): # if not self.eventInfoPopulated: # return # if self.parent.eventWidget.hasValidEvent(): # self.currentEvent = event # if self.currentEvent is not None: # date = event['UTC Date'] # time = event['UTC Time'][0:5] # qdate = QDate.fromString(date, 'yyyy-MM-dd') # qtime = QTime.fromString(time, 'HH:mm') # qtime.addSecs(-5*60) # start about 5 minutes before event # self.startDate_edit.setDate(qdate) # self.startTime_edit.setTime(qtime) def populateStationInfoFromStationList(self): items = self.stationListWidget.selectedItems() if len(items) < 1: return # nothing to do netList = [] staList = [] for item in items: text = item.text() text = text.split(' ')[0] netSta = text.split('.') netList.append(netSta[0]) staList.append(netSta[1]) netList = list(set(netList)) staList = list(set(staList)) netString = '' for net in netList: netString = netString + net + ', ' staString = '' for sta in staList: staString = staString + sta + ', ' self.networkNameBox.setText(netString[:-2]) self.stationNameBox.setText(staString[:-2]) def onActivated_cb(self, key): if (key != 'choose...'): url = URL_MAPPINGS[key] def onClicked_replace(self): self.downloadWaveforms() if self.stream is not None and self.inventory is not None: self.sigTracesReplaced.emit(self.stream, self.inventory) def onClicked_append(self): self.downloadWaveforms() if self.stream is not None and self.inventory is not None: self.sigTracesAppended.emit(self.stream, self.inventory) # get waveform button was clicked def downloadWaveforms(self): # first check to make sure the boxes are filled...addWidget # TODO!!! # get the inputs...inputs service = self.cb.currentText() if (service == 'choose...'): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('Please select a service to search') msg.setWindowTitle('oops...') msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return # Clear old streams because we don't need them anymore self.clearWaveforms() network = self.networkNameBox.text().upper().replace(' ', '') self.networkNameBox.setText(network) station = self.stationNameBox.text().upper().replace(' ', '') self.stationNameBox.setText(station) location = self.location_Box.text().upper().replace(' ', '') self.location_Box.setText(location) channel = self.channel_Box.text().upper().replace(' ', '') self.channel_Box.setText(channel) date = self.startDate_edit.date().toPyDate() time = self.startTime_edit.time().toPyTime() traceLength = self.traceLength_t.value() utcString = str(date) + 'T' + str(time) startTime = UTCDateTime(utcString) endTime = startTime + traceLength # Check for unfilled boxes if (network == '' or station == '' or channel == ''): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('You are missing some important info...') msg.setWindowTitle('oops...') msg.setDetailedText( "Network, Station, Location, and Channel are all required data." ) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return # Download the waveforms # self.parent.setStatus('connecting to '+service) client = Client(service) # self.parent.setStatus('downloading Waveforms...') try: self.stream = client.get_waveforms(network, station, location, channel, startTime, endTime) except Exception: # self.parent.setStatus('') msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('Failure loading waveform') msg.setWindowTitle('oops...') msg.setDetailedText( "Double check that the values you entered are valid and the time and date are appropriate." ) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return for trace in self.stream: trace.data = trace.data - np.mean(trace.data) self.stream.merge(fill_value=0) # self.parent.setStatus('downloading Inventory...') # self.parent.consoleBox.append( 'Downloaded waveforms from '+service ) # Now get the corresponding stations try: self.inventory = client.get_stations(network=network, station=station) except: # self.parent.setStatus('') msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('Failure loading Inventory') msg.setWindowTitle('oops...') msg.setDetailedText( "Double check that the values you entered are valid and the time and date are appropriate." ) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return # self.parent.consoleBox.append( 'Downloaded stations from '+service) # self.parent.setStatus('Finished...', 3000) def getStreams(self): return self.stream def getInventory(self): return self.inventory def getService(self): return self.cb.currentText() def clearWaveforms(self): self.stream = None self.inventory = None def clear(self): self.clearWaveforms() self.stationListWidget.clear() self.cb.setCurrentText( 'IRIS') # default to IRIS because why the hell not? self.networkNameBox.clear() self.stationNameBox.clear() self.location_Box.setText('*') self.channel_Box.setText('*') self.startDate_edit.setDate(self.startDate_edit.minimumDate()) self.startTime_edit.setTime(self.startTime_edit.minimumTime()) self.traceLength_t.setValue(3600)
class VarietyPriceWindow(AncestorWindow): name = "variety_price" export_table_signal = pyqtSignal() def __init__(self, *args, **kwargs): super(VarietyPriceWindow, self).__init__(*args, **kwargs) """绑定公用属性""" self.products = None self.db_worker = None # 线程是否结束标志位 self.exchange_lib_thread_over = True self.selected_variety_thread_over = True """总布局""" self.vertical_layout = QVBoxLayout() # 总纵向布局 top_select = QHBoxLayout() # 顶部横向条件选择栏 """交易所选择下拉框""" exchange_label = QLabel('选择交易所:') self.exchange_lib = QComboBox() self.exchange_lib.activated[str].connect( self.exchange_lib_selected) # 选择交易所调用的方法 """品种选择下拉框""" variety_label = QLabel('选择品种:') self.variety_lib = QComboBox() self.variety_lib.setMinimumSize(80, 20) self.variety_lib.activated[str].connect( self.variety_lib_selected) # 选择品种所调用的方法 """时间选择""" begin_time_label = QLabel("起始日期:") self.begin_time = QDateEdit( QDate.currentDate().addDays(-2)) # 参数为设置的日期 self.begin_time.setDisplayFormat('yyyy-MM-dd') # 时间显示格式 self.begin_time.setCalendarPopup(True) # 使用日历选择时间 end_time_label = QLabel("终止日期:") self.end_time = QDateEdit(QDate.currentDate().addDays(-1)) # 参数为设置的日期 self.end_time.setDisplayFormat('yyyy-MM-dd') # 时间显示格式 self.end_time.setCalendarPopup(True) # 使用日历选择时间 """确认按钮""" self.confirm_button = QPushButton("确定") self.confirm_button.clicked.connect(self.confirm) """水平布局添加控件""" top_select.addWidget(exchange_label) top_select.addWidget(self.exchange_lib) top_select.addWidget(variety_label) top_select.addWidget(self.variety_lib) top_select.addWidget(begin_time_label) top_select.addWidget(self.begin_time) top_select.addWidget(end_time_label) top_select.addWidget(self.end_time) top_select.addWidget(self.confirm_button) """自定义部件""" # 工具栏 self.tools = ToolWidget() tool_btn = QPushButton("季节图表") self.tool_view_all = QPushButton("返回总览") self.tool_view_all.setEnabled(False) self.tool_view_all.clicked.connect(self.return_view_all) self.tools.addTool(tool_btn) self.tools.addTool(self.tool_view_all) self.tools.addSpacer() tool_btn.clicked.connect(self.season_table) # 画布 self.map_widget = MapWidget() # 表格 self.table_widget = TableWidget(4) # 设置格式 self.table_widget.set_style( header_labels=['日期', '价格', '成交量合计', '持仓量合计']) """创建QSplitter""" self.show_splitter = QSplitter() self.show_splitter.setOrientation(Qt.Vertical) # 垂直拉伸 # 加入自定义控件 self.show_splitter.addWidget(self.map_widget) self.show_splitter.addWidget(self.table_widget) """垂直布局添加布局和控件并设置到窗口""" self.vertical_layout.addLayout(top_select) self.vertical_layout.addWidget(self.tools) self.vertical_layout.addWidget(self.show_splitter) # 加入控件 self.web_view = QWebEngineView() self.web_view.load(QUrl("file:///static/html/variety_price.html")) self.web_view.page().profile().downloadRequested.connect( self.download_requested) # 页面下载请求(导出excel) self.show_splitter.addWidget(self.web_view) self.web_view.hide() # 隐藏,刚开始不可见 """js交互通道""" web_channel = QWebChannel(self.web_view.page()) self.web_view.page().setWebChannel(web_channel) # 网页设置信息通道 web_channel.registerObject("season_table", self.tools) # 注册信号对象 web_channel.registerObject("export_table", self) # 导出表格数据信号对象 self.season_table_file = None # 季节表的保存路径 self.setLayout(self.vertical_layout) def fill_init_data(self): """填充交易所""" self.exchange_lib.clear() for lib in RESEARCH_LIB: self.exchange_lib.addItem(lib) # 获取当前交易所的品种并填充 self.exchange_lib_selected() def exchange_lib_selected(self): """交易所选择""" if not self.exchange_lib_thread_over: QMessageBox.information(self, "错误", "您的手速太快啦...", QMessageBox.Ok) return self.confirm_button.setEnabled(False) lib = self.exchange_lib.currentText() self.variety_lib.clear() if lib == "中国金融期货交易所": key = 'cffex' self.db_worker = self.cffex_getter self.products = CFFEX_PRODUCT_NAMES elif lib == "上海期货交易所": key = 'shfe' self.db_worker = self.shfe_getter self.products = SHFE_PRODUCT_NAMES elif lib == "大连商品交易所": key = 'dce' self.db_worker = self.dce_getter self.products = DCE_PRODUCT_NAMES elif lib == "郑州商品交易所": key = 'czce' self.db_worker = self.czce_getter self.products = CZCE_PRODUCT_NAMES else: self.db_worker = None self.products = None QMessageBox.information(self, '错误', "没有此项交易所..", QMessageBox.Ok) return for variety in GOODS_LIB.get(key): self.variety_lib.addItem(variety) # 关闭交易所选择 self.exchange_lib_thread_over = False # 品种选择 self.variety_lib_selected() def get_variety_en(self, variety): """获取相应的品种英文代号""" # 获取品种英文名称 if not self.products: # print("没有品种库:", self.products) QMessageBox.warning(self, "错误", "内部发生未知错误") return '' return self.products.get(variety) def variety_lib_selected(self): """ 选择品种所调用的方法,线程执行: 查询当前品种上市的日期 """ # 设置确认按钮不可用 self.confirm_button.setEnabled(False) if not self.selected_variety_thread_over: QMessageBox.warning(self, "错误", "您手速太快啦...", QMessageBox.Ok) return # 状态显示 variety = self.variety_lib.currentText() self.message_signal.emit("正在查询" + variety + "的数据时间区间...") en_variety = self.get_variety_en(variety) self.selected_variety_thread_over = False # 设置品种选择关闭 if self.db_worker: self.variety_selected_thread = VarietySelectedThread( db_worker=self.db_worker, variety=en_variety) self.variety_selected_thread.result_signal.connect( self.change_time_interval) self.variety_selected_thread.start() def change_time_interval(self, data): """根据品种选择线程的信号改变当前时间显示区间""" current_date = datetime.datetime.today() min_date = datetime.datetime.strptime(data[0], "%Y%m%d") max_date = datetime.datetime.strptime(data[1], "%Y%m%d") # 计算天数间隔 big_time_interval = -(current_date - min_date).days # 要往前取数,调整为负值 small_time_interval = -(current_date - max_date).days # 设置时间 self.begin_time.setDate(QDate.currentDate().addDays(big_time_interval)) self.end_time.setDate(QDate.currentDate().addDays(small_time_interval)) self.confirm_button.setEnabled(True) # 设置提交按钮为可用 # 设置完时间就所有锁打开 self.exchange_lib_thread_over = True self.selected_variety_thread_over = True # 状态显示时间区间查询完毕 self.message_signal.emit("时间区间查询完毕!") def clear_map_table(self): self.map_widget.delete() def confirm(self): """确认按钮点击""" # 开启定时器 self.timer.start(1000) # 改变确认按钮的状态 self.confirm_button.setText("提交成功") self.confirm_button.setEnabled(False) # 清除原图表并设置样式 self.map_widget.delete() self.table_widget.clear() self.table_widget.set_style( header_labels=['日期', '价格', '成交量合计', '持仓量合计']) # 根据时间段取得时间生成器类,查询相关数据,计算结果,返回时间列表及对应的价格列表 lib = self.exchange_lib.currentText() variety = self.variety_lib.currentText() variety_en = self.get_variety_en(variety) begin_time = re.sub('-', '', str(self.begin_time.date().toPyDate())) end_time = re.sub('-', '', str(self.end_time.date().toPyDate())) print("确认提交:\n当前交易所:{}\n当前品种:{},英文{}\n起始时间:{}\n终止时间:{}\n".format( lib, variety, variety_en, begin_time, end_time)) # 转成可计算的datetime.datetime时间对象 begin_time_datetime_cls = datetime.datetime.strptime( begin_time, "%Y%m%d") end_time_datetime_cls = datetime.datetime.strptime(end_time, "%Y%m%d") # 起止时间应早于终止时间 if begin_time_datetime_cls >= end_time_datetime_cls: QMessageBox.warning(self, "错误", "起止时间应早于终止时间", QMessageBox.Ok) self.message_signal.emit("时间选择有误!") self.timer.stop() self.cost_time = 0 # 设置确认按钮可用 self.confirm_button.setText("确定") self.confirm_button.setEnabled(True) return # 生成时间器对象 iterator_cls = GenerateTime(begin=begin_time_datetime_cls, end=end_time_datetime_cls) print("执行线程") if self.db_worker: # 线程执行查询目标数据 self.confirm_thread = ConfirmQueryThread(db_worker=self.db_worker, iterator=iterator_cls, variety=variety_en, lib=lib) self.confirm_thread.result_signal.connect(self.draw_map_table) self.confirm_thread.process_signal.connect(self.show_process) self.confirm_thread.start() def show_process(self, data): self.process_signal.emit(data) def draw_map_table(self, data): """数据展示""" print("结果", data) # 设置样式 self.map_widget.set_style() # 画图 x_data = [] y_data = [] tuple_data_list = data.get("data") message = data.get("message") for item in tuple_data_list: x_data.append(item[0]) y_data.append(item[1]) self.map_widget.axes.set_title(message) self.map_widget.map(x_data=x_data, y_data=y_data) # 表格数据填充 self.table_widget.table(data=tuple_data_list) self.message_signal.emit("处理完毕,生成图表成功!") self.timer.stop() self.cost_time = 0 self.confirm_button.setText("确定") self.confirm_button.setEnabled(True) def season_table(self): """处理展示季节图表""" # 菜单可用状态改变 main_window = self.parent().parent() main_window.export_table.setEnabled(True) # 获取表格的行数和列数 col-列,row-行 # col_count = self.table_widget.columnCount() row_count = self.table_widget.rowCount() # if not row_count: # return # 隐藏与可见的处理 self.confirm_button.setEnabled(False) self.map_widget.hide() self.table_widget.hide() self.web_view.show() self.tool_view_all.setEnabled(True) # 获取数据,处理数据,将结果数据传入页面展示 # print("列数", col_count) # print("行数", row_count) # 遍历获取数据 data = OrderedDict() for row in range(row_count): date = self.table_widget.item(row_count - 1, 0).text() # date = date[:4] + "/" + date[4:6] + "/" + date[6:] price = self.table_widget.item(row_count - 1, 1).text() if date[:4] not in data.keys(): data[date[:4]] = [] data[date[:4]].append([date, price]) # for col in range(col_count): # print(self.table_widget.item(row_count-1, col).text(), ' ', end='') row_count -= 1 # 数据处理 finally_data = self.data_handler(data) # print(finally_data) self.tools.tool_click_signal.emit(finally_data) # 数据传到页面 def return_view_all(self): # 加入自定义控件 self.confirm_button.setEnabled(True) self.web_view.hide() self.map_widget.show() self.table_widget.show() self.tool_view_all.setEnabled(False) # 菜单可用状态改变 main_window = self.parent().parent() main_window.export_table.setEnabled(False) @staticmethod def generate_axis_x(): """生成横坐标数据, 以闰年计""" start_day = datetime.datetime.strptime("20160101", "%Y%m%d") end_day = datetime.datetime.strptime("20161231", "%Y%m%d") axis_x = [] for date in GenerateTime(begin=start_day, end=end_day).generate_time(): axis_x.append(date[4:]) return axis_x def data_handler(self, data): """ 页面展示图表的数据处理 :param data: :return: json Data """ axis_x = self.generate_axis_x( ) # 生成横坐标,整理用于作折线的原始数据,结果的结构{year:[[date, value], [date, value],...]} month_data = OrderedDict() # 创建一个字典存放数据 map_data = OrderedDict() # 存用于作图的数据 # 将数据以月份为单位分开,结果的结构 {year:{month:[up_down, shock]}} for year in data: # 年为单位的数据 month_data[year] = {} map_data[year] = [] for year_item in data[year]: # 每年的各个数据 for x in axis_x: if x == year_item[0][4:]: map_data[year].append([x, year_item[1]]) # 放入当天的数据用于作图的 # 根据时间将数据重新整理 month = year_item[0][4:6] if month not in month_data[year].keys(): month_data[year][month] = [] month_data[year][month].append( year_item ) # month_data = json.dumps(month_data) # {year:{month:[[date, price], ...]}} new_month_data = OrderedDict() last_price = None for y in month_data: # {year:{month:[[date, price], ...]}} if y not in new_month_data: new_month_data[y] = OrderedDict() for m in [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12' ]: one_month_data = month_data[y].get(m) if one_month_data: last = int(one_month_data[-1][1]) # 计算涨跌 up_down = None if last_price: up_down = "%.4f" % ((last - last_price) / last_price) if last_price else "-" up_down = "%.2f" % (float(up_down) * 100) if last_price else "-" last_price = last # 计算波幅 data_set = [] for item in one_month_data: data_set.append(int(item[1])) min_price = min(data_set) max_price = max(data_set) shock = "%.4f" % ((max_price - min_price) / min_price) if min_price else "-" # 波幅 shock = "%.2f" % (float(shock) * 100) if min_price else "-" new_month_data[y][m] = [] new_month_data[y][m].append(up_down) new_month_data[y][m].append(shock) else: last_price = None # title的处理 title = "" if self.name == "variety_price": title = self.exchange_lib.currentText( ) + self.variety_lib.currentText() + "品种权重指数" if self.name == "main_contract": title = self.exchange_lib.currentText( ) + self.variety_lib.currentText() + "主力合约指数" # 整理数据 finally_data = dict() finally_data["raw"] = data finally_data["result"] = new_month_data finally_data["mapData"] = map_data finally_data["title"] = title return json.dumps(finally_data) def download_requested(self, download_item): # 保存位置选择,默认桌面 if not download_item.isFinished() and download_item.state() == 0: cur_window = self.parent().parent().window_stack.currentWidget() if cur_window.name == "variety_price": title = "品种权重指数季节表" elif cur_window.name == "main_contract": title = "主力合约指数季节表" else: return desktop_path = get_desktop_path() save_path = QFileDialog.getExistingDirectory( self, "选择保存的位置", desktop_path) if not save_path: return cur_time = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d") excel_name = cur_window.exchange_lib.currentText( ) + cur_window.variety_lib.currentText() + title + cur_time file_path = save_path + "/" + excel_name + ".xls" download_item.setPath(file_path) download_item.accept() self.season_table_file = file_path download_item.finished.connect(self.download_finished) def download_finished(self): try: if self.season_table_file: open_dialog = QMessageBox.question( self, "成功", "导出保存成功!\n是否现在打开?", QMessageBox.Yes | QMessageBox.No) if open_dialog == QMessageBox.Yes: open_excel( self.season_table_file) # 调用Microsoft Excel 打开文件 self.season_table_file = None except Exception as e: pass
class CreateReportPopup(QDialog): def __init__(self, variety_info, *args, **kwargs): super(CreateReportPopup, self).__init__(*args, **kwargs) self.setWindowTitle("新建报告") self.variety_info = variety_info # 总布局-左右 layout = QHBoxLayout() # 左侧上下布局 llayout = QVBoxLayout() # 左侧是品种树 self.left_tree = QTreeWidget(clicked=self.variety_tree_clicked) self.left_tree.header().hide() self.left_tree.setMaximumWidth(160) llayout.addWidget(self.left_tree) layout.addLayout(llayout) # 右侧上下布局 rlayout = QVBoxLayout(spacing=10) # 所属品种 attach_varieties_layout = QHBoxLayout() attach_varieties_layout.addWidget(QLabel('所属品种:')) self.attach_varieties = QLabel() self.attach_varieties.variety_ids = list() # id字符串 attach_varieties_layout.addWidget(self.attach_varieties) attach_varieties_layout.addStretch() attach_varieties_layout.addWidget(QPushButton( '清空', objectName='deleteBtn', cursor=Qt.PointingHandCursor, clicked=self.clear_attach_varieties), alignment=Qt.AlignRight) rlayout.addLayout(attach_varieties_layout) # 所属分类 attach_category_layout = QHBoxLayout() attach_category_layout.addWidget(QLabel('所属分类:')) self.category_combo = QComboBox() self.category_combo.setMinimumWidth(400) attach_category_layout.addWidget(self.category_combo) attach_category_layout.addStretch() rlayout.addLayout(attach_category_layout) date_layout = QHBoxLayout() date_layout.addWidget(QLabel("报告日期:", self)) self.date_edit = QDateEdit(QDate.currentDate()) self.date_edit.setCalendarPopup(True) self.date_edit.setDisplayFormat('yyyy-MM-dd') date_layout.addWidget(self.date_edit) date_layout.addStretch() rlayout.addLayout(date_layout) title_layout = QHBoxLayout() title_layout.addWidget(QLabel('报告标题:', self)) self.title_edit = QLineEdit(self) title_layout.addWidget(self.title_edit) rlayout.addLayout(title_layout) # 选择报告 select_report_layout = QHBoxLayout() select_report_layout.addWidget(QLabel('报告文件:', self)) self.report_file_edit = FileLineEdit() self.report_file_edit.setParent(self) select_report_layout.addWidget(self.report_file_edit) rlayout.addLayout(select_report_layout) # 提交按钮 self.commit_button = QPushButton('提交', clicked=self.commit_upload_report) rlayout.addWidget(self.commit_button, alignment=Qt.AlignRight) rlayout.addStretch() layout.addLayout(rlayout) self.setLayout(layout) self.setFixedSize(800, 500) self.setStyleSheet(""" #deleteBtn{ border: none; color:rgb(200,100,80) } #newCategoryBtn{ border:none; color:rgb(80,100,200) } """) self.geTreeVarieties() for category_item in [("日报", 1), ("周报", 2), ("月报", 3), ("年报", 4), ("专题报告", 5), ("其他", 0)]: self.category_combo.addItem(category_item[0], category_item[1]) def geTreeVarieties(self): # 填充品种树 for group_item in self.variety_info: group = QTreeWidgetItem(self.left_tree) group.setText(0, group_item['name']) group.gid = group_item['id'] # 添加子节点 for variety_item in group_item['subs']: child = QTreeWidgetItem() child.setText(0, variety_item['name']) child.vid = variety_item['id'] group.addChild(child) self.left_tree.expandAll() # 展开所有 # 清空所属品种 def clear_attach_varieties(self): self.attach_varieties.setText('') self.attach_varieties.variety_ids.clear() # id列表 def commit_upload_report(self): data = dict() title = self.title_edit.text() file_path = self.report_file_edit.text() if not all([title, file_path]): QMessageBox.information(self, "错误", "请填写完整信息") return data['utoken'] = settings.app_dawn.value('AUTHORIZATION') data['title'] = title data['link_varieties'] = ','.join( map(str, self.attach_varieties.variety_ids)) data["custom_time"] = self.date_edit.text() data['category'] = self.category_combo.currentData() # 读取文件 file = open(file_path, "rb") file_content = file.read() file.close() filename = file_path.rsplit('/', 1)[1] # 文件内容字段 data["report_file"] = (filename, file_content) encode_data = encode_multipart_formdata(data) try: r = requests.post(url=settings.SERVER_ADDR + 'report/', headers={"Content-Type": encode_data[1]}, data=encode_data[0]) response = json.loads(r.content.decode('utf8')) if r.status_code != 201: raise ValueError(response['message']) except Exception as e: QMessageBox.information(self, "错误", str(e)) else: QMessageBox.information(self, "成功", "添加报告成功") self.close() # 点击左侧品种树 def variety_tree_clicked(self): item = self.left_tree.currentItem() if item.childCount(): # has children open the root if item.isExpanded(): item.setExpanded(False) else: item.setExpanded(True) text = item.text(0) if item.parent( ) and item.vid not in self.attach_varieties.variety_ids: # 所属品种中增加当前品种 self.attach_varieties.setText(self.attach_varieties.text() + text + '、') self.attach_varieties.variety_ids.append(item.vid)
class PricePositionWin(QWidget): """ 价格净持仓窗口 """ def __init__(self, *args, **kwargs): super(PricePositionWin, self).__init__(*args, **kwargs) """ UI部分 """ layout = QVBoxLayout() layout.setContentsMargins(QMargins(0, 0, 0, 0)) # 操作头 title_layout = QHBoxLayout() title_layout.setAlignment(Qt.AlignLeft) title_layout.addWidget(QLabel("交易所:", self)) self.exchange_combobox = QComboBox(self) title_layout.addWidget(self.exchange_combobox) title_layout.addWidget(QLabel("期货品种:", self)) self.variety_combobox = QComboBox(self) self.variety_combobox.setMinimumWidth(100) title_layout.addWidget(self.variety_combobox) title_layout.addWidget(QLabel("合约:", self)) self.contract_combobox = QComboBox(self) title_layout.addWidget(self.contract_combobox) title_layout.addWidget(QLabel("起始日期:")) self.start_date = QDateEdit(self) self.start_date.setDisplayFormat('yyyy-MM-dd') self.start_date.setCalendarPopup(True) title_layout.addWidget(self.start_date) title_layout.addWidget(QLabel("终止日期:")) self.end_date = QDateEdit(self) self.end_date.setDisplayFormat('yyyy-MM-dd') self.end_date.setCalendarPopup(True) title_layout.addWidget(self.end_date) self.analysis_button = QPushButton("开始分析", self) self.analysis_button.setEnabled(False) title_layout.addWidget(self.analysis_button) self.option_widget = TitleOptionWidget(self) self.option_widget.setLayout(title_layout) layout.addWidget(self.option_widget) # 图形表格拖动区 splitter = QSplitter(Qt.Vertical, self) splitter.setContentsMargins(QMargins(10, 5, 10, 5)) # 请求数据遮罩层(需放在splitter之后才能显示,不然估计是被splitter覆盖) self.loading_cover = LoadingCover() self.loading_cover.setParent(self) self.loading_cover.resize(self.parent().width(), self.parent().height()) # 图形区 self.loading_cover.show(text='正在加载资源') self.chart_container = ChartContainWidget(ChartSourceChannel(), 'file:/templates/price_position.html', self) self.chart_container.page().loadFinished.connect(self.page_load_finished) splitter.addWidget(self.chart_container) # 表格区 self.table_widget = QWidget(self) table_layout = QVBoxLayout() table_layout.setContentsMargins(QMargins(0, 0, 0, 0)) opt_widget = QWidget(self.table_widget) opt_lt = QHBoxLayout(opt_widget) opt_lt.setContentsMargins(0,0,0,0) opt_widget.setLayout(opt_lt) # 日期选择,全品种净持率查看 self.all_date_edit = QDateEdit(self) self.all_date_edit.setCalendarPopup(True) self.all_date_edit.setDisplayFormat('yyyy-MM-dd') self.all_date_edit.setDate(QDate.currentDate()) opt_lt.addWidget(self.all_date_edit) self.all_query_button = QPushButton('查询全净持率', self) opt_lt.addWidget(self.all_query_button) # 增加净持率 self.add_net_rate = QPushButton('增加列', self) opt_lt.addWidget(self.add_net_rate) opt_lt.addStretch() # 导出数据按钮 self.export_button = QPushButton('导出EXCEL', self) self.export_button.setEnabled(False) opt_lt.addWidget(self.export_button) opt_widget.setFixedHeight(30) table_layout.addWidget(opt_widget) self.data_table = QTableWidget(self) self.data_table.verticalHeader().hide() self.data_table.setFocusPolicy(Qt.NoFocus) self.data_table.setColumnCount(7) self.data_table.setHorizontalHeaderLabels(['日期', '收盘价', '总持仓', '多头', '空头', '净持仓', '净持仓率%']) self.data_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.data_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.data_table.setSelectionMode(QAbstractItemView.SingleSelection) table_layout.addWidget(self.data_table) # 全品种净持仓率显示表 self.all_table = QTableWidget(self) self.all_table.hide() table_layout.addWidget(self.all_table) self.table_widget.setLayout(table_layout) splitter.addWidget(self.table_widget) splitter.setSizes([self.parent().height() * 0.6, self.parent().height() * 0.4]) layout.addWidget(splitter) # 设置表行高,各行颜色 self.data_table.verticalHeader().setDefaultSectionSize(18) # 设置行高(与下行代码同时才生效) self.data_table.verticalHeader().setMinimumSectionSize(18) self.data_table.setAlternatingRowColors(True) self.data_table.setObjectName('dataTable') self.setStyleSheet( "#dataTable{selection-color:rgb(80,100,200);selection-background-color:rgb(220,220,220);" "alternate-background-color:rgb(230,254,238);gridline-color:rgb(60,60,60)}" ) # 设置表头,表滚动条样式 self.data_table.horizontalHeader().setStyleSheet(HORIZONTAL_HEADER_STYLE) self.data_table.horizontalScrollBar().setStyleSheet(HORIZONTAL_SCROLL_STYLE) self.data_table.verticalScrollBar().setStyleSheet(VERTICAL_SCROLL_STYLE) self.setLayout(layout) """ 业务逻辑部分 """ self.query_type = 'contract' # 当前查询的数据类型 # 网管器 self.network_manager = getattr(qApp, 'network') # 关联交易所变化信号 self.exchange_combobox.currentTextChanged.connect(self.get_variety_with_exchange) # 关联品种变化信号 self.variety_combobox.currentTextChanged.connect(self.get_contract_with_variety) # 关联合约变化的信号 self.contract_combobox.currentTextChanged.connect(self.get_min_max_date_with_contract) # 添加交易所 for exchange_item in EXCHANGES: self.exchange_combobox.addItem(exchange_item['name'], exchange_item['id']) # 关联开始计算按钮信号 self.analysis_button.clicked.connect(self.get_analysis_data) # 关联导出数据信息 self.export_button.clicked.connect(self.export_table_to_excel) # 查询全品种净持仓率的信号 self.all_query_button.clicked.connect(self.to_query_all_position) # 增加净持率列的信号 self.add_net_rate.setEnabled(False) self.add_net_rate.clicked.connect(self.to_add_new_column_rate) # 点击表头排序 self.all_table.horizontalHeader().sectionClicked.connect(self.all_table_horizontal_clicked) self.current_table = 'single_contract' def all_table_horizontal_clicked(self, col): if col < 7: return self.all_table.sortItems(col) # 重新设置一下颜色 for row in range(self.all_table.rowCount()): for col in range(self.all_table.columnCount()): item = self.all_table.item(row, col) if row % 2 == 0: item.setBackground(QBrush(QColor(230, 254, 238))) else: item.setBackground(QBrush(QColor(255, 255, 255))) def to_add_new_column_rate(self): # 新增净持率列 new_column_date = self.all_date_edit.text() self.show_loading("正在获取数据") url = SERVER_2_0 + 'dsas/price-position/?ds={}&de={}'.format(new_column_date, new_column_date) reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.new_column_data_reply) def new_column_data_reply(self): reply = self.sender() self.loading_finished() if reply.error(): logger.error('GET NEW COLUMN NET POSTION ERROR. STATUS:{}'.format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) variety_data = data.get('data', None) if not variety_data: return current_columns = self.all_table.columnCount() self.all_table.insertColumn(current_columns) self.all_table.setHorizontalHeaderItem(current_columns, QTableWidgetItem(self.all_date_edit.text())) self.insert_column_data(variety_data) reply.deleteLater() def insert_column_data(self, data): # 添加列数据 # 过滤data数据 data = list(filter(lambda x: x['variety_en'] == x['contract'], data)) # 数据转为dict形式 rate_data = {item['variety_en']: item for item in data} current_column = self.all_table.columnCount() - 1 for row in range(self.all_table.rowCount()): row_item = self.all_table.item(row, 0) variety_en = row_item.data(Qt.UserRole)['variety_en'] data_item = rate_data.get(variety_en) if not data_item: continue # 计算净持率 a = float(data_item['net_position'].replace(',', '')) b = float(data_item['position_volume'].replace(',', '')) rate = f'{round(a * 100 / b, 2)}%' if b > 0 else '-' display = round(a * 100 / b, 2) if b > 0 else '-' new_item = QTableWidgetItem(rate) new_item.setTextAlignment(Qt.AlignCenter) new_item.setData(Qt.DisplayRole, display) self.all_table.setItem(row, current_column, new_item) if row % 2 == 0: new_item.setBackground(QBrush(QColor(230, 254, 238))) def to_query_all_position(self): self.show_loading("正在获取数据") current_date = self.all_date_edit.text() url = SERVER_2_0 + 'dsas/price-position/?ds={}&de={}'.format(current_date, current_date) reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.all_variety_position_reply) def all_variety_position_reply(self): reply = self.sender() self.loading_finished() if reply.error(): logger.error('GET ALL VARIETY NET POSTION ERROR. STATUS:{}'.format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) self.show_all_variety_net_position(data.get('data', [])) reply.deleteLater() def show_all_variety_net_position(self, data): # 过滤data数据 show_list = list(filter(lambda x: x['variety_en'] == x['contract'], data)) self.all_table.clear() titles = ['日期', '品种', '主力收盘价', '总持仓量', '前20多单量', '前20空单量', '前20净持仓', '净持率%'] columns = ['quotes_date', 'variety_name', 'close_price', 'position_volume', 'long_position', 'short_position', 'net_position', 'net_rate'] self.all_table.setRowCount(len(show_list)) self.all_table.setColumnCount(len(columns)) self.all_table.setHorizontalHeaderLabels(titles) for row, p_item in enumerate(show_list): print(p_item) for col, key in enumerate(columns): if key == 'net_rate': a = float(p_item['net_position'].replace(',', '')) b = float(p_item['position_volume'].replace(',', '')) rate = f'{round(a * 100 / b, 2)}%' if b > 0 else '-' item = QTableWidgetItem(rate) display = round(a * 100 / b, 2) if b > 0 else '-' item.setData(Qt.DisplayRole, display) else: item = QTableWidgetItem(str(p_item[key])) item.setTextAlignment(Qt.AlignCenter) if row % 2 == 0: item.setBackground(QBrush(QColor(230, 254, 238))) if col == 0: item.setData(Qt.UserRole, {'variety_en': p_item['variety_en']}) self.all_table.setItem(row, col, item) self.data_table.hide() self.all_table.show() self.current_table = 'all_variety' if len(show_list) > 0: self.export_button.setEnabled(True) self.add_net_rate.setEnabled(True) def resizeEvent(self, event): super(PricePositionWin, self).resizeEvent(event) self.loading_cover.resize(self.parent().width(), self.parent().height()) def clear_contents(self): """ 清除图形和表格 """ self.chart_container.clear_chart() self.data_table.clearContents() self.data_table.setRowCount(0) def show_loading(self, show_text): """ 显示正在请求数据 """ # 请求数据 self.loading_cover.show(text=show_text) self.analysis_button.setEnabled(False) self.export_button.setEnabled(False) self.clear_contents() def loading_finished(self): """ 请求数据结束 """ self.loading_cover.hide() self.analysis_button.setEnabled(True) def page_load_finished(self): """ 页面加载完成 """ # self.loading_cover.hide() pass def get_variety_with_exchange(self): """ 获取交易所下的所有品种 """ self.show_loading("正在获取品种") url = SERVER_API + 'exchange-variety/?is_real=1&exchange={}'.format(self.exchange_combobox.currentData()) reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.exchange_variety_reply) def exchange_variety_reply(self): # 交易所品种返回 reply = self.sender() if reply.error(): logger.error('GET EXCHANGE VARIETY ERROR. STATUS:{}'.format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) self.set_current_variety(data['varieties']) reply.deleteLater() def set_current_variety(self, varieties: list): """ 设置当前的品种 """ self.variety_combobox.clear() for variety_item in varieties: self.variety_combobox.addItem(variety_item['variety_name'], variety_item['variety_en']) def get_contract_with_variety(self): """ 根据品种获取全部合约 """ if not self.variety_combobox.currentData(): return self.show_loading('正在获取合约') url = SERVER_API + 'price-position-contracts/?variety_en={}'.format(self.variety_combobox.currentData()) reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.variety_contracts_reply) def variety_contracts_reply(self): """ 品种的所有合约返回 """ reply = self.sender() if reply.error(): logger.error("GET CONTRACTS OF VARIETY ERROR. STATUS:{}".format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) self.set_current_contract(data['contracts']) reply.deleteLater() def set_current_contract(self, contracts: list): self.contract_combobox.clear() # 将第一个合约进行英文与数字的分离 if len(contracts) > 0: variety = [''.join(list(g)) for k, g in groupby(contracts[0]['contract'], key=lambda x: x.isdigit())] v = variety[0] if len(variety[0]) <= 2 else variety[0][:2] self.contract_combobox.addItem(v) for contract_item in contracts: self.contract_combobox.addItem(contract_item['contract']) def get_min_max_date_with_contract(self): """ 根据合约获取时间范围 """ if not self.contract_combobox.currentText(): return current_contract = self.contract_combobox.currentText() split_list = [''.join(list(g)) for k, g in groupby(current_contract, key=lambda x: x.isdigit())] if len(split_list) > 1: # 查询的是合约 self.query_type = 'contract' self.show_loading('正在获取日期范围') url = SERVER_API + 'price-position-dates/?contract={}'.format(self.contract_combobox.currentText()) reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.min_max_date_reply) else: # 查询的是品种 max_date = int(datetime.datetime.strptime(datetime.datetime.today().strftime('%Y-%m-%d'), '%Y-%m-%d').timestamp()) min_date = int(datetime.datetime.strptime(str(datetime.datetime.today().year - 3), '%Y').timestamp()) self.set_min_and_max_date(min_date, max_date) self.query_type = 'variety' self.loading_finished() # 加载数据结束 def min_max_date_reply(self): """ 日期值返回 """ reply = self.sender() if reply.error(): logger.error("GET MIN & MAX DATE WITH CONTRACT ERROR. STATUS:{}".format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) min_max_date = data["dates"] self.set_min_and_max_date(min_max_date['min_date'], min_max_date['max_date']) reply.deleteLater() self.loading_finished() # 加载数据结束 def set_min_and_max_date(self, min_date: int, max_date: int): """ 设置最大最小日期 """ if not min_date or not max_date: self.analysis_button.setEnabled(False) return min_date = datetime.datetime.fromtimestamp(min_date) max_date = datetime.datetime.fromtimestamp(max_date) q_min_date = QDate(min_date.year, min_date.month, min_date.day) q_max_date = QDate(max_date.year, max_date.month, max_date.day) self.start_date.setDateRange(q_min_date, q_max_date) self.start_date.setDate(q_min_date) self.end_date.setDateRange(q_min_date, q_max_date) self.end_date.setDate(q_max_date) self.analysis_button.setEnabled(True) def get_analysis_data(self): """ 获取结果数据 """ if not self.contract_combobox.currentText(): QMessageBox.information(self, '错误', '请先选择合约后再操作.') return self.show_loading('正在获取资源数据') min_date = int(datetime.datetime.strptime(self.start_date.text(), '%Y-%m-%d').timestamp()) max_date = int(datetime.datetime.strptime(self.end_date.text(), '%Y-%m-%d').timestamp()) if self.query_type == 'contract': url = SERVER_API + 'price-position/?contract={}&min_date={}&max_date={}'.format( self.contract_combobox.currentText(), min_date, max_date ) elif self.query_type == 'variety': url = SERVER_2_0 + 'dsas/price-position/?ds={}&de={}&c={}'.format( self.start_date.text(), self.end_date.text(), self.contract_combobox.currentText() ) else: return reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.price_position_reply) def price_position_reply(self): """ 获取数据返回 """ reply = self.sender() if reply.error(): logger.error("GET PRICE-POSITION DATA ERROR. STATUS:{}".format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) if self.query_type == 'variety': # 处理数据,由于新版接口与旧版不一致 for item in data['data']: item['date'] = item['quotes_date'].replace('-', '') item['contract'] = item['variety_en'] item['empty_volume'] = float(item['position_volume'].replace(',', '')) item['long_position'] = float(item['long_position'].replace(',', '')) item['short_position'] = float(item['short_position'].replace(',', '')) del item['quotes_ts'] del item['position_volume'] del item['net_position'] del item['quotes_date'] self.set_current_data_to_table(data['data'].copy()) # 数据在表格展示 self.export_button.setEnabled(True) # 组合基本配置信息和源数据传递到页面 base_option = { 'title': '{}价格与净持率趋势图'.format(self.contract_combobox.currentText()) } self.set_current_chart_to_page(json.dumps(data['data']), json.dumps(base_option)) reply.deleteLater() self.loading_finished() def set_current_data_to_table(self, data_items: list): """ 将数据在表格显示 """ self.data_table.clearContents() self.data_table.setRowCount(len(data_items)) data_items.reverse() for row, row_item in enumerate(data_items): t_item0 = QTableWidgetItem(row_item['date']) t_item0.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 0, t_item0) t_item1 = QTableWidgetItem(str(row_item['close_price'])) t_item1.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 1, t_item1) t_item2 = QTableWidgetItem(str(row_item['empty_volume'])) t_item2.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 2, t_item2) t_item3 = QTableWidgetItem(str(row_item['long_position'])) t_item3.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 3, t_item3) t_item4 = QTableWidgetItem(str(row_item['short_position'])) t_item4.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 4, t_item4) t_item5 = QTableWidgetItem(str(row_item['long_position'] - row_item['short_position'])) t_item5.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 5, t_item5) rate = '-' if row_item['empty_volume'] == 0 else str( round((row_item['long_position'] - row_item['short_position']) * 100 / row_item['empty_volume'], 2)) t_item6 = QTableWidgetItem(rate) t_item6.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, 6, t_item6) self.current_table = 'single_contract' self.data_table.show() self.all_table.hide() def set_current_chart_to_page(self, source_data: str, base_option: str): """ 设置数据到图形区域 """ self.chart_container.set_chart_option(source_data, base_option) def export_table_to_excel(self): """ 导出表格数据到excel""" if self.current_table == 'single_contract': # 1 读取表格数据: table_df = self.read_table_data() # 2 选定保存的位置 # 保存的文件名称 filename = '{}价格-净持率数据'.format(self.contract_combobox.currentText()) filepath, _ = QFileDialog.getSaveFileName(self, '保存文件', filename, 'EXCEL文件(*.xlsx *.xls)') if filepath: # 3 导出数据 writer = pd.ExcelWriter(filepath, engine='xlsxwriter', datetime_format='YYYY-MM-DD') table_df.to_excel(writer, sheet_name='价格-净持率', index=False, encoding='utf8') writer.save() if self.current_table == 'all_variety': df = self.read_all_table_data() # 读取全品种表格的数据 # 2 选定保存的位置 # 保存的文件名称 filename = '{}全品种价格-净持率数据'.format(self.all_date_edit.text()) filepath, _ = QFileDialog.getSaveFileName(self, '保存文件', filename, 'EXCEL文件(*.xlsx *.xls)') if filepath: # 3 导出数据 writer = pd.ExcelWriter(filepath, engine='xlsxwriter', datetime_format='YYYY-MM-DD') df.to_excel(writer, sheet_name='全品种价格-净持率', index=False, encoding='utf8') writer.save() def read_all_table_data(self): header_list = [] value_list = [] for header_col in range(self.all_table.columnCount()): header_list.append( self.all_table.horizontalHeaderItem(header_col).text() ) for row in range(self.all_table.rowCount()): row_list = [] for col in range(self.all_table.columnCount()): item_value = self.all_table.item(row, col).text() try: value = datetime.datetime.strptime(item_value, '%Y%m%d') if col == 0 else float( self.all_table.item(row, col).text()) except ValueError: value = item_value row_list.append(value) value_list.append(row_list) return pd.DataFrame(value_list, columns=header_list) def read_table_data(self): """ 读取表格数据 """ header_list = [] value_list = [] for header_col in range(self.data_table.columnCount()): header_list.append( self.data_table.horizontalHeaderItem(header_col).text() ) for row in range(self.data_table.rowCount()): row_list = [] for col in range(self.data_table.columnCount()): item_value = self.data_table.item(row, col).text() try: value = datetime.datetime.strptime(item_value, '%Y%m%d') if col == 0 else float( self.data_table.item(row, col).text()) except ValueError: value = item_value row_list.append(value) value_list.append(row_list) return pd.DataFrame(value_list, columns=header_list)
class AddEmployeeDetails(QMainWindow): closing = pyqtSignal(int) def __init__(self, parent, update, id=None): super().__init__(parent) self.parent = parent self.db = DB() self.initUI(update, id) def initUI(self, update, id): self.setWindowModality(Qt.ApplicationModal) frame = QFrame() # frame.setStyleSheet("background-color: rgb(30, 45, 66);") frame.setFrameShape(QFrame.StyledPanel) frame.setFrameShadow(QFrame.Raised) # frame.setMinimumWidth(430) # frame.setFixedHeight(395) frame.setStyleSheet("border: none") add_employee_button = QLabel(frame) add_employee_button.setAlignment(Qt.AlignCenter) add_employee_button.setGeometry(QRect(110, 30, 210, 41)) add_employee_button.setStyleSheet("font: 75 12pt \"MS Shell Dlg 2\";\n" "background-color: rgb(30, 45, 66);\n" "color: rgb(255, 255, 255);") add_employee_button.setText("Add Employee Details") # name = QHBoxLayout() # jobtitle = QHBoxLayout() # salary = QHBoxLayout() # bonus = QHBoxLayout() # joindate = QHBoxLayout() namelabel = QLabel(frame) namelabel.setText("Name") namelabel.setGeometry(QRect(80, 100, 47, 13)) self.nametextbox = QLineEdit(frame) self.nametextbox.setGeometry(QRect(160, 90, 181, 31)) self.nametextbox.setFixedWidth(180) jobtitlelabel = QLabel(frame) jobtitlelabel.setText("Job Title") jobtitlelabel.setGeometry(QRect(80, 140, 61, 16)) self.jobtitletextbox = QComboBox(frame) self.jobtitletextbox.setGeometry(QRect(160, 130, 181, 31)) self.jobtitletextbox.setFixedWidth(180) self.jobtitletextbox.addItems(["Manager", "Waiter", "Chef", "Security"]) salarylabel = QLabel(frame) salarylabel.setText("Salary") salarylabel.setGeometry(QRect(80, 180, 47, 13)) self.salarytextbox = QLineEdit(frame) self.salarytextbox.setGeometry(QRect(160, 170, 181, 31)) self.salarytextbox.setFixedWidth(180) self.salarytextbox.setValidator(QIntValidator()) # bonuslabel = QLabel(frame) # bonuslabel.setText("Bonus") # bonuslabel.setGeometry(QRect(80, 220, 47, 13)) # bonustextbox = QLineEdit(frame) # bonustextbox.setGeometry(QRect(160, 210, 181, 31)) # bonustextbox.setFixedWidth(180) joindatelabel = QLabel(frame) joindatelabel.setText("Start Date") joindatelabel.setGeometry(QRect(80, 260, 71, 16)) self.joindatetextbox = QDateEdit(frame) self.joindatetextbox.setGeometry(QRect(160, 250, 181, 31)) self.joindatetextbox.setFixedWidth(180) self.joindatetextbox.setDate(QDate.currentDate()) self.joindatetextbox.setMinimumDate(QDate.currentDate()) self.joindatetextbox.setDisplayFormat("dd-MM-yyyy") self.addbutton = QPushButton(frame) self.addbutton.setGeometry(QRect(160, 300, 111, 31)) self.addbutton.setStyleSheet("font: 75 12pt \"MS Shell Dlg 2\";\n" "background-color: rgb(30, 45, 66);\n" "color: rgb(255, 255, 255);") if update == 'add': print("Add") print(id) self.addbutton.setText("Add Employee") self.addbutton.clicked.connect(lambda: self.add_button_click("employee")) else: print("Update") print(id) self.addbutton.setText("Update Employee") self.addbutton.clicked.connect(lambda: self.update_button_click("employee", id)) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(frame) centralWidget = QWidget() centralWidget.setLayout(layout) self.setCentralWidget(centralWidget) # self.setLayout(layout) self.setWindowTitle("Add Employee Details") self.resize(430, 395) self.show() self.center() def center(self): '''centers the window on the screen''' screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def update_button_click(self, where, id): if where == "employee": print("Employees Finally here") print(self.nametextbox.text()) print(self.jobtitletextbox.currentText()) print(self.salarytextbox.text()) print(self.joindatetextbox.text()) employee_name = self.nametextbox.text() job_title = self.jobtitletextbox.currentText() salary = self.salarytextbox.text() try: date = datetime.datetime.strptime(self.joindatetextbox.text(), "%d-%m-%Y") joining_date = datetime.datetime.strftime(date, "%Y-%m-%d") except: ''' Make sure to add an error message. ''' return if employee_name != "" and salary != "": query = "update employee set `employee_name`=%s, `job_title`=%s, `salary`=%s, " \ "`joining_date`=%s where id=%s" values = (employee_name, job_title, salary, joining_date, id) result = self.db.execute(query, values) self.closeEvent = self.message() def add_button_click(self, where): if where == "employee": print("Employees Finally here") print(self.nametextbox.text()) print(self.jobtitletextbox.currentText()) print(self.salarytextbox.text()) print(self.joindatetextbox.text()) employee_name = self.nametextbox.text() job_title = self.jobtitletextbox.currentText() salary = self.salarytextbox.text() try: date = datetime.datetime.strptime(self.joindatetextbox.text(), "%d-%m-%Y") joining_date = datetime.datetime.strftime(date, "%Y-%m-%d") except: ''' Make sure to add an error message. ''' return if employee_name != "" and salary != "": query = "insert into employee (`employee_name`, `job_title`,`salary`, `joining_date`)" \ "values (%s, %s, %s, %s);" values = (employee_name, job_title, salary, joining_date) result = self.db.execute(query, values) self.closeEvent = self.message() def message(self): self.closing.emit(1) self.close() # def closeEvent(self, event): # print("Closed") # self.closing.emit() # # self.parent.update()
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1920, 1080) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout_3 = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout_3.setObjectName("gridLayout_3") self.Tab1 = QtWidgets.QTabWidget(self.centralwidget) self.Tab1.setLocale( QtCore.QLocale(QtCore.QLocale.Russian, QtCore.QLocale.Russia)) self.Tab1.setObjectName("Tab1") self.tab = QtWidgets.QWidget() self.tab.setObjectName("tab") self.gridLayout = QtWidgets.QGridLayout(self.tab) self.gridLayout.setObjectName("gridLayout") self.groupBoxButtons = QGroupBox(self.tab) self.groupBoxButtons.setObjectName(u"groupBoxButtons") self.groupBoxButtons.setMaximumSize(QSize(100, 16777215)) self.formLayout = QFormLayout(self.groupBoxButtons) self.gridLayout.addWidget(self.groupBoxButtons, 0, 1, 6, 1) self.ButtonAddLeg = QtWidgets.QPushButton(self.groupBoxButtons) self.ButtonAddLeg.setObjectName("ButtonAddLeg") self.formLayout.setWidget(2, QFormLayout.LabelRole, self.ButtonAddLeg) self.pushButtonDelLeg = QtWidgets.QPushButton(self.groupBoxButtons) self.pushButtonDelLeg.setObjectName(u"pushButtonDelLeg") self.pushButtonDelLeg.setText(u"Del Leg") self.formLayout.setWidget(3, QFormLayout.LabelRole, self.pushButtonDelLeg) self.calendarWidget = QtWidgets.QCalendarWidget(self.tab) self.calendarWidget.setObjectName("calendarWidget") self.gridLayout.addWidget(self.calendarWidget, 0, 0, 6, 1, QtCore.Qt.AlignLeft) self.calendarWidget.setGridVisible(True) self.ButtonAddAC = QtWidgets.QPushButton(self.groupBoxButtons) self.ButtonAddAC.setObjectName("ButtonAddAC") self.formLayout.setWidget(0, QFormLayout.LabelRole, self.ButtonAddAC) self.pushButtonDelAC = QtWidgets.QPushButton(self.groupBoxButtons) self.pushButtonDelAC.setObjectName("pushButtonDelAC") self.pushButtonDelAC.setText(u"Del A/C") self.formLayout.setWidget(1, QFormLayout.LabelRole, self.pushButtonDelAC) self.tableViewAcft = QtWidgets.QTableView(self.tab) self.tableViewAcft.setObjectName(u"tableViewAcft") self.gridLayout.addWidget(self.tableViewAcft, 0, 2, 6, 1, QtCore.Qt.AlignLeft) self.tableViewAcft.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.tableViewAcft.horizontalHeader().setStretchLastSection(False) self.tableViewAcft.setMaximumSize(QSize(140, 16777215)) self.model = QtGui.QStandardItemModel(self.tab) self.tableLog = QtWidgets.QTableView(self.tab) self.tableLog.setModel(self.model) self.tableLog.setObjectName("tableLog") self.gridLayout.addWidget(self.tableLog, 6, 0, 1, 6) self.tableLog.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.tableLog.horizontalHeader().setStretchLastSection(False) self.tableLog.setSortingEnabled(True) self.tableLog.setAlternatingRowColors(True) self.Tab1.addTab(self.tab, "") self.tab_2 = QtWidgets.QWidget() self.tab_2.setObjectName("tab_2") self.Tab1.addTab(self.tab_2, "") self.gridLayout_3.addWidget(self.Tab1, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1920, 30)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.lcdNumber = QtWidgets.QLCDNumber(self.tab) self.lcdNumber.setObjectName(u"lcdNumber") self.lcdNumber.setMinimumSize(QtCore.QSize(300, 0)) self.lcdNumber.setDigitCount(8) self.gridLayout.addWidget(self.lcdNumber, 2, 5, 2, 1, QtCore.Qt.AlignLeft) self.lcdNumberBLK = QtWidgets.QLCDNumber(self.tab) self.lcdNumberBLK.setObjectName(u"lcdNumberBLK") self.lcdNumberBLK.setMinimumSize(QtCore.QSize(300, 0)) self.lcdNumberBLK.setDigitCount(8) self.gridLayout.addWidget(self.lcdNumberBLK, 0, 5, 2, 1, QtCore.Qt.AlignLeft) self.lcdNumberNight = QtWidgets.QLCDNumber(self.tab) self.lcdNumberNight.setObjectName(u"lcdNumberNight") self.lcdNumberNight.setMinimumSize(QtCore.QSize(300, 0)) self.lcdNumberNight.setDigitCount(8) self.gridLayout.addWidget(self.lcdNumberNight, 4, 5, 2, 1, QtCore.Qt.AlignLeft) self.label_3 = QtWidgets.QLabel(self.tab) self.label_3.setObjectName(u"label_3") self.label_3.setEnabled(True) font = QtGui.QFont() font.setPointSize(30) font.setBold(True) font.setWeight(75) self.label_3.setFont(font) self.label_3.setText( u"<html><head/><body><p>Night Time </p></body></html>") self.label_3.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) self.gridLayout.addWidget(self.label_3, 4, 4, 2, 1, QtCore.Qt.AlignLeft) self.label_2 = QtWidgets.QLabel(self.tab) self.label_2.setObjectName(u"label_2") self.label_2.setFont(font) self.label_2.setText( u"<html><head/><body><p>Flight Time </p></body></html>") self.label_2.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) self.gridLayout.addWidget(self.label_2, 2, 4, 2, 1, QtCore.Qt.AlignLeft) self.label = QtWidgets.QLabel(self.tab) self.label.setObjectName(u"label") self.label.setFont(font) self.label.setText( u"<html><head/><body><p>Block Time </p></body></html>") self.label.setTextFormat(QtCore.Qt.AutoText) self.label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) self.gridLayout.addWidget(self.label, 0, 4, 2, 1, QtCore.Qt.AlignLeft) self.groupBoxFilters = QGroupBox(self.tab) self.groupBoxFilters.setObjectName(u"groupBoxFilters") self.groupBoxFilters.setToolTip(u"") self.groupBoxFilters.setStatusTip(u"") self.groupBoxFilters.setWhatsThis(u"") self.groupBoxFilters.setAccessibleName(u"") self.groupBoxFilters.setAccessibleDescription(u"") self.groupBoxFilters.setTitle(u"Filters") self.gridLayout_2 = QGridLayout(self.groupBoxFilters) self.gridLayout_2.setObjectName(u"gridLayout_2") self.gridLayout.addWidget(self.groupBoxFilters, 0, 3, 6, 1, QtCore.Qt.AlignLeft) self.radioButton12Month = QRadioButton(self.groupBoxFilters) self.buttonGroupFilter = QButtonGroup(MainWindow) self.buttonGroupFilter.setObjectName(u"buttonGroupFilter") self.buttonGroupFilter.addButton(self.radioButton12Month) self.radioButton12Month.setObjectName(u"radioButton12Month") self.radioButton12Month.setToolTip(u"") self.radioButton12Month.setStatusTip(u"") self.radioButton12Month.setWhatsThis(u"") self.radioButton12Month.setAccessibleName(u"") self.radioButton12Month.setAccessibleDescription(u"") self.radioButton12Month.setText(u"Last 12 Month") self.gridLayout_2.addWidget(self.radioButton12Month, 2, 1, 1, 1) self.radioButtonDateToDate = QRadioButton(self.groupBoxFilters) self.buttonGroupFilter.addButton(self.radioButtonDateToDate) self.radioButtonDateToDate.setObjectName(u"radioButtonDateToDate") self.radioButtonDateToDate.setToolTip(u"") self.radioButtonDateToDate.setStatusTip(u"") self.radioButtonDateToDate.setWhatsThis(u"") self.radioButtonDateToDate.setAccessibleName(u"") self.radioButtonDateToDate.setAccessibleDescription(u"") self.radioButtonDateToDate.setText(u"From Date To Date") self.gridLayout_2.addWidget(self.radioButtonDateToDate, 4, 1, 1, 1) self.radioButtonPrDay = QRadioButton(self.groupBoxFilters) self.buttonGroupFilter.addButton(self.radioButtonPrDay) self.radioButtonPrDay.setObjectName(u"radioButtonPrDay") self.radioButtonPrDay.setToolTip(u"") self.radioButtonPrDay.setStatusTip(u"") self.radioButtonPrDay.setWhatsThis(u"") self.radioButtonPrDay.setAccessibleName(u"") self.radioButtonPrDay.setAccessibleDescription(u"") self.radioButtonPrDay.setText(u"Previous Day") self.gridLayout_2.addWidget(self.radioButtonPrDay, 0, 0, 1, 1) self.radioButton30days = QRadioButton(self.groupBoxFilters) self.buttonGroupFilter.addButton(self.radioButton30days) self.radioButton30days.setObjectName(u"radioButton30days") self.radioButton30days.setToolTip(u"") self.radioButton30days.setStatusTip(u"") self.radioButton30days.setWhatsThis(u"") self.radioButton30days.setAccessibleName(u"") self.radioButton30days.setAccessibleDescription(u"") self.radioButton30days.setText(u"Last 30 Days") self.gridLayout_2.addWidget(self.radioButton30days, 0, 1, 1, 1) self.radioButtonPrYear = QRadioButton(self.groupBoxFilters) self.buttonGroupFilter.addButton(self.radioButtonPrYear) self.radioButtonPrYear.setObjectName(u"radioButtonPrYear") self.radioButtonPrYear.setToolTip(u"") self.radioButtonPrYear.setStatusTip(u"") self.radioButtonPrYear.setWhatsThis(u"") self.radioButtonPrYear.setAccessibleName(u"") self.radioButtonPrYear.setAccessibleDescription(u"") self.radioButtonPrYear.setText(u"Previous Year") self.gridLayout_2.addWidget(self.radioButtonPrYear, 4, 0, 1, 1) self.radioButtonPrMonth = QRadioButton(self.groupBoxFilters) self.buttonGroupFilter.addButton(self.radioButtonPrMonth) self.radioButtonPrMonth.setObjectName(u"radioButtonPrMonth") self.radioButtonPrMonth.setToolTip(u"") self.radioButtonPrMonth.setStatusTip(u"") self.radioButtonPrMonth.setWhatsThis(u"") self.radioButtonPrMonth.setAccessibleName(u"") self.radioButtonPrMonth.setAccessibleDescription(u"") self.radioButtonPrMonth.setText(u"Previous Month") self.gridLayout_2.addWidget(self.radioButtonPrMonth, 2, 0, 1, 1) self.dateEditFilterFrom = QDateEdit(self.groupBoxFilters) self.dateEditFilterFrom.setObjectName(u"dateEditFilterFrom") self.dateEditFilterFrom.setToolTip(u"") self.dateEditFilterFrom.setStatusTip(u"") self.dateEditFilterFrom.setWhatsThis(u"") self.dateEditFilterFrom.setAccessibleName(u"") self.dateEditFilterFrom.setAccessibleDescription(u"") self.dateEditFilterFrom.setSpecialValueText(u"") self.dateEditFilterFrom.setDisplayFormat(u"dd.MM.yyyy") self.dateEditFilterFrom.setCalendarPopup(True) self.dateEditFilterFrom.setTimeSpec(Qt.UTC) self.gridLayout_2.addWidget(self.dateEditFilterFrom, 5, 0, 1, 1) self.dateEditFilterTo = QDateEdit(self.groupBoxFilters) self.dateEditFilterTo.setObjectName(u"dateEditFilterTo") self.dateEditFilterTo.setToolTip(u"") self.dateEditFilterTo.setStatusTip(u"") self.dateEditFilterTo.setWhatsThis(u"") self.dateEditFilterTo.setAccessibleName(u"") self.dateEditFilterTo.setAccessibleDescription(u"") self.dateEditFilterTo.setSpecialValueText(u"") self.dateEditFilterTo.setDisplayFormat(u"dd.MM.yyyy") self.dateEditFilterTo.setCalendarPopup(True) self.dateEditFilterTo.setTimeSpec(Qt.UTC) self.gridLayout_2.addWidget(self.dateEditFilterTo, 5, 1, 1, 1) self.pushButtonAppFilter = QPushButton(self.groupBoxFilters) self.pushButtonAppFilter.setObjectName(u"pushButtonAppFilter") self.pushButtonAppFilter.setToolTip(u"") self.pushButtonAppFilter.setStatusTip(u"") self.pushButtonAppFilter.setWhatsThis(u"") self.pushButtonAppFilter.setAccessibleName(u"") self.pushButtonAppFilter.setAccessibleDescription(u"") self.pushButtonAppFilter.setText(u"Apply Filter") self.gridLayout_2.addWidget(self.pushButtonAppFilter, 7, 0, 1, 1) self.pushButtonResetFilter = QPushButton(self.groupBoxFilters) self.pushButtonResetFilter.setObjectName(u"pushButtonResetFilter") self.pushButtonResetFilter.setToolTip(u"") self.pushButtonResetFilter.setStatusTip(u"") self.pushButtonResetFilter.setWhatsThis(u"") self.pushButtonResetFilter.setAccessibleName(u"") self.pushButtonResetFilter.setAccessibleDescription(u"") self.pushButtonResetFilter.setText(u"Reset Filter") self.gridLayout_2.addWidget(self.pushButtonResetFilter, 7, 1, 1, 1) self.retranslateUi(MainWindow) self.Tab1.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle( _translate("Yet Another Log Book", "Yet Another Log Book")) self.ButtonAddLeg.setText(_translate("MainWindow", "Add Leg")) self.ButtonAddAC.setText(_translate("MainWindow", "Add A/C")) self.Tab1.setTabText(self.Tab1.indexOf(self.tab), _translate("MainWindow", "Log Book")) self.Tab1.setTabText(self.Tab1.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
class EditFinanceCalendarWidget(QWidget): def __init__(self): super(EditFinanceCalendarWidget, self).__init__() layout = QVBoxLayout(margin=0) layout.setParent(self) date_layout = QHBoxLayout() date_layout.addWidget(QLabel("日期:", self)) self.date_edit = QDateEdit(QDate.currentDate(), self) self.date_edit.setDisplayFormat("yyyy-MM-dd") date_layout.addWidget(self.date_edit) date_layout.addStretch() layout.addLayout(date_layout) time_layout = QHBoxLayout() time_layout.addWidget(QLabel("时间:", self)) self.time_edit = QTimeEdit(QTime.currentTime(), self) self.time_edit.setDisplayFormat('hh:mm:ss') time_layout.addWidget(self.time_edit) time_layout.addStretch() layout.addLayout(time_layout) area_layout = QHBoxLayout() area_layout.addWidget(QLabel('地区:', self)) self.area_edit = QLineEdit(self) area_layout.addWidget(self.area_edit) layout.addLayout(area_layout) event_layout = QHBoxLayout() event_layout.addWidget(QLabel('事件:', self), alignment=Qt.AlignTop) self.event_edit = QTextEdit(self) self.event_edit.setFixedHeight(100) event_layout.addWidget(self.event_edit) layout.addLayout(event_layout) expected_layout = QHBoxLayout() expected_layout.addWidget(QLabel('预期值:', self)) self.expected_edit = QLineEdit(self) expected_layout.addWidget(self.expected_edit) layout.addLayout(expected_layout) self.commit_button = QPushButton("提交", self) self.commit_button.clicked.connect(self.commit_financial_calendar) layout.addWidget(self.commit_button, alignment=Qt.AlignRight) self.setLayout(layout) def commit_financial_calendar(self): date = self.date_edit.text().strip() time = self.time_edit.text().strip() area = self.area_edit.text().strip() event = self.event_edit.toPlainText() expected = self.expected_edit.text().strip() if not all([date, time, area, event]): QMessageBox.information(self, "错误", "请填写完整信息") return try: r = requests.post( url=settings.SERVER_ADDR + 'fecalendar/', headers={"Content-Type": "application/json;charset=utf8"}, data=json.dumps({ 'utoken': settings.app_dawn.value('AUTHORIZATION'), 'date': date, 'time': time, 'country': area, 'event': event, 'expected': expected, })) response = json.loads(r.content.decode('utf8')) if r.status_code != 201: raise ValueError(response['message']) except Exception as e: QMessageBox.information(self, '错误', str(e)) else: QMessageBox.information(self, "成功", response['message'])
class EditSpotMessageWidget(QWidget): commit_successful = pyqtSignal() def __init__(self, *args, **kwargs): super(EditSpotMessageWidget, self).__init__(*args, **kwargs) layout = QVBoxLayout(self) date_layout = QHBoxLayout(self) date_layout.addWidget(QLabel("日期:", self)) self.custom_time_edit = QDateEdit(QDate.currentDate(), parent=self) self.custom_time_edit.setCalendarPopup(True) self.custom_time_edit.setDisplayFormat("yyyy-MM-dd") date_layout.addWidget(self.custom_time_edit) date_layout.addStretch() layout.addLayout(date_layout) name_layout = QHBoxLayout(self) name_layout.addWidget(QLabel("名称:", self)) self.name_edit = QLineEdit(self) name_layout.addWidget(self.name_edit) layout.addLayout(name_layout) area_layout = QHBoxLayout(self) area_layout.addWidget(QLabel("地区:", self)) self.area_edit = QLineEdit(self) area_layout.addWidget(self.area_edit) layout.addLayout(area_layout) level_layout = QHBoxLayout(self) level_layout.addWidget(QLabel("等级:", self)) self.level_edit = QLineEdit(self) level_layout.addWidget(self.level_edit) layout.addLayout(level_layout) price_layout = QHBoxLayout(self) price_layout.addWidget(QLabel("价格:", self)) self.price_edit = QLineEdit(self) decimal_validator = QRegExpValidator( QRegExp(r"[-]{0,1}[0-9]+[.]{1}[0-9]+")) self.price_edit.setValidator(decimal_validator) price_layout.addWidget(self.price_edit) layout.addLayout(price_layout) increase_layout = QHBoxLayout(self) increase_layout.addWidget(QLabel("增减:", self)) self.increase_edit = QLineEdit(self) self.increase_edit.setValidator(decimal_validator) increase_layout.addWidget(self.increase_edit) layout.addLayout(increase_layout) self.commit_button = QPushButton("确认提交", self) self.commit_button.clicked.connect(self.commit_spot) layout.addWidget(self.commit_button, alignment=Qt.AlignRight) self.setLayout(layout) def commit_spot(self): date = self.custom_time_edit.text() name = self.name_edit.text().strip() area = self.area_edit.text().strip() level = self.level_edit.text().strip() price = self.price_edit.text().strip() increase = self.increase_edit.text().strip() if not all([name, level, price]): QMessageBox.information(self, "错误", "请填写完整信息") return try: r = requests.post( url=settings.SERVER_ADDR + 'spot/', headers={"Content-Type": "application/json;charset=utf8"}, data=json.dumps({ 'utoken': settings.app_dawn.value('AUTHORIZATION'), 'custom_time': date, 'name': name, 'area': area, 'level': level, 'price': price, 'increase': increase })) response = json.loads(r.content.decode('utf8')) if r.status_code != 201: raise ValueError(response['message']) except Exception as e: QMessageBox.information(self, '错误', str(e)) else: QMessageBox.information(self, "成功", response['message']) self.commit_successful.emit()
class MainWindow(QWidget): articleInfoUpdate = pyqtSignal() entityUpdate = pyqtSignal() crawlerUpdate = pyqtSignal() def __init__(self): super(MainWindow, self).__init__() self.initUI() self.articleInfoUpdate.connect(self.updateArticleInfo) self.entityUpdate.connect(self.updateEntityList) def initUI(self): self.setGeometry(0, 0, 500, 700) self.center() self.setWindowTitle('PView') mainLayout = QVBoxLayout() self.createArticleInfoBox() self.createViewArticleBox() self.createEntityBox() self.createReportBox() self.createDatabaseBox() mainLayout.addWidget(self.infoBox) mainLayout.addWidget(self.viewArticleBox) mainLayout.addWidget(self.entityBox) mainLayout.addWidget(self.raportBox) mainLayout.addWidget(self.databaseBox) self.setLayout(mainLayout) self.show() def createArticleInfoBox(self): self.articleCount = self.selectCountArticles() entityCount = self.selectCountEntities() associationsCount = self.selectCountAssociations() classifiedCount = self.selectCountClassifiedAssociations() label = "Number of articles: " + str(self.articleCount) self.articleCountLabel = QLabel(label) label = "Number of entities: " + str(entityCount) self.entitiesCountLabel = QLabel(label) label = "Number of associations: " + str(associationsCount) self.associationsCountLabel = QLabel(label) label = "Number of classified associations: " + str(classifiedCount) self.classifiedCountLabel = QLabel(label) layout = QVBoxLayout() layout.addWidget(self.articleCountLabel) layout.addWidget(self.entitiesCountLabel) layout.addWidget(self.associationsCountLabel) layout.addWidget(self.classifiedCountLabel) self.infoBox = QGroupBox("Statistics") self.infoBox.setLayout(layout) def createCrawlerBox(self): self.crawlButton = QPushButton("Crawl") self.crawlButton.setFocusPolicy(Qt.NoFocus) self.websiteList = QComboBox() self.websiteList.addItem("HotNews") layout = QGridLayout() layout.addWidget(self.websiteList, 0, 0, 1, 1) layout.addWidget(self.crawlButton, 0, 1, 1, 1) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 1) self.crawlerBox = QGroupBox("Crawler") self.crawlerBox.setLayout(layout) def createViewArticleBox(self): self.articleNumberLineEdit = QLineEdit("") self.articleNumberLineEdit.setAlignment(Qt.AlignHCenter) self.viewArticleButton = QPushButton("Open") self.viewArticleButton.clicked.connect(self.viewArticle) layout = QGridLayout() layout.addWidget(self.articleNumberLineEdit, 0, 0, 1, 1) layout.addWidget(self.viewArticleButton, 0, 1, 1, 1) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 1) self.viewArticleBox = QGroupBox("View Article") self.viewArticleBox.setLayout(layout) def createReportBox(self): minDate, maxDate = self.selectMinAndMaxDate() minDate = QDate(minDate.year, minDate.month, minDate.day) maxDate = QDate(maxDate.year, maxDate.month, maxDate.day) self.fromDateEdit = QDateEdit() self.fromDateEdit.setDate(minDate) self.fromDateEdit.setDisplayFormat('d MMM yyyy') self.fromDateEdit.setAlignment(Qt.AlignHCenter) self.toDateEdit = QDateEdit() self.toDateEdit.setDate(maxDate) self.toDateEdit.setDisplayFormat('d MMM yyyy') self.toDateEdit.setAlignment(Qt.AlignHCenter) self.reportTypeComboBox = QComboBox() for item in reportTypes: self.reportTypeComboBox.addItem(item) monthlyButton = QPushButton("View") monthlyButton.clicked.connect(self.createReport) layout = QGridLayout() layout.addWidget(self.fromDateEdit, 0, 0, 1, 1) layout.addWidget(self.toDateEdit, 0, 1, 1, 1) layout.addWidget(self.reportTypeComboBox, 1, 0, 1, 1) layout.addWidget(monthlyButton, 1, 1, 1, 1) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 1) self.raportBox = QGroupBox("Charts") self.raportBox.setLayout(layout) def createEntityBox(self): rows = self.selectCountEntities() self.entityList = QListWidget() entities = self.selectAllEntities() for entity in entities: self.doAssociationsForEntity(entity[1]) self.entityList.addItem(entity[1]) addButton = QPushButton("Add") addButton.clicked.connect(self.addEntity) removeButton = QPushButton("Delete") removeButton.clicked.connect(self.removeEntity) self.addEntityLineEdit = QLineEdit("") viewArticlesButton = QPushButton("View articles") viewArticlesButton.clicked.connect(self.viewArticleByEntity) self.algorithmComboBox = QComboBox() for key in classifiers.keys(): self.algorithmComboBox.addItem(key) classifyButton = QPushButton("Classify") classifyButton.clicked.connect(self.classifyAllAssociations) layout = QGridLayout() layout.addWidget(self.entityList, 0, 0, 1, 4) layout.addWidget(self.addEntityLineEdit, 1, 0, 1, 2) layout.addWidget(addButton, 1, 2, 1, 1) layout.addWidget(removeButton, 1, 3, 1, 1) layout.addWidget(viewArticlesButton, 2, 0, 1, 4) layout.addWidget(self.algorithmComboBox, 3, 0, 1, 2) layout.addWidget(classifyButton, 3, 2, 1, 2) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 1) layout.setColumnStretch(2, 1) layout.setColumnStretch(3, 1) self.entityBox = QGroupBox("Entities") self.entityBox.setLayout(layout) def createDatabaseBox(self): deleteClassificationsButton = QPushButton("Remove all classifications") deleteClassificationsButton.clicked.connect(self.clearAllCalculatedPolarities) deleteEntitiesButton = QPushButton("Remove all entities") deleteEntitiesButton.clicked.connect(self.deleteAllEntities) deleteAssociationsButton = QPushButton("Remove all associations") deleteAssociationsButton.clicked.connect(self.deleteAllAssociations) layout = QVBoxLayout() layout.addWidget(deleteClassificationsButton) layout.addWidget(deleteAssociationsButton) layout.addWidget(deleteEntitiesButton) self.databaseBox = QGroupBox("Database") self.databaseBox.setLayout(layout) def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def monthsBetweenDates(self, fromDate, toDate): curDate = QDate(fromDate) months =[] while curDate < toDate: months.append(curDate) curDate = curDate.addMonths(1) return months def makeMonthlyPolarityChart(self, entities, fromDate, toDate): cursor = mysql_conn.cursor() chartData = [] for (entityId, entity) in entities: monthlyPol = self.selectAllPolaritiesForEntity(entityId, fromDate, toDate) trace0=Bar( x = [self.monthYearLabel(month) for (month, _, _) in monthlyPol], y = [(0.0 + rows.count(1L)) / (l+1) * 100 for (_, l, rows) in monthlyPol], name = entity, marker = Marker( color = 'rgb(204,204,204)', opacity = 0.5, ), ) chartData.append(trace0) chartData = Data(chartData) layout = Layout( xaxis=XAxis( #set x-axis' labels direction at 45 degree angle tickangle=-45, ), barmode='group', ) fig = Figure(data = chartData, layout = layout) py.image.save_as({'data': chartData}, "polarities.png") img = Image.open("polarities.png") img.show() def makeMonthlyAppearanceChart(self, entities, fromDate, toDate): cursor = mysql_conn.cursor() chartData = [] for (entityId, entity) in entities: monthlyApp = self.selectCountAssociationsForEntityBetweenDates(entityId, fromDate, toDate) trace0=Bar( x = [self.monthYearLabel(month) for (month, _) in monthlyApp], y = [count for (_, count) in monthlyApp], name = entity, marker = Marker( color = 'rgb(204,204,204)', opacity = 0.5, ), ) chartData.append(trace0) chartData = Data(chartData) layout = Layout( xaxis=XAxis( #set x-axis' labels direction at 45 degree angle tickangle=-45, ), barmode='group', ) fig = Figure(data = chartData, layout = layout) py.image.save_as({'data': chartData}, "appearances.png") img = Image.open("appearances.png") img.show() def getStringDate(self, date): sDate = str(date.year()) sDate += '-'+str(date.month()) sDate += '-'+'01' time = '00:00:00' return sDate + ' ' + time def monthYearLabel(self, date): label = monthIntToString[date.month()] + ' ' label += str(date.year()) return label def createReport(self): reportType = self.reportTypeComboBox.currentText() fromDate = self.fromDateEdit.date() toDate = self.toDateEdit.date() entities = [] if "All entities" in reportType: entities = self.selectAllEntities() else: selected = self.entityList.selectedItems() if len(selected) == 1: entity = selected[0].text() entities = [(self.selectEntityId(entity), entity)] if len(entities) > 0: if "Opinions" in reportType: self.makeMonthlyPolarityChart(entities, fromDate, toDate) else: print entities self.makeMonthlyAppearanceChart(entities, fromDate, toDate) def viewArticle(self): try: articleId = int(self.articleNumberLineEdit.text()) if articleId > 0 and articleId < self.articleCount: self.viewArticleButton.setEnabled(False) self.articleNumberLineEdit.setDisabled(True) articleList = [i+1 for i in xrange(self.articleCount)] articleView = Article(articleId-1, articleList, parentW=self) articleView.exec_() self.viewArticleButton.setEnabled(True) self.articleNumberLineEdit.setDisabled(False) except ValueError: print "Invalid article id" def viewArticleByEntity(self): selected = self.entityList.selectedItems() if len(selected) == 1: articles = self.selectAllArticlesByEntity(selected[0].text()) articleList = [a[0] for a in articles] articleView = Article(0, articleList, shuffle_=True, parentW=self) articleView.exec_() def addEntity(self): newEntity = self.addEntityLineEdit.text().strip() newEntity = re.sub(r' +', ' ', newEntity) cursor = mysql_conn.cursor() if len(newEntity) != 0: selectStmt = """SELECT * FROM entities WHERE entity=%s""" data = (newEntity,) cursor.execute(selectStmt, data) rows = cursor.fetchall() if len(rows) == 0: insertStmt = """INSERT INTO entities (entity) VALUES (%s)""" data = (newEntity,) cursor.execute(insertStmt, data) cursor.execute("""COMMIT""") self.entityUpdate.emit() self.doAssociationsForEntity(newEntity) self.addEntityLineEdit.setText("") def removeEntity(self): selected = self.entityList.selectedItems() cursor = mysql_conn.cursor() for item in selected: self.deleteAssciationsForEntity(item.text()) selectStmt = """SELECT entity_id FROM entities WHERE entity=%s""" data = (item.text(),) cursor.execute(selectStmt, data) entityId = cursor.fetchone() deleteStmt = """DELETE FROM entities WHERE entity_id=%s""" data = (entityId[0],) cursor.execute(deleteStmt, data) cursor.execute("""COMMIT""") self.entityUpdate.emit() def updateEntityList(self): self.entityList.clear() entities = self.selectAllEntities() for entity in entities: self.entityList.addItem(entity[1]) label = "Number of entities: " + str(len(entities)) self.entitiesCountLabel.setText(label) def updateArticleInfo(self): self.articleCount = self.selectCountArticles() entityCount = self.selectCountEntities() associationsCount = self.selectCountAssociations() classifiedCount = self.selectCountClassifiedAssociations() label = "Number of articles: " + str(self.articleCount) self.articleCountLabel.setText(label) label = "Number of entities: " + str(entityCount) self.entitiesCountLabel.setText(label) label = "Number of classified associations: " + str(classifiedCount) self.classifiedCountLabel.setText(label) label = "Number of associations: " + str(associationsCount) self.associationsCountLabel.setText(label) def classifyAllAssociations(self): cursor = mysql_conn.cursor() entities = self.selectAllEntities() for (entityId, entity) in entities: manualPol = self.selectManualPolaritiesForEntity(entityId) trainingData = [self.selectArticle(id_)[4] for (id_, _) in manualPol] trainingTarget = [polarity for (_, polarity) in manualPol] algorithm = self.algorithmComboBox.currentText() textClf = Pipeline([('vect', CountVectorizer()), ('tfidf', TfidfTransformer()), ('clf', classifiers[algorithm]), ]) textClf.fit(trainingData, trainingTarget) # select all articles associated with entity that need to be classified selectStmt = """SELECT article_id FROM assocEntityArticle WHERE polarity_manual IS NULL AND polarity_calculated IS NULL AND entity_id=%s""" data = (entityId,) cursor.execute(selectStmt, data) ids = cursor.fetchall() if len(ids) > 0: ids = [a[0] for a in ids] testData = [self.selectArticle(id_)[4] for id_ in ids] predicted = textClf.predict(testData) print [x for x in predicted].count(1) updateData = zip(predicted, ids) updateData = [(polarity, entityId, id_) for (polarity, id_) in updateData] updateStmt = """UPDATE assocEntityArticle SET polarity_calculated=%s WHERE entity_id=%s AND article_id=%s""" cursor.executemany(updateStmt, updateData) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() def selectArticle(self, articleId): cursor = mysql_conn.cursor() selectStmt = """SELECT * FROM articles WHERE article_id=%s""" data = (articleId,) cursor.execute(selectStmt, data) row = cursor.fetchone() return row def selectEntityId(self, entity): cursor = mysql_conn.cursor() selectStmt = """SELECT entity_id FROM entities WHERE entity=%s""" data = (entity,) cursor.execute(selectStmt, data) entityId = cursor.fetchone()[0] return entityId def selectAllArticlesByEntity(self, entity): cursor = mysql_conn.cursor() selectStmt = """SELECT * FROM articles WHERE content LIKE %s""" data = ("%" + entity + "%",) cursor.execute(selectStmt, data) rows = cursor.fetchall() return rows def selectAllEntities(self): cursor = mysql_conn.cursor() selectStmt = """SELECT * FROM entities""" cursor.execute(selectStmt) rows = cursor.fetchall() return rows def selectMinAndMaxDate(self): cursor = mysql_conn.cursor() selectStmt = """SELECT MIN(date), MAX(date) FROM articles""" cursor.execute(selectStmt) row = cursor.fetchone() return row def selectCountArticles(self): cursor = mysql_conn.cursor() selectStmt = """SELECT count(*) FROM articles""" cursor.execute(selectStmt) row = cursor.fetchone() return row[0] def selectCountAuthors(self): cursor = mysql_conn.cursor() selectStmt = """SELECT count(*) FROM authors""" cursor.execute(selectStmt) row = cursor.fetchone() return row[0] def selectCountEntities(self): cursor = mysql_conn.cursor() selectStmt = """SELECT count(*) FROM entities""" cursor.execute(selectStmt) row = cursor.fetchone() return row[0] def selectCountAssociations(self): cursor = mysql_conn.cursor() selectStmt = """SELECT count(*) FROM assocEntityArticle""" cursor.execute(selectStmt) row = cursor.fetchone() return row[0] def selectCountAssociationsForEntityBetweenDates(self, entityId, fromDate, toDate): cursor = mysql_conn.cursor() months = self.monthsBetweenDates(fromDate, toDate) selectStmt = """SELECT count(*) FROM assocEntityArticle a, articles b WHERE a.article_id = b.article_id AND b.date BETWEEN %s AND %s AND a.entity_id=%s""" associations = [] if len(months) != 0: for month in months: fromDateString = self.getStringDate(month) toDateString = self.getStringDate(month.addMonths(1)) data = (fromDateString, toDateString, entityId) cursor.execute(selectStmt, data) count = cursor.fetchone()[0] associations.append((month, count)) return associations def selectCountClassifiedAssociations(self): cursor = mysql_conn.cursor() selectStmt = """SELECT count(*) FROM assocEntityArticle WHERE polarity_calculated IS NOT NULL OR polarity_manual IS NOT NULL""" cursor.execute(selectStmt) row = cursor.fetchone() return row[0] def selectManualPolaritiesForEntity(self, entityId): cursor = mysql_conn.cursor() selectStmt = """SELECT article_id, polarity_manual FROM assocEntityArticle WHERE polarity_manual IS NOT NULL AND entity_id=%s""" data = (entityId,) cursor.execute(selectStmt, data) rows = cursor.fetchall() return rows def selectAllPolaritiesForEntity(self, entityId, fromDate, toDate): cursor = mysql_conn.cursor() months = self.monthsBetweenDates(fromDate, toDate) selectStmt = """SELECT a.polarity_manual, a.polarity_calculated FROM assocEntityArticle a, articles b WHERE (a.polarity_manual IS NOT NULL OR a.polarity_calculated IS NOT NULL) AND a.article_id = b.article_id AND b.date BETWEEN %s AND %s AND a.entity_id=%s""" polarities = [] if len(months) != 0: for month in months: fromDateString = self.getStringDate(month) toDateString = self.getStringDate(month.addMonths(1)) data = (fromDateString, toDateString, entityId) cursor.execute(selectStmt, data) rows = cursor.fetchall() rows = [a or b for a, b in rows] polarities.append((month, len(rows), rows)) return polarities def doAssociationsForEntity(self, entity): cursor = mysql_conn.cursor() # select entity_id for entity given as parameter entityId = self.selectEntityId(entity) # select list of article_id for which associations exist # in database for entity given as param selectStmt = """SELECT article_id FROM assocEntityArticle WHERE entity_id=%s""" data = (entityId,) cursor.execute(selectStmt, data) articleIdsInDB = cursor.fetchall() articleIdsInDB = [pair[0] for pair in articleIdsInDB] # select all articles that contain entity in content selectStmt = """SELECT article_id FROM articles WHERE content LIKE %s""" data = ("%" + entity + "%",) cursor.execute(selectStmt, data) rows = cursor.fetchall() rows = [pair[0] for pair in rows] # find articles for which associations don't exist in the database diff = list(set(rows) - set(articleIdsInDB)) if len(diff) != 0: insertStmt = """INSERT INTO assocEntityArticle (article_id, entity_id) VALUES (%s, %s)""" data = [(articleId, entityId) for articleId in diff] cursor.executemany(insertStmt, data) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() def deleteAssciationsForEntity(self, entity): cursor = mysql_conn.cursor() selectStmt = """SELECT entity_id FROM entities WHERE entity=%s""" data = (entity,) cursor.execute(selectStmt, data) entityId = cursor.fetchone()[0] deleteStmt = """DELETE FROM assocEntityArticle WHERE entity_id=%s""" data = (entityId,) cursor.execute(deleteStmt, data) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() def doAllAssociations(self): cursor = mysql_conn.cursor() entities = self.selectAllEntities() for entity in entities: self.doAssociationsForEntity(entity) self.articleInfoUpdate.emit() def deleteAllAssociations(self): cursor = mysql_conn.cursor() deleteStmt = """DELETE FROM assocEntityArticle WHERE article_id > 0""" cursor.execute(deleteStmt) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() def clearAllCalculatedPolarities(self): cursor = mysql_conn.cursor() updateStmt = """UPDATE assocEntityArticle SET polarity_calculated=%s WHERE polarity_calculated IS NOT NULL""" data = (None,) cursor.execute(updateStmt, data) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() def deleteAllArticles(self): try: cursor = mysql_conn.cursor() deleteStmt = """DELETE FROM articles WHERE article_id > 0""" cursor.execute(deleteStmt) alterTableStmt = """ALTER TABLE articles AUTO_INCREMENT = 1""" cursor.execute(alterTableStmt) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() except IntegrityError: pass def deleteAllAuthors(self): cursor = mysql_conn.cursor() deleteStmt = """DELETE FROM authors WHERE author_id > 0""" cursor.execute(deleteStmt) alterTableStmt = """ALTER TABLE authors AUTO_INCREMENT = 1""" cursor.execute(alterTableStmt) cursor.execute("""COMMIT""") def deleteAllArticlesAndAuthors(self): self.deleteAllArticles() self.deleteAllAuthors() def deleteAllEntities(self): cursor = mysql_conn.cursor() deleteStmt = """DELETE FROM entities WHERE entity_id > 0""" cursor.execute(deleteStmt) alterTableStmt = """ALTER TABLE entities AUTO_INCREMENT = 1""" cursor.execute(alterTableStmt) cursor.execute("""COMMIT""") self.articleInfoUpdate.emit() self.entityUpdate.emit()
class WeatherDataGapfiller(QMainWindow): ConsoleSignal = QSignal(str) def __init__(self, parent=None): super().__init__(parent) self._workdir = None self._corrcoeff_update_inprogress = False self._pending_corrcoeff_update = None self._loading_data_inprogress = False self.__initUI__() # Setup the DataGapfillManager. self.gapfill_manager = DataGapfillManager() self.gapfill_manager.sig_task_progress.connect( self.progressbar.setValue) self.gapfill_manager.sig_status_message.connect( self.set_statusbar_text) def __initUI__(self): self.setWindowIcon(get_icon('master')) # Setup the toolbar at the bottom. self.btn_fill = QPushButton('Gapfill Data') self.btn_fill.setIcon(get_icon('fill_data')) self.btn_fill.setIconSize(get_iconsize('small')) self.btn_fill.setToolTip( "Fill the gaps in the daily weather data of the selected " "weather station.") self.btn_fill.clicked.connect(self._handle_gapfill_btn_clicked) widget_toolbar = QFrame() grid_toolbar = QGridLayout(widget_toolbar) grid_toolbar.addWidget(self.btn_fill, 0, 0) grid_toolbar.setContentsMargins(0, 0, 0, 0) grid_toolbar.setColumnStretch(0, 100) # ---- Target Station groupbox self.target_station = QComboBox() self.target_station.currentIndexChanged.connect( self._handle_target_station_changed) self.target_station_info = QTextEdit() self.target_station_info.setReadOnly(True) self.target_station_info.setMaximumHeight(110) self.btn_refresh_staList = QToolButton() self.btn_refresh_staList.setIcon(get_icon('refresh')) self.btn_refresh_staList.setToolTip( 'Force the reloading of the weather data files') self.btn_refresh_staList.setIconSize(get_iconsize('small')) self.btn_refresh_staList.setAutoRaise(True) self.btn_refresh_staList.clicked.connect( lambda: self.load_data_dir_content(force_reload=True)) self.btn_delete_data = QToolButton() self.btn_delete_data.setIcon(get_icon('delete_data')) self.btn_delete_data.setEnabled(False) self.btn_delete_data.setAutoRaise(True) self.btn_delete_data.setToolTip( 'Remove the currently selected dataset and delete the input ' 'datafile. However, raw datafiles will be kept.') self.btn_delete_data.clicked.connect(self.delete_current_dataset) # Generate the layout for the target station group widget. self.target_widget = QWidget() target_station_layout = QGridLayout(self.target_widget) target_station_layout.setHorizontalSpacing(1) target_station_layout.setColumnStretch(0, 1) target_station_layout.setContentsMargins(0, 0, 0, 0) widgets = [self.target_station, self.btn_refresh_staList, self.btn_delete_data] target_station_layout.addWidget(self.target_station, 1, 0) for col, widget in enumerate(widgets): target_station_layout.addWidget(widget, 1, col) # Setup the gapfill dates. label_From = QLabel('From : ') self.date_start_widget = QDateEdit() self.date_start_widget.setDisplayFormat('dd / MM / yyyy') self.date_start_widget.setEnabled(False) self.date_start_widget.dateChanged.connect( self._update_corrcoeff_table) label_To = QLabel('To : ') self.date_end_widget = QDateEdit() self.date_end_widget.setEnabled(False) self.date_end_widget.setDisplayFormat('dd / MM / yyyy') self.date_end_widget.dateChanged.connect( self._update_corrcoeff_table) self.fillDates_widg = QWidget() gapfilldates_layout = QGridLayout(self.fillDates_widg) gapfilldates_layout.addWidget(label_From, 0, 0) gapfilldates_layout.addWidget(self.date_start_widget, 0, 1) gapfilldates_layout.addWidget(label_To, 1, 0) gapfilldates_layout.addWidget(self.date_end_widget, 1, 1) gapfilldates_layout.setColumnStretch(2, 1) gapfilldates_layout.setContentsMargins(0, 0, 0, 0) # Create the gapfill target station groupbox. target_groupbox = QGroupBox("Fill data for weather station") target_layout = QGridLayout(target_groupbox) target_layout.addWidget(self.target_widget, 0, 0) target_layout.addWidget(self.target_station_info, 1, 0) target_layout.addWidget(self.fillDates_widg, 2, 0) # Setup the left panel. self._regression_model_groupbox = ( self._create_regression_model_settings()) self._station_selection_groupbox = ( self._create_station_selection_criteria()) self.left_panel = QFrame() left_panel_layout = QGridLayout(self.left_panel) left_panel_layout.addWidget(target_groupbox, 0, 0) left_panel_layout.addWidget(self._station_selection_groupbox, 3, 0) left_panel_layout.addWidget(self._regression_model_groupbox, 4, 0) left_panel_layout.addWidget(widget_toolbar, 5, 0) left_panel_layout.setRowStretch(6, 1) left_panel_layout.setContentsMargins(0, 0, 0, 0) # Setup the right panel. self.corrcoeff_textedit = QTextEdit() self.corrcoeff_textedit.setReadOnly(True) self.corrcoeff_textedit.setMinimumWidth(700) self.corrcoeff_textedit.setFrameStyle(0) self.corrcoeff_textedit.document().setDocumentMargin(10) self.sta_display_summary = QTextEdit() self.sta_display_summary.setReadOnly(True) self.sta_display_summary.setFrameStyle(0) self.sta_display_summary.document().setDocumentMargin(10) self.right_panel = QTabWidget() self.right_panel.addTab( self.corrcoeff_textedit, 'Correlation Coefficients') self.right_panel.addTab( self.sta_display_summary, 'Data Overview') # Setup the progressbar. self.progressbar = QProgressBar() self.progressbar.setValue(0) self.progressbar.hide() self.statustext = QLabel() self.statustext.setStyleSheet( "QLabel {background-color: transparent; padding: 0 0 0 3px;}") self.statustext.setMinimumHeight(self.progressbar.minimumHeight()) # Setup the main widget. main_widget = QWidget() main_grid = QGridLayout(main_widget) main_grid.addWidget(self.left_panel, 0, 0) main_grid.addWidget(self.right_panel, 0, 1) main_grid.addWidget(self.progressbar, 1, 0, 1, 2) main_grid.addWidget(self.statustext, 1, 0, 1, 2) main_grid.setColumnStretch(1, 500) main_grid.setRowStretch(0, 500) self.setCentralWidget(main_widget) def _create_station_selection_criteria(self): Nmax_label = QLabel('Nbr. of stations :') self.Nmax = QSpinBox() self.Nmax.setRange(0, 99) self.Nmax.setMinimum(1) self.Nmax.setValue(CONF.get('gapfill_data', 'nbr_of_station', 4)) self.Nmax.setAlignment(Qt.AlignCenter) ttip = ('<p>Distance limit beyond which neighboring stations' ' are excluded from the gapfilling procedure.</p>' '<p>This condition is ignored if set to -1.</p>') distlimit_label = QLabel('Max. Distance :') distlimit_label.setToolTip(ttip) self.distlimit = QSpinBox() self.distlimit.setRange(-1, 9999) self.distlimit.setSingleStep(1) self.distlimit.setValue( CONF.get('gapfill_data', 'max_horiz_dist', 100)) self.distlimit.setToolTip(ttip) self.distlimit.setSuffix(' km') self.distlimit.setAlignment(Qt.AlignCenter) self.distlimit.valueChanged.connect(self._update_corrcoeff_table) ttip = ('<p>Altitude difference limit over which neighboring ' ' stations are excluded from the gapfilling procedure.</p>' '<p>This condition is ignored if set to -1.</p>') altlimit_label = QLabel('Max. Elevation Diff. :') altlimit_label.setToolTip(ttip) self.altlimit = QSpinBox() self.altlimit.setRange(-1, 9999) self.altlimit.setSingleStep(1) self.altlimit.setValue( CONF.get('gapfill_data', 'max_vert_dist', 350)) self.altlimit.setToolTip(ttip) self.altlimit.setSuffix(' m') self.altlimit.setAlignment(Qt.AlignCenter) self.altlimit.valueChanged.connect(self._update_corrcoeff_table) # Setup the main widget. widget = QGroupBox('Stations Selection Criteria') layout = QGridLayout(widget) layout.addWidget(Nmax_label, 0, 0) layout.addWidget(self.Nmax, 0, 1) layout.addWidget(distlimit_label, 1, 0) layout.addWidget(self.distlimit, 1, 1) layout.addWidget(altlimit_label, 2, 0) layout.addWidget(self.altlimit, 2, 1) layout.setColumnStretch(0, 1) return widget def _create_advanced_settings(self): self.full_error_analysis = QCheckBox('Full Error Analysis.') self.full_error_analysis.setChecked(True) fig_opt_layout = QGridLayout() fig_opt_layout.addWidget(QLabel("Figure output format : "), 0, 0) fig_opt_layout.addWidget(self.fig_format, 0, 2) fig_opt_layout.addWidget(QLabel("Figure labels language : "), 1, 0) fig_opt_layout.addWidget(self.fig_language, 1, 2) fig_opt_layout.setContentsMargins(0, 0, 0, 0) fig_opt_layout.setColumnStretch(1, 100) # Setup the main layout. widget = QFrame() layout = QGridLayout(widget) layout.addWidget(self.full_error_analysis, 0, 0) layout.addLayout(fig_opt_layout, 2, 0) layout.setRowStretch(layout.rowCount(), 100) layout.setContentsMargins(10, 0, 10, 0) return widget def _create_regression_model_settings(self): self.RMSE_regression = QRadioButton('Ordinary Least Squares') self.RMSE_regression.setChecked( CONF.get('gapfill_data', 'regression_model', 'OLS') == 'OLS') self.ABS_regression = QRadioButton('Least Absolute Deviations') self.ABS_regression.setChecked( CONF.get('gapfill_data', 'regression_model', 'OLS') == 'LAD') widget = QGroupBox('Regression Model') layout = QGridLayout(widget) layout.addWidget(self.RMSE_regression, 0, 0) layout.addWidget(self.ABS_regression, 1, 0) return widget def set_statusbar_text(self, text): self.statustext.setText(text) @property def workdir(self): return self._workdir def set_workdir(self, dirname): """ Set the working directory to dirname. """ self._workdir = dirname self.gapfill_manager.set_workdir(dirname) self.load_data_dir_content() def delete_current_dataset(self): """ Delete the current dataset source file and force a reload of the input daily weather datafiles. """ current_index = self.target_station.currentIndex() if current_index != -1: basename = self.gapfill_manager.worker().wxdatasets.fnames[ current_index] filename = os.path.join(self.workdir, basename) delete_file(filename) self.load_data_dir_content() def _handle_target_station_changed(self): """Handle when the target station is changed by the user.""" self.btn_delete_data.setEnabled( self.target_station.currentIndex() != -1) self.update_corrcoeff() def get_dataset_names(self): """ Return a list of the names of the dataset that are loaded in memory and listed in the target station dropdown menu. """ return [self.target_station.itemText(i) for i in range(self.target_station.count())] # ---- Correlation coefficients def update_corrcoeff(self): """ Calculate the correlation coefficients and display the results in the GUI. """ if self.target_station.currentIndex() != -1: station_id = self.target_station.currentData() if self._corrcoeff_update_inprogress is True: self._pending_corrcoeff_update = station_id else: self._corrcoeff_update_inprogress = True self.corrcoeff_textedit.setText('') self.gapfill_manager.set_target_station( station_id, callback=self._handle_corrcoeff_updated) def _handle_corrcoeff_updated(self): self._corrcoeff_update_inprogress = False if self._pending_corrcoeff_update is None: self._update_corrcoeff_table() else: self._pending_corrcoeff_update = None self.update_corrcoeff() def _update_corrcoeff_table(self): """ This method plot the correlation coefficient table in the display area. It is separated from the method "update_corrcoeff" because red numbers and statistics regarding missing data for the selected time period can be updated in the table when the user changes the values without having to recalculate the correlation coefficient each time. """ if self.target_station.currentIndex() != -1: table, target_info = ( self.gapfill_manager.worker().generate_correlation_html_table( self.get_gapfill_parameters())) self.corrcoeff_textedit.setText(table) self.target_station_info.setText(target_info) # ---- Load Data def load_data_dir_content(self, force_reload=False): """ Load weater data from valid files contained in the working directory. """ self._pending_corrcoeff_update = None self._loading_data_inprogress = True self.left_panel.setEnabled(False) self.right_panel.setEnabled(False) self.corrcoeff_textedit.setText('') self.target_station_info.setText('') self.target_station.clear() self.gapfill_manager.load_data( force_reload=force_reload, callback=self._handle_data_dir_content_loaded) def _handle_data_dir_content_loaded(self): """ Handle when data finished loaded from valid files contained in the working directory. """ self.left_panel.setEnabled(True) self.right_panel.setEnabled(True) self.target_station.blockSignals(True) station_names = self.gapfill_manager.get_station_names() station_ids = self.gapfill_manager.get_station_ids() for station_name, station_id in zip(station_names, station_ids): self.target_station.addItem( '{} ({})'.format(station_name, station_id), userData=station_id) self.target_station.blockSignals(False) self.sta_display_summary.setHtml( self.gapfill_manager.worker().generate_html_summary_table()) if len(station_names) > 0: self._setup_fill_and_save_dates() self.target_station.blockSignals(True) self.target_station.setCurrentIndex(0) self.target_station.blockSignals(False) self._handle_target_station_changed() self._loading_data_inprogress = False def _setup_fill_and_save_dates(self): """ Set first and last dates of the 'Fill data for weather station'. """ if self.gapfill_manager.count(): self.date_start_widget.setEnabled(True) self.date_end_widget.setEnabled(True) mindate = ( self.gapfill_manager.worker() .wxdatasets.metadata['first_date'].min()) maxdate = ( self.gapfill_manager.worker() .wxdatasets.metadata['last_date'].max()) qdatemin = QDate(mindate.year, mindate.month, mindate.day) qdatemax = QDate(maxdate.year, maxdate.month, maxdate.day) self.date_start_widget.blockSignals(True) self.date_start_widget.setDate(qdatemin) self.date_start_widget.setMinimumDate(qdatemin) self.date_start_widget.setMaximumDate(qdatemax) self.date_start_widget.blockSignals(False) self.date_end_widget.blockSignals(True) self.date_end_widget.setDate(qdatemax) self.date_end_widget.setMinimumDate(qdatemin) self.date_end_widget.setMaximumDate(qdatemax) self.date_end_widget.blockSignals(False) # ---- Gapfill Data def get_gapfill_parameters(self): """ Return a dictionary containing the parameters that are set in the GUI for gapfilling weather data. """ return { 'limitDist': self.distlimit.value(), 'limitAlt': self.altlimit.value(), 'date_start': self.date_start_widget.date().toString('dd/MM/yyyy'), 'date_end': self.date_end_widget.date().toString('dd/MM/yyyy') } def _handle_gapfill_btn_clicked(self): """ Handle when the user clicked on the gapfill button. """ if self.gapfill_manager.count() == 0: QMessageBox.warning( self, 'Warning', "There is no data to fill.", QMessageBox.Ok) return # Check for dates errors. datetime_start = datetime_from_qdatedit(self.date_start_widget) datetime_end = datetime_from_qdatedit(self.date_end_widget) if datetime_start > datetime_end: QMessageBox.warning( self, 'Warning', ("<i>From</i> date is set to a later time than " "the <i>To</i> date."), QMessageBox.Ok) return if self.target_station.currentIndex() == -1: QMessageBox.warning( self, 'Warning', "No weather station is currently selected", QMessageBox.Ok) return self.start_gapfill_target() def _handle_gapfill_target_finished(self): """ Method initiated from an automatic return from the gapfilling process in batch mode. Iterate over the station list and continue process normally. """ self.btn_fill.setIcon(get_icon('fill_data')) self.btn_fill.setEnabled(True) self.target_widget.setEnabled(True) self.fillDates_widg.setEnabled(True) self._regression_model_groupbox.setEnabled(True) self._station_selection_groupbox.setEnabled(True) self.progressbar.setValue(0) QApplication.processEvents() self.progressbar.hide() def start_gapfill_target(self): # Update the gui. self.btn_fill.setEnabled(False) self.fillDates_widg.setEnabled(False) self.target_widget.setEnabled(False) self._regression_model_groupbox.setEnabled(False) self._station_selection_groupbox.setEnabled(False) self.progressbar.show() # Start the gapfill thread. self.gapfill_manager.gapfill_data( time_start=datetime_from_qdatedit(self.date_start_widget), time_end=datetime_from_qdatedit(self.date_end_widget), max_neighbors=self.Nmax.value(), hdist_limit=self.distlimit.value(), vdist_limit=self.altlimit.value(), regression_mode=self.RMSE_regression.isChecked(), callback=self._handle_gapfill_target_finished ) def close(self): CONF.set('gapfill_data', 'nbr_of_station', self.Nmax.value()) CONF.set('gapfill_data', 'max_horiz_dist', self.distlimit.value()) CONF.set('gapfill_data', 'max_vert_dist', self.altlimit.value()) CONF.set('gapfill_data', 'regression_model', 'OLS' if self.RMSE_regression.isChecked() else 'LAD') super().close()
class TaskView(QWidget): close = pyqtSignal() def __init__(self, model): super().__init__() self.header = QLabel('') self.desc = QLineEdit() self.date = QDateEdit() self.time = QTimeEdit() self.init_ui() self.mapper = QDataWidgetMapper() self.mapper.setModel(model) self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self.mapper.addMapping(self.desc, TaskModel.col_desc) self.mapper.addMapping(self.date, TaskModel.col_date) self.mapper.addMapping(self.time, TaskModel.col_time) def set_task(self, index): self.mapper.setCurrentIndex(index) self.header.setText('РЕДАКТИРОВАНИЕ ЗАДАЧИ') # text = 'НОВАЯ ЗАДАЧА' # self.date.setDate(QDate().currentDate()) def create_date(self): self.date.setDisplayFormat('dd.MM.yyyy') self.date.setCalendarPopup(True) self.date.setFixedWidth(120) return self.date def create_time(self): self.time.setDisplayFormat('hh.mm') self.time.setFixedWidth(120) return self.time def create_date_buttons(self): date_lt = QHBoxLayout() btn_now = QPushButton('сегодня') btn_now.clicked.connect(lambda: self.date.setDate(QDate().currentDate())) date_lt.addWidget(btn_now, 0, Qt.AlignCenter) btn_tomorrow = QPushButton('завтра') btn_tomorrow.clicked.connect(lambda: self.date.setDate(QDate().currentDate().addDays(1))) date_lt.addWidget(btn_tomorrow, 0, Qt.AlignCenter) btn_week_later = QPushButton('через неделю') btn_week_later.clicked.connect(lambda: self.date.setDate(QDate().currentDate().addDays(7))) date_lt.addWidget(btn_week_later, 0, Qt.AlignCenter) return date_lt # def create_time_choice(self): # self.time.setMaxVisibleItems(15) # self.time.setStyleSheet('QComboBox { combobox-popup: 0; }') # for it in range(24): # self.time.insertItem(it * 2 + 0, '%.2d:00' % it) # self.time.insertItem(it * 2 + 1, '%.2d:30' % it) # # return self.time def save(self): print('save', self.mapper.submit()) self.close.emit() def cancel(self): self.close.emit() def remove(self): self.mapper.model().removeRow(self.mapper.currentIndex()) self.close.emit() def create_control_buttons(self): control_lt = QHBoxLayout() btn_save = QPushButton('Сохранить') btn_save.clicked.connect(self.save) control_lt.addWidget(btn_save, 0, Qt.AlignCenter) btn_cancel = QPushButton('Отменить') btn_cancel.clicked.connect(self.cancel) control_lt.addWidget(btn_cancel, 0, Qt.AlignCenter) btn_remove = QPushButton('Удалить') btn_remove.clicked.connect(self.remove) control_lt.addWidget(btn_remove, 1, Qt.AlignRight) return control_lt def create_main_form(self): fm = QFormLayout() fm.addRow(self.header) fm.addRow(QLabel('')) fm.addRow(self.desc) fm.addRow(QLabel('')) fm.addRow(QLabel('Когда это нужно сделать?')) fm.addRow(self.create_date()) fm.addRow(self.create_date_buttons()) fm.addRow(QLabel('')) fm.addRow(QLabel('Во сколько?')) fm.addRow(self.create_time()) return fm def init_ui(self): layout = QVBoxLayout() layout.addLayout(self.create_main_form()) layout.addStretch() layout.addLayout(self.create_control_buttons()) self.setLayout(layout)
class ClientEditor(QWidget): def __init__(self, win): QWidget.__init__(self) self.win = win self.id = 0 title = QLabel("Client Data") fnt = title.font() fnt.setPointSize(20) fnt.setBold(True) title.setFont(fnt) self.layout = QGridLayout() self.layout.setColumnStretch(0, 1) self.number = QLineEdit() self.name = QLineEdit() self.email = QLineEdit() self.profession = QLineEdit() self.address = QLineEdit() self.mobile = QLineEdit() self.notes = QTextEdit() self.birthday = QDateEdit() self.birthday.setCalendarPopup(True) self.birthday.setDisplayFormat("dd.MM.yyyy") self.image = ImageSelector() self.image.setMinimumWidth(250) self.layout.addWidget(title, 0, 0, 1, 2) self.layout.addWidget(QLabel("Id"), 1, 0) self.layout.addWidget(self.number, 2, 0) self.layout.addWidget(QLabel("Name"), 3, 0) self.layout.addWidget(self.name, 4, 0) self.layout.addWidget(QLabel("Address"), 5, 0) self.layout.addWidget(self.address, 6, 0) self.layout.addWidget(QLabel("Email"), 7, 0) self.layout.addWidget(self.email, 8, 0) self.layout.addWidget(QLabel("Mobile"), 9, 0) self.layout.addWidget(self.mobile, 10, 0) self.layout.addWidget(QLabel("Profession"), 11, 0) self.layout.addWidget(self.profession, 12, 0) self.layout.addWidget(QLabel("Notes"), 17, 0) self.layout.addWidget(self.notes, 18, 0, 1, 2) self.layout.addWidget(self.image, 2, 1, 7, 1) self.layout.addWidget(QLabel("Birhday"), 9, 1) self.layout.addWidget(self.birthday, 10, 1) self.setLayout(self.layout) self.reload() self.number.textEdited.connect(self.clientChanged) self.name.textEdited.connect(self.clientChanged) self.address.textEdited.connect(self.clientChanged) self.email.textEdited.connect(self.clientChanged) self.mobile.textEdited.connect(self.clientChanged) self.profession.textEdited.connect(self.clientChanged) self.notes.textChanged.connect(self.clientChanged) self.birthday.dateChanged.connect(self.clientChanged) self.image.clicked.connect(self.seek) def reload(self): self.loading = True if self.win.client: self.number.setText(self.win.client["number"]) self.name.setText(self.win.client["name"]) self.address.setText(self.win.client["address"]) self.email.setText(self.win.client["email"]) self.mobile.setText(self.win.client["mobile"]) self.profession.setText(self.win.client["profession"]) self.notes.setText(self.win.client["notes"]) self.birthday.setDate( QDate(self.win.client["birthday_year"], self.win.client["birthday_month"], self.win.client["birthday_day"])) name = os.path.join(str(self.win.client.doc_id) + ".png") path = os.path.join(self.win.database, "images", name) if os.path.exists(path): self.image.setImage(QImage(path)) else: self.image.setImage(QImage(":/images/image_placeholder.png")) else: self.number.setText("") self.name.setText("") self.address.setText("") self.email.setText("") self.mobile.setText("") self.profession.setText("") self.notes.setText("") self.birthday.setDate(QDate(1900, 1, 1)) self.image.setImage(QImage(":/images/image_placeholder.png")) self.loading = False def clientChanged(self): if self.loading: return self.win.client["number"] = self.number.text() self.win.client["name"] = self.name.text() self.win.client["address"] = self.address.text() self.win.client["email"] = self.email.text() self.win.client["mobile"] = self.mobile.text() self.win.client["profession"] = self.profession.text() self.win.client["notes"] = self.notes.toPlainText() self.win.client["birthday_year"] = self.birthday.date().year() self.win.client["birthday_month"] = self.birthday.date().month() self.win.client["birthday_day"] = self.birthday.date().day() self.win.clients.update(self.win.client, doc_ids=[self.win.client.doc_id]) self.win.updateClient() def seek(self): fileName = "" dialog = QFileDialog() dialog.setFileMode(QFileDialog.AnyFile) dialog.setNameFilter("Images (*.png *.gif *.jpg);;All (*)") dialog.setWindowTitle("Load Image") dialog.setOption(QFileDialog.DontUseNativeDialog, True) dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec(): fileName = dialog.selectedFiles()[0] del dialog if not fileName: return # copy file to database dir name = os.path.join(str(self.win.client.doc_id) + ".png") path = os.path.join(self.win.database, "images", name) shutil.copy(fileName, path) self.image.setImage(QImage(path)) self.clientChanged()
class Window(QWidget): def __init__(self): super(Window, self).__init__() self.createPreviewGroupBox() self.createGeneralOptionsGroupBox() self.createDatesGroupBox() self.createTextFormatsGroupBox() layout = QGridLayout() layout.addWidget(self.previewGroupBox, 0, 0) layout.addWidget(self.generalOptionsGroupBox, 0, 1) layout.addWidget(self.datesGroupBox, 1, 0) layout.addWidget(self.textFormatsGroupBox, 1, 1) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.previewLayout.setRowMinimumHeight( 0, self.calendar.sizeHint().height()) self.previewLayout.setColumnMinimumWidth( 0, self.calendar.sizeHint().width()) self.setWindowTitle("Calendar Widget") def localeChanged(self, index): self.calendar.setLocale(self.localeCombo.itemData(index)) def firstDayChanged(self, index): self.calendar.setFirstDayOfWeek( Qt.DayOfWeek(self.firstDayCombo.itemData(index))) def selectionModeChanged(self, index): self.calendar.setSelectionMode( QCalendarWidget.SelectionMode( self.selectionModeCombo.itemData(index))) def horizontalHeaderChanged(self, index): self.calendar.setHorizontalHeaderFormat( QCalendarWidget.HorizontalHeaderFormat( self.horizontalHeaderCombo.itemData(index))) def verticalHeaderChanged(self, index): self.calendar.setVerticalHeaderFormat( QCalendarWidget.VerticalHeaderFormat( self.verticalHeaderCombo.itemData(index))) def selectedDateChanged(self): self.currentDateEdit.setDate(self.calendar.selectedDate()) def minimumDateChanged(self, date): self.calendar.setMinimumDate(date) self.maximumDateEdit.setDate(self.calendar.maximumDate()) def maximumDateChanged(self, date): self.calendar.setMaximumDate(date) self.minimumDateEdit.setDate(self.calendar.minimumDate()) def weekdayFormatChanged(self): format = QTextCharFormat() format.setForeground( Qt.GlobalColor( self.weekdayColorCombo.itemData( self.weekdayColorCombo.currentIndex()))) self.calendar.setWeekdayTextFormat(Qt.Monday, format) self.calendar.setWeekdayTextFormat(Qt.Tuesday, format) self.calendar.setWeekdayTextFormat(Qt.Wednesday, format) self.calendar.setWeekdayTextFormat(Qt.Thursday, format) self.calendar.setWeekdayTextFormat(Qt.Friday, format) def weekendFormatChanged(self): format = QTextCharFormat() format.setForeground( Qt.GlobalColor( self.weekendColorCombo.itemData( self.weekendColorCombo.currentIndex()))) self.calendar.setWeekdayTextFormat(Qt.Saturday, format) self.calendar.setWeekdayTextFormat(Qt.Sunday, format) def reformatHeaders(self): text = self.headerTextFormatCombo.currentText() format = QTextCharFormat() if text == "Bold": format.setFontWeight(QFont.Bold) elif text == "Italic": format.setFontItalic(True) elif text == "Green": format.setForeground(Qt.green) self.calendar.setHeaderTextFormat(format) def reformatCalendarPage(self): if self.firstFridayCheckBox.isChecked(): firstFriday = QDate(self.calendar.yearShown(), self.calendar.monthShown(), 1) while firstFriday.dayOfWeek() != Qt.Friday: firstFriday = firstFriday.addDays(1) firstFridayFormat = QTextCharFormat() firstFridayFormat.setForeground(Qt.blue) self.calendar.setDateTextFormat(firstFriday, firstFridayFormat) # May 1st in Red takes precedence. if self.mayFirstCheckBox.isChecked(): mayFirst = QDate(self.calendar.yearShown(), 5, 1) mayFirstFormat = QTextCharFormat() mayFirstFormat.setForeground(Qt.red) self.calendar.setDateTextFormat(mayFirst, mayFirstFormat) def createPreviewGroupBox(self): self.previewGroupBox = QGroupBox("Preview") self.calendar = QCalendarWidget() self.calendar.setMinimumDate(QDate(1900, 1, 1)) self.calendar.setMaximumDate(QDate(3000, 1, 1)) self.calendar.setGridVisible(True) self.calendar.currentPageChanged.connect(self.reformatCalendarPage) self.previewLayout = QGridLayout() self.previewLayout.addWidget(self.calendar, 0, 0, Qt.AlignCenter) self.previewGroupBox.setLayout(self.previewLayout) def createGeneralOptionsGroupBox(self): self.generalOptionsGroupBox = QGroupBox("General Options") self.localeCombo = QComboBox() curLocaleIndex = -1 index = 0 this_language = self.locale().nativeLanguageName() this_country = self.locale().nativeCountryName() for locale in QLocale.matchingLocales(QLocale.AnyLanguage, QLocale.AnyScript, QLocale.AnyCountry): language = locale.nativeLanguageName() country = locale.nativeCountryName() if language == this_language and country == this_country: curLocaleIndex = index self.localeCombo.addItem('%s/%s' % (language, country), locale) index += 1 if curLocaleIndex != -1: self.localeCombo.setCurrentIndex(curLocaleIndex) self.localeLabel = QLabel("&Locale") self.localeLabel.setBuddy(self.localeCombo) self.firstDayCombo = QComboBox() self.firstDayCombo.addItem("Sunday", Qt.Sunday) self.firstDayCombo.addItem("Monday", Qt.Monday) self.firstDayCombo.addItem("Tuesday", Qt.Tuesday) self.firstDayCombo.addItem("Wednesday", Qt.Wednesday) self.firstDayCombo.addItem("Thursday", Qt.Thursday) self.firstDayCombo.addItem("Friday", Qt.Friday) self.firstDayCombo.addItem("Saturday", Qt.Saturday) self.firstDayLabel = QLabel("Wee&k starts on:") self.firstDayLabel.setBuddy(self.firstDayCombo) self.selectionModeCombo = QComboBox() self.selectionModeCombo.addItem("Single selection", QCalendarWidget.SingleSelection) self.selectionModeCombo.addItem("None", QCalendarWidget.NoSelection) self.selectionModeLabel = QLabel("&Selection mode:") self.selectionModeLabel.setBuddy(self.selectionModeCombo) self.gridCheckBox = QCheckBox("&Grid") self.gridCheckBox.setChecked(self.calendar.isGridVisible()) self.navigationCheckBox = QCheckBox("&Navigation bar") self.navigationCheckBox.setChecked(True) self.horizontalHeaderCombo = QComboBox() self.horizontalHeaderCombo.addItem( "Single letter day names", QCalendarWidget.SingleLetterDayNames) self.horizontalHeaderCombo.addItem("Short day names", QCalendarWidget.ShortDayNames) self.horizontalHeaderCombo.addItem("Long day names", QCalendarWidget.LongDayNames) self.horizontalHeaderCombo.addItem("None", QCalendarWidget.NoHorizontalHeader) self.horizontalHeaderCombo.setCurrentIndex(1) self.horizontalHeaderLabel = QLabel("&Horizontal header:") self.horizontalHeaderLabel.setBuddy(self.horizontalHeaderCombo) self.verticalHeaderCombo = QComboBox() self.verticalHeaderCombo.addItem("ISO week numbers", QCalendarWidget.ISOWeekNumbers) self.verticalHeaderCombo.addItem("None", QCalendarWidget.NoVerticalHeader) self.verticalHeaderLabel = QLabel("&Vertical header:") self.verticalHeaderLabel.setBuddy(self.verticalHeaderCombo) self.localeCombo.currentIndexChanged.connect(self.localeChanged) self.firstDayCombo.currentIndexChanged.connect(self.firstDayChanged) self.selectionModeCombo.currentIndexChanged.connect( self.selectionModeChanged) self.gridCheckBox.toggled.connect(self.calendar.setGridVisible) self.navigationCheckBox.toggled.connect( self.calendar.setNavigationBarVisible) self.horizontalHeaderCombo.currentIndexChanged.connect( self.horizontalHeaderChanged) self.verticalHeaderCombo.currentIndexChanged.connect( self.verticalHeaderChanged) checkBoxLayout = QHBoxLayout() checkBoxLayout.addWidget(self.gridCheckBox) checkBoxLayout.addStretch() checkBoxLayout.addWidget(self.navigationCheckBox) outerLayout = QGridLayout() outerLayout.addWidget(self.localeLabel, 0, 0) outerLayout.addWidget(self.localeCombo, 0, 1) outerLayout.addWidget(self.firstDayLabel, 1, 0) outerLayout.addWidget(self.firstDayCombo, 1, 1) outerLayout.addWidget(self.selectionModeLabel, 2, 0) outerLayout.addWidget(self.selectionModeCombo, 2, 1) outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) outerLayout.addWidget(self.horizontalHeaderLabel, 4, 0) outerLayout.addWidget(self.horizontalHeaderCombo, 4, 1) outerLayout.addWidget(self.verticalHeaderLabel, 5, 0) outerLayout.addWidget(self.verticalHeaderCombo, 5, 1) self.generalOptionsGroupBox.setLayout(outerLayout) self.firstDayChanged(self.firstDayCombo.currentIndex()) self.selectionModeChanged(self.selectionModeCombo.currentIndex()) self.horizontalHeaderChanged(self.horizontalHeaderCombo.currentIndex()) self.verticalHeaderChanged(self.verticalHeaderCombo.currentIndex()) def createDatesGroupBox(self): self.datesGroupBox = QGroupBox(self.tr("Dates")) self.minimumDateEdit = QDateEdit() self.minimumDateEdit.setDisplayFormat('MMM d yyyy') self.minimumDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.minimumDateEdit.setDate(self.calendar.minimumDate()) self.minimumDateLabel = QLabel("&Minimum Date:") self.minimumDateLabel.setBuddy(self.minimumDateEdit) self.currentDateEdit = QDateEdit() self.currentDateEdit.setDisplayFormat('MMM d yyyy') self.currentDateEdit.setDate(self.calendar.selectedDate()) self.currentDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.currentDateLabel = QLabel("&Current Date:") self.currentDateLabel.setBuddy(self.currentDateEdit) self.maximumDateEdit = QDateEdit() self.maximumDateEdit.setDisplayFormat('MMM d yyyy') self.maximumDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.maximumDateEdit.setDate(self.calendar.maximumDate()) self.maximumDateLabel = QLabel("Ma&ximum Date:") self.maximumDateLabel.setBuddy(self.maximumDateEdit) self.currentDateEdit.dateChanged.connect(self.calendar.setSelectedDate) self.calendar.selectionChanged.connect(self.selectedDateChanged) self.minimumDateEdit.dateChanged.connect(self.minimumDateChanged) self.maximumDateEdit.dateChanged.connect(self.maximumDateChanged) dateBoxLayout = QGridLayout() dateBoxLayout.addWidget(self.currentDateLabel, 1, 0) dateBoxLayout.addWidget(self.currentDateEdit, 1, 1) dateBoxLayout.addWidget(self.minimumDateLabel, 0, 0) dateBoxLayout.addWidget(self.minimumDateEdit, 0, 1) dateBoxLayout.addWidget(self.maximumDateLabel, 2, 0) dateBoxLayout.addWidget(self.maximumDateEdit, 2, 1) dateBoxLayout.setRowStretch(3, 1) self.datesGroupBox.setLayout(dateBoxLayout) def createTextFormatsGroupBox(self): self.textFormatsGroupBox = QGroupBox("Text Formats") self.weekdayColorCombo = self.createColorComboBox() self.weekdayColorCombo.setCurrentIndex( self.weekdayColorCombo.findText("Black")) self.weekdayColorLabel = QLabel("&Weekday color:") self.weekdayColorLabel.setBuddy(self.weekdayColorCombo) self.weekendColorCombo = self.createColorComboBox() self.weekendColorCombo.setCurrentIndex( self.weekendColorCombo.findText("Red")) self.weekendColorLabel = QLabel("Week&end color:") self.weekendColorLabel.setBuddy(self.weekendColorCombo) self.headerTextFormatCombo = QComboBox() self.headerTextFormatCombo.addItem("Bold") self.headerTextFormatCombo.addItem("Italic") self.headerTextFormatCombo.addItem("Plain") self.headerTextFormatLabel = QLabel("&Header text:") self.headerTextFormatLabel.setBuddy(self.headerTextFormatCombo) self.firstFridayCheckBox = QCheckBox("&First Friday in blue") self.mayFirstCheckBox = QCheckBox("May &1 in red") self.weekdayColorCombo.currentIndexChanged.connect( self.weekdayFormatChanged) self.weekendColorCombo.currentIndexChanged.connect( self.weekendFormatChanged) self.headerTextFormatCombo.currentIndexChanged.connect( self.reformatHeaders) self.firstFridayCheckBox.toggled.connect(self.reformatCalendarPage) self.mayFirstCheckBox.toggled.connect(self.reformatCalendarPage) checkBoxLayout = QHBoxLayout() checkBoxLayout.addWidget(self.firstFridayCheckBox) checkBoxLayout.addStretch() checkBoxLayout.addWidget(self.mayFirstCheckBox) outerLayout = QGridLayout() outerLayout.addWidget(self.weekdayColorLabel, 0, 0) outerLayout.addWidget(self.weekdayColorCombo, 0, 1) outerLayout.addWidget(self.weekendColorLabel, 1, 0) outerLayout.addWidget(self.weekendColorCombo, 1, 1) outerLayout.addWidget(self.headerTextFormatLabel, 2, 0) outerLayout.addWidget(self.headerTextFormatCombo, 2, 1) outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) self.textFormatsGroupBox.setLayout(outerLayout) self.weekdayFormatChanged() self.weekendFormatChanged() self.reformatHeaders() self.reformatCalendarPage() def createColorComboBox(self): comboBox = QComboBox() comboBox.addItem("Red", Qt.red) comboBox.addItem("Blue", Qt.blue) comboBox.addItem("Black", Qt.black) comboBox.addItem("Magenta", Qt.magenta) return comboBox
class InputPasien(QWidget): def __init__(self): super(InputPasien, self).__init__() self.setWindowTitle("Input Pasien") #self.setGeometry(200,200,300,400) self.InitUI() def InitUI(self): self.form = QFormLayout(self) self.ID = QLineEdit(self) self.ID.setReadOnly(True) self.ID.setStyleSheet('background-color: ') self.form.addRow("ID", self.ID) self.nama = QLineEdit(self) self.nama.setPlaceholderText("Nama Pasien") self.form.addRow("Nama Pasien", self.nama) self.tglLahir = QDateEdit(self) self.tglLahir.setDisplayFormat('dd/MM/yyyy') self.tglLahir.setCalendarPopup(True) self.form.addRow("Tanggal Lahir", self.tglLahir) self.Nik = QLineEdit(self) #self.Nik.setValidator(QIntValidator()) self.Nik.setMaxLength(16) self.form.addRow("NIK", self.Nik) self.noTel = QLineEdit(self) self.noTel.setInputMask("+62 9999 9999 999") self.form.addRow("No Telpon", self.noTel) self.jk = QComboBox() self.jk.addItem("Pria") self.jk.addItem("Wanita") self.form.addRow("Jenis Kelamin ", self.jk) self.alamat = QTextEdit(self) self.alamat.setPlaceholderText("Alamat Lengkap") self.alamat.setFixedHeight(50) self.form.addRow("Alamat", self.alamat) self.clear = QPushButton(self) self.clear.setText("Bersihkan") self.clear.setFixedHeight(70) self.clear.clicked.connect(self.clear_btn) self.form.addRow(self.clear) #self.form.addRow() def clear_btn(self): self.nama.clear() self.noTel.clear() self.alamat.clear() self.Nik.clear() self.tglLahir.setDate(QDate.currentDate()) def update_btn(self): try: ORMPasien.update_pasien(self.ID.text(), self.nama.text(), self.tglLahir.text(), self.Nik.text(), self.alamat.toPlainText(), self.jk.currentText(), self.noTel.text()) msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Data Telah Terupdate") msg.setInformativeText(f"Data telah di Update") msg.setWindowTitle("Berhasil, Selamat") s = msg.exec_() self.clear_btn() except Exception as e: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Data Gagal Input") msg.setInformativeText(f"KESALAHAN : {e}") msg.setWindowTitle("Gagal") s = msg.exec_() #self.parent().isitable() def submit_btn(self): try: x = Pasien(self.nama.text(), self.tglLahir.text(), self.Nik.text(), self.alamat.toPlainText(), self.noTel.text(), self.jk.currentText()) kode = x.getID_Pasien() msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Data Telah Disimpan") msg.setInformativeText(f"ID Pasien adalah {kode}") msg.setWindowTitle("Berhasil") s = msg.exec_() self.clear_btn() except Exception as e: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Data Gagal Input") msg.setInformativeText(f"KESALAHAN : {e}") msg.setWindowTitle("Gagal") s = msg.exec_()
class IPStationBrowser(QWidget): __inv = None def __init__(self, service=None, network=None): super().__init__() # these are for managing the event info in form elements # self.eventInfoPopulated = False # self.currentEvent = None self.__buildUI__(service, network) self.show() def __buildUI__(self, service, network): vertLayout = QVBoxLayout() self.setLayout(vertLayout) gridLayout = QGridLayout() # First lets populate the client drop down with all available services self.service_cb = QComboBox() # self.service_cb.addItem("choose...") fdsn_dictionary = URL_MAPPINGS fdsn_dictionary.update( {'RaspShake': 'https://fdsnws.rasberryshakedata.com'}) for key in sorted(fdsn_dictionary.keys()): self.service_cb.addItem(key) self.service_cb.setCurrentText('IRIS') if service is not None: self.service_cb.setCurrentText(service) validator = Validator(self) # Network selector self.network_edit = QLineEdit(network) self.network_edit.setToolTip( 'Wildcards OK \nCan be SEED network codes or data center defined codes. \nMultiple codes are comma-separated (e.g. "IU,TA").' ) self.network_edit.setValidator(validator) if network is not None: self.network_edit.setText(network) # Station selector self.station_edit = QLineEdit() self.station_edit.setToolTip( 'Wildcards OK \nOne or more SEED station codes. \nMultiple codes are comma-separated (e.g. "ANMO,PFO")' ) self.station_edit.setValidator(validator) # Location selector self.location_edit = QLineEdit() self.location_edit.setToolTip( 'One or more SEED location identifiers. \nMultiple identifiers are comma-separated (e.g. "00,01"). \nAs a special case “--“ (two dashes) will be translated to a string of two space characters to match blank location IDs.' ) self.location_edit.setText('') # Channel selector self.channel_edit = QLineEdit() self.channel_edit.setToolTip( 'Wildcards OK \nOne or more SEED channel codes. \nMultiple codes are comma-separated (e.g. "BHZ,HHZ")' ) self.channel_edit.setValidator(validator) # Date time editors minimumDate = QDate(1900, 1, 1) self.startDate_edit = QDateEdit() self.startDate_edit.setDisplayFormat('yyyy-MM-dd') self.startDate_edit.setMinimumDate(minimumDate) self.startDate_edit.setDate(self.startDate_edit.minimumDate()) self.endDate_edit = QDateEdit() self.endDate_edit.setDisplayFormat('yyyy-MM-dd') self.endDate_edit.setMinimumDate(minimumDate) self.endDate_edit.setDate(self.endDate_edit.minimumDate()) self.lat_edit = QDoubleSpinBox() self.lat_edit.setRange(-90.1, 90.0) # the -90.1 is used as the "unset" value self.lat_edit.setDecimals(8) self.lat_edit.setSpecialValueText('--') self.lat_edit.setSingleStep(0.1) self.lat_edit.setValue(self.lat_edit.minimum()) self.lon_edit = QDoubleSpinBox() self.lon_edit.setRange(-180.1, 180.0) self.lon_edit.setDecimals(8) self.lon_edit.setSpecialValueText('--') self.lon_edit.setSingleStep(0.1) self.lon_edit.setValue(self.lon_edit.minimum()) # self.evt_import_button = QPushButton('Populate with Event Info') self.minLat_edit = QDoubleSpinBox() self.minLat_edit.setRange(-90.1, 90.0) self.minLat_edit.setDecimals(8) self.minLat_edit.setSpecialValueText('--') self.minLat_edit.setSingleStep(0.1) self.minLat_edit.setValue(self.minLat_edit.minimum()) self.maxLat_edit = QDoubleSpinBox() self.maxLat_edit.setRange(-90.1, 90.0) self.maxLat_edit.setDecimals(8) self.maxLat_edit.setSpecialValueText('--') self.maxLat_edit.setSingleStep(0.1) self.maxLat_edit.setValue(self.maxLat_edit.minimum()) self.minLon_edit = QDoubleSpinBox() self.minLon_edit.setRange(-180.1, 180.0) self.minLon_edit.setDecimals(8) self.minLon_edit.setSpecialValueText('--') self.minLon_edit.setSingleStep(0.1) self.minLon_edit.setValue(self.minLon_edit.minimum()) self.maxLon_edit = QDoubleSpinBox() self.maxLon_edit.setRange(-180.1, 180.0) self.maxLon_edit.setDecimals(8) self.maxLon_edit.setSpecialValueText('--') self.maxLon_edit.setSingleStep(0.1) self.maxLon_edit.setValue(self.maxLon_edit.minimum()) self.minRadius_edit = QDoubleSpinBox() self.minRadius_edit.setMinimum(0.0) self.minRadius_edit.setMaximum(180.0) self.minRadius_edit.setSpecialValueText('--') self.minRadius_edit.setSuffix(' deg') self.minRadius_edit.setValue(self.minRadius_edit.minimum()) self.minRadius_edit.setEnabled( False) # Need lat and lon before this means anything self.maxRadius_edit = QDoubleSpinBox() self.maxRadius_edit.setMinimum(0.0) self.maxRadius_edit.setMaximum(180.0) self.maxRadius_edit.setSpecialValueText('--') self.maxRadius_edit.setSuffix(' deg') self.maxRadius_edit.setValue(self.maxRadius_edit.minimum()) self.maxRadius_edit.setEnabled( False) # Need lat and lon before this means anything # Set up the search button here self.searchButton = QPushButton('Search') # Reset Button self.resetButton = QPushButton('Reset Inputs') # assemble the grid layout gridLayout.addWidget(QLabel(self.tr('Service: ')), 0, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.service_cb, 0, 1) gridLayout.addWidget(QLabel(self.tr('Network(s): ')), 1, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.network_edit, 1, 1) gridLayout.addWidget(QLabel(self.tr('Station(s): ')), 1, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.station_edit, 1, 3) gridLayout.addWidget(QLabel(self.tr('Location(s): ')), 2, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.location_edit, 2, 1) gridLayout.addWidget(QLabel(self.tr('Channel(s): ')), 2, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.channel_edit, 2, 3) gridLayout.addWidget(self.HLine(), 3, 0, 1, 4) # This is a horizontal line gridLayout.addWidget(QLabel(self.tr('Start Date (UTC)')), 4, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.startDate_edit, 4, 1) gridLayout.addWidget(QLabel(self.tr('End Date (UTC)')), 4, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.endDate_edit, 4, 3) gridLayout.addWidget(QLabel(self.tr('Latitude: ')), 5, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.lat_edit, 5, 1) gridLayout.addWidget(QLabel(self.tr('Longitude: ')), 5, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.lon_edit, 5, 3) # gridLayout.addWidget(self.evt_import_button, 6, 1, 1, 2) gridLayout.addWidget(self.HLine(), 7, 0, 1, 4) # This is a horizontal line gridLayout.addWidget(QLabel(self.tr('Minimum Latitude: ')), 8, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.minLat_edit, 8, 1) gridLayout.addWidget(QLabel(self.tr('Maximum Latitude: ')), 8, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.maxLat_edit, 8, 3) gridLayout.addWidget(QLabel(self.tr('Minimum Longitude: ')), 9, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.minLon_edit, 9, 1) gridLayout.addWidget(QLabel(self.tr('Maximum Longitude: ')), 9, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.maxLon_edit, 9, 3) gridLayout.addWidget(self.HLine(), 10, 0, 1, 4) # This is a horizontal line gridLayout.addWidget(QLabel(self.tr('Minimum Radius: ')), 11, 0, alignment=Qt.AlignRight) gridLayout.addWidget(self.minRadius_edit, 11, 1) gridLayout.addWidget(QLabel(self.tr('Maximum Radius: ')), 11, 2, alignment=Qt.AlignRight) gridLayout.addWidget(self.maxRadius_edit, 11, 3) gridLayout.addWidget(self.HLine(), 12, 0, 1, 4) # This is a horizontal line gridLayout.addWidget(self.resetButton, 13, 0) gridLayout.addWidget(self.searchButton, 13, 2, 1, 2) # Center the form in the widget centeringLayout = QHBoxLayout() centeringLayout.addStretch() centeringLayout.addLayout(gridLayout) centeringLayout.addStretch() self.stationListWidget = QListWidget() # self.stationListWidget.setSelectionMode(QAbstractItemView.SingleSelection) # for multiple selection, uncomment out the next line, and comment out the above line self.stationListWidget.setSelectionMode( QAbstractItemView.ExtendedSelection) # create a tab widget to hold the stationList and the station map stationTabs = QTabWidget() stationTabs.addTab(self.stationListWidget, "Station List") # Placeholder for map widget, whenever I get around to making one self.mapWidget = QWidget() stationTabs.addTab(self.mapWidget, 'Map') vertLayout.addLayout(centeringLayout) vertLayout.addWidget(stationTabs) self.connectSignalsAndSlots() def connectSignalsAndSlots(self): self.searchButton.clicked.connect(self.onActivated_search) self.resetButton.clicked.connect(self.onActivated_reset) # self.evt_import_button.clicked.connect(self.populateEventInfo) self.stationListWidget.itemClicked.connect(self.getSelected) self.service_cb.currentIndexChanged[str].connect(self.serviceClicked) self.lat_edit.valueChanged.connect(self.updateWidget) self.lon_edit.valueChanged.connect(self.updateWidget) self.startDate_edit.dateChanged.connect(self.adjust_end_date) @QtCore.pyqtSlot(QDate) def adjust_end_date(self, start_date): if self.endDate_edit.date() == self.endDate_edit.minimumDate(): self.endDate_edit.setDate(start_date) elif self.endDate_edit.date() < start_date: self.endDate_edit.setDate(start_date) def populateStationInfo(self): service = self.service_cb.currentText() if self.network_edit.text() == '': network = None else: network = self.network_edit.text() if self.station_edit.text() == '': station = None else: station = self.station_edit.text() if self.location_edit.text() == '': location = None else: location = self.location_edit.text() if self.channel_edit.text() == '': channel = None else: channel = self.channel_edit.text() if self.lat_edit.value() == self.lat_edit.minimum(): lat = None else: lat = self.lat_edit.value() if self.lon_edit.value() == self.lon_edit.minimum(): lon = None else: lon = self.lon_edit.value() if self.minLat_edit.value() == self.minLat_edit.minimum(): minLat = None else: minLat = self.minLat_edit.value() if self.maxLat_edit.value() == self.maxLat_edit.minimum(): maxLat = None else: maxLat = self.maxLat_edit.value() if self.minLon_edit.value() == self.minLon_edit.minimum(): minLon = None else: minLon = self.minLon_edit.value() if self.maxLon_edit.value() == self.maxLon_edit.minimum(): maxLon = None else: maxLon = self.maxLon_edit.value() if self.lat_edit.value() != self.lat_edit.minimum( ) and self.lon_edit.value() != self.lon_edit.minimum(): if self.minRadius_edit.value() == self.minRadius_edit.minimum(): minRad = None else: minRad = self.minRadius_edit.value() if self.maxRadius_edit.value() == self.maxRadius_edit.minimum(): maxRad = None else: maxRad = self.maxRadius_edit.value() else: minRad = None maxRad = None if service != '': try: client = Client(service) except obspy.clients.fdsn.header.FDSNException as e: self.errorPopup(str(e)) return startDate = self.startDate_edit.date().toString("yyyy-MM-dd") endDate = self.endDate_edit.date().toString("yyyy-MM-dd") try: self.__inv = client.get_stations(network=network, station=station, location=location, channel=channel, starttime=startDate, endtime=endDate, latitude=lat, longitude=lon, minlongitude=minLon, maxlongitude=maxLon, minlatitude=minLat, maxlatitude=maxLon, minradius=minRad, maxradius=maxRad, format='xml') except: emptyMessage = ["...No Data Found..."] self.stationListWidget.clear() self.stationListWidget.addItems(emptyMessage) return self.stationListWidget.clear() inv_contents = self.__inv.get_contents() stationList = [] # fill up the stationList with stations for item in inv_contents['stations']: stationList.append(item.strip()) self.stationListWidget.clear() self.stationListWidget.addItems(stationList) def errorPopup(self, message): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Information) msgBox.setText(message) msgBox.setWindowTitle("Oops...") msgBox.exec_() def onActivated_search(self): self.stationListWidget.clear() QtGui.QGuiApplication.processEvents() QApplication.processEvents() msg = ['...Searching...'] self.stationListWidget.addItems(msg) QApplication.processEvents() QtGui.QGuiApplication.processEvents() self.populateStationInfo() return def onActivated_reset(self): self.__inv = None self.network_edit.setText('') self.station_edit.setText('') self.location_edit.setText('') self.channel_edit.setText('') self.startDate_edit.setDate(self.startDate_edit.minimumDate()) self.endDate_edit.setDate(self.endDate_edit.minimumDate()) self.lat_edit.setValue(self.lat_edit.minimum()) self.lon_edit.setValue(self.lon_edit.minimum()) self.minLat_edit.setValue(self.minLat_edit.minimum()) self.minLon_edit.setValue(self.minLon_edit.minimum()) self.maxLat_edit.setValue(self.maxLat_edit.minimum()) self.maxLon_edit.setValue(self.maxLon_edit.minimum()) self.minRadius_edit.setValue(self.minRadius_edit.minimum()) self.maxRadius_edit.setValue(self.maxRadius_edit.minimum()) self.stationListWidget.clear() # self.eventInfoPopulated = False # def populateEventInfo(self): # if self.currentEvent is not None: # date = self.currentEvent['UTC Date'] # lat = self.currentEvent['Latitude'] # lon = self.currentEvent['Longitude'] # self.lat_edit.setValue(lat) # self.lon_edit.setValue(lon) # qdate = QDate.fromString(date, 'yyyy-MM-dd') # self.startDate_edit.setDate(qdate) # self.endDate_edit.setDate(qdate.addDays(1)) # self.eventInfoPopulated = True # else: # msg = QMessageBox() # msg.setIcon(QMessageBox.Warning) # msg.setText('There is not a valid event in the Event Tab') # msg.setWindowTitle('oops...') # msg.setStandardButtons(QMessageBox.Ok) # msg.exec_() # def setEvent(self, event): # self.currentEvent = event # # Update the event info if it has been imported # if self.eventInfoPopulated: # self.populateEventInfo() def updateWidget(self): # We need lat and lon values if we are going to use the radius inputs enableRadius = self.lat_edit.value() != self.lat_edit.minimum( ) and self.lon_edit.value() != self.lon_edit.minimum() self.maxRadius_edit.setEnabled(enableRadius) self.minRadius_edit.setEnabled(enableRadius) def getSelected(self): selectedText = self.stationListWidget.currentItem().text() # first split the string at the first space, this will return just the # network and the station name = selectedText.split(" ") fullID = name[0] # next split that at the period, to seperate the network and station networkID = fullID.split(".")[0] stationID = fullID.split(".")[1] result = {"networkID": networkID, "stationID": stationID} return result def get_current_center(self): # this method will calculate the center of the current inventory and will return a [lat,lon] # TODO: This is not really setup right now to handle the (very rare) case where an array straddles the # international date line lat, lon, cnt = 0, 0, 0 for network in self.__inv: for station in network: lat += station.latitude lon += station.longitude cnt += 1 return [lat / cnt, lon / cnt] def getInventory(self): return self.__inv def getSelectedInventory(self): reducedInv = [] for item in self.__inv: if item.isSelected(): reducedInv.append(item) return reducedInv def serviceClicked(self): self.stationListWidget.clear() self.network_edit.clear() def HLine(self): hl = QFrame() hl.setFrameShape(QFrame.HLine) hl.setFrameShadow(QFrame.Sunken) return hl
class SpotPriceAdminUI(QTabWidget): def __init__(self, *args, **kwargs): super(SpotPriceAdminUI, self).__init__(*args, **kwargs) self.extra_data_widget = QWidget(self) # 提取数据tab layout = QVBoxLayout() # 现货价格源数据 source_layout = QHBoxLayout() self.current_date = QDateEdit(self) self.current_date.setDisplayFormat("yyyy-MM-dd") self.current_date.setDate(QDate.currentDate()) self.current_date.setCalendarPopup(True) source_layout.addWidget(self.current_date) source_layout.addWidget(QLabel("源数据:", self)) self.source_edit = QLineEdit(self) source_layout.addWidget(self.source_edit) layout.addLayout(source_layout) # 分析 analysis_layout = QHBoxLayout() self.analysis_button = QPushButton("提取数据", self) analysis_layout.addWidget(self.analysis_button) self.tip_label = QLabel("输入源数据后,点击提取数据进行数据提取.", self) analysis_layout.addWidget(self.tip_label) analysis_layout.addStretch() layout.addLayout(analysis_layout) # 预览数据的表格 self.preview_table = QTableWidget(self) self.preview_table.setColumnCount(5) self.preview_table.setHorizontalHeaderLabels( ["日期", "品种", "交易代码", "现货价", "增减"]) layout.addWidget(self.preview_table) # 提交按钮 commit_layout = QHBoxLayout() commit_layout.addStretch() self.commit_button = QPushButton("确认提交", self) commit_layout.addWidget(self.commit_button) layout.addLayout(commit_layout) self.extra_data_widget.setLayout(layout) self.addTab(self.extra_data_widget, "数据提取") # 提取数据tab # 修改数据的tab self.modify_data_widget = QWidget(self) modify_layout = QVBoxLayout() params_layout = QHBoxLayout() params_layout.addWidget(QLabel("选择日期:", self)) self.modify_date_edit = QDateEdit(self) self.modify_date_edit.setDate(QDate.currentDate()) self.modify_date_edit.setCalendarPopup(True) self.modify_date_edit.setDisplayFormat("yyyy-MM-dd") params_layout.addWidget(self.modify_date_edit) self.modify_query_button = QPushButton("查询", self) params_layout.addWidget(self.modify_query_button) self.modify_tip_label = QLabel("选择日期查询出数据,双击要修改的数据编辑正确的数据,点击行尾修改.", self) params_layout.addWidget(self.modify_tip_label) params_layout.addStretch() modify_layout.addLayout(params_layout) # 数据表格 self.modify_table = QTableWidget(self) self.modify_table.setColumnCount(6) self.modify_table.setHorizontalHeaderLabels( ["ID", "日期", "品种", "现货价", "增减", "修改"]) modify_layout.addWidget(self.modify_table) self.modify_data_widget.setLayout(modify_layout) self.addTab(self.modify_data_widget, "修改数据") self.setStyleSheet( "#modifyButton{border:none;color:rgb(180,30,50)}#modifyButton:hover{color:rgb(20,50,160)}" )
class DataWidget(QWidget): def __init__(self): super(DataWidget, self).__init__(None) self.read_data_file(config.HISTORIC_DATA) self.start_date = date(2016, 10, 1) self.end_date = date(2016, 11, 1) self.graph = GraphCanvas(self.data_frame) with open(config.LOGFILE, 'w', newline='') as logfile: logwriter = csv.writer(logfile) logwriter.writerow(config.headers) # options group box self.optionsGroupBox = QGroupBox("Options") options_layout = QVBoxLayout() date_range_layout = QFormLayout() start_date_label = QLabel("Start Date:") self.start_date_box = QDateEdit(self.start_date) self.start_date_box.setCalendarPopup(True) self.start_date_box.setDisplayFormat(config.DATE_DISPLAY_FORMAT) self.start_date_box.dateChanged.connect(self.plot) end_date_label = QLabel("End Date:") self.end_date_box = QDateEdit(self.end_date) self.end_date_box.setCalendarPopup(True) self.end_date_box.setDisplayFormat(config.DATE_DISPLAY_FORMAT) self.end_date_box.dateChanged.connect(self.plot) date_range_layout.addRow(start_date_label, self.start_date_box) date_range_layout.addRow(end_date_label, self.end_date_box) # days of week self.sundayCheckBox = QCheckBox("Sunday") self.mondayCheckBox = QCheckBox("Monday") self.tuesdayCheckBox = QCheckBox("Tuesday") self.wednesdayCheckBox = QCheckBox("Wednesday") self.thursdayCheckBox = QCheckBox("Thursday") self.fridayCheckBox = QCheckBox("Friday") self.saturdayCheckBox = QCheckBox("Saturday") self.sundayCheckBox.toggled.connect(self.plot) self.mondayCheckBox.toggled.connect(self.plot) self.tuesdayCheckBox.toggled.connect(self.plot) self.wednesdayCheckBox.toggled.connect(self.plot) self.thursdayCheckBox.toggled.connect(self.plot) self.fridayCheckBox.toggled.connect(self.plot) self.saturdayCheckBox.toggled.connect(self.plot) options_layout.addLayout(date_range_layout) options_layout.addWidget(self.sundayCheckBox) options_layout.addWidget(self.mondayCheckBox) options_layout.addWidget(self.tuesdayCheckBox) options_layout.addWidget(self.wednesdayCheckBox) options_layout.addWidget(self.thursdayCheckBox) options_layout.addWidget(self.fridayCheckBox) options_layout.addWidget(self.saturdayCheckBox) options_layout.addWidget(QPushButton("Button")) self.optionsGroupBox.setLayout(options_layout) # graph group box self.graphGroupBox = QGroupBox("Graph") graphLayout = QVBoxLayout() graphLayout.addWidget(self.graph) self.graphGroupBox.setLayout(graphLayout) # choice group box self.choiceGroupBox = QGroupBox("Choice") choice_layout = QVBoxLayout() choice_layout_1 = QHBoxLayout() choice_layout_1.addWidget(QLabel("A")) choice_layout_1.addWidget(QLabel("B")) choice_layout_1.addWidget(QLabel("C")) choice_layout_1.addWidget(QLabel("D")) choice_layout_2 = QHBoxLayout() self.decision_value_1 = QSpinBox() self.decision_value_2 = QSpinBox() self.decision_value_3 = QSpinBox() self.decision_value_4 = QSpinBox() choice_layout_2.addWidget(self.decision_value_1) choice_layout_2.addWidget(self.decision_value_2) choice_layout_2.addWidget(self.decision_value_3) choice_layout_2.addWidget(self.decision_value_4) choice_layout.addLayout(choice_layout_1) choice_layout.addLayout(choice_layout_2) self.decision_value_1.setValue(42) self.choiceGroupBox.setLayout(choice_layout) # count-down timer self.timerGroupBox = QGroupBox("Timer") timer_layout = QVBoxLayout() self.timerGroupBox.setLayout(timer_layout) self.count_down_timer = CountDownTimer() timer_layout.addWidget(self.count_down_timer.lcd) # central widget frame = QFrame(self) self.grid = QGridLayout(frame) self.grid.setSpacing(16) self.grid.setContentsMargins(16, 16, 16, 16) self.grid.addWidget(self.optionsGroupBox, 0, 0, 2, 1) self.grid.addWidget(self.graphGroupBox, 0, 1, 2, 1) self.grid.addWidget(self.timerGroupBox, 0, 2) self.grid.addWidget(self.choiceGroupBox, 2, 1) self.grid.setColumnStretch(0, 2) self.grid.setColumnStretch(1, 6) self.grid.setColumnStretch(2, 1) self.grid.setRowStretch(0, 1) self.grid.setRowStretch(1, 2) self.grid.setRowStretch(2, 2) self.setLayout(self.grid) def read_data_file(self, data_file): """read data_file and import it's content as pandas dataframe""" dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d') self.data_frame = pd.read_csv(data_file, index_col=0, parse_dates=True) def plot(self): """ Method to update start / end dates upon selection. Fetch the start / end dates, convert the QTime datatype to DateTime.Date datatype, and plot the graph. """ self.start_date = self.start_date_box.date().toPyDate() self.end_date = self.end_date_box.date().toPyDate() self.graph.plot(self.data_frame.loc[self.start_date : self.end_date]) def add_log_row(self): """ Write data in the log file :return: """ new_row = [config.id, config.age, config.male, config.field, 'test_condition', datetime.now()] with open(config.LOGFILE, 'a', newline='') as logfile: logwriter = csv.writer(logfile) logwriter.writerow(new_row)
class RegisterWidget(QWidget): login_request = pyqtSignal(str, str) def __init__(self, parent=None): super(RegisterWidget, self).__init__(parent) self.kik_client = KikClient() self.interceptor = RequestInterceptor(self) self.error_label = QLabel() self.webview = QWebEngineView() self.login_button = QPushButton() self.birthday_edit = QDateEdit() self.password_edit = QLineEdit() self.email_edit = QLineEdit() self.username_edit = QLineEdit() self.last_name_edit = QLineEdit() self.first_name_edit = QLineEdit() self.init_ui() def init_ui(self): main_box = QVBoxLayout() main_box.setSpacing(20) main_box.setAlignment(Qt.AlignCenter) label = QLabel("Sign up") main_box.addWidget(label, alignment=Qt.AlignCenter) self.first_name_edit.setPlaceholderText("First name") main_box.addWidget(self.first_name_edit, alignment=Qt.AlignCenter) self.last_name_edit.setPlaceholderText("Last name") main_box.addWidget(self.last_name_edit, alignment=Qt.AlignCenter) self.username_edit.setPlaceholderText("Username") self.username_edit.setValidator(UserNameValidator(self.kik_client)) main_box.addWidget(self.username_edit, alignment=Qt.AlignCenter) self.email_edit.setPlaceholderText("Email") main_box.addWidget(self.email_edit, alignment=Qt.AlignCenter) self.password_edit.setEchoMode(QLineEdit.Password) self.password_edit.setPlaceholderText("Password") main_box.addWidget(self.password_edit, alignment=Qt.AlignCenter) self.birthday_edit.setCalendarPopup(True) self.birthday_edit.setDisplayFormat("yyyy-MM-dd") birthday_layout = QHBoxLayout() birthday_label = QLabel("Birthday:") birthday_layout.addWidget(birthday_label, alignment=Qt.AlignCenter) birthday_layout.addWidget(self.birthday_edit, alignment=Qt.AlignCenter) birthday_layout.setAlignment(Qt.AlignCenter) main_box.addLayout(birthday_layout) self.login_button.setText("Sign up") self.login_button.clicked.connect(self.sign_up) main_box.addWidget(self.login_button, alignment=Qt.AlignCenter) self.error_label.setObjectName("errorLabel") main_box.addWidget(self.error_label, alignment=Qt.AlignCenter) main_box.addWidget(self.webview, alignment=Qt.AlignCenter) self.setLayout(main_box) self.show() def sign_up(self): self.error_label.setText("") first_name = self.first_name_edit.text() last_name = self.last_name_edit.text() username = self.username_edit.text() email = self.email_edit.text() password = self.password_edit.text() birthday = self.birthday_edit.date() try: self.kik_client.sign_up(email, username, password, first_name, last_name, birthday.toString("yyyy-MM-dd")) except KikCaptchaException as e: url = e.captcha_url + "&callback_url=https://kik.com/captcha-url" self.webview.load(QUrl(url)) self.webview.page().profile().setHttpUserAgent( "Mozilla/5.0 (Linux; Android 7.1.2; Nexus 7 Build/NJH47F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.78 Safari/537.36" ) self.webview.page().profile().setRequestInterceptor( self.interceptor) except Exception as e: self.error_label.setText(str(e)) return False def on_captcha_response(self, captcha_result): print("Received response: {}".format(captcha_result)) self.sign_up_captcha(captcha_result) def sign_up_captcha(self, captcha_result): self.error_label.setText("") first_name = self.first_name_edit.text() last_name = self.last_name_edit.text() username = self.username_edit.text() email = self.email_edit.text() password = self.password_edit.text() birthday = self.birthday_edit.date() try: node = self.kik_client.sign_up(email, username, password, first_name, last_name, birthday.toString("yyyy-MM-dd"), captcha_result) print(node) self.login_request.emit(username, password) except: self.error_label.setText("Account creation failed")
class ReportFileAdminUI(QTabWidget): def __init__(self, *args, **kwargs): super(ReportFileAdminUI, self).__init__(*args, **kwargs) upload_widget = QWidget(self) main_layout = QVBoxLayout() local_file_layout = QHBoxLayout() local_file_layout.addWidget(QLabel('本地文件:', self)) self.local_file_edit = FilePathLineEdit(self) self.local_file_edit.setPlaceholderText("点击选择本地文件进行上传") self.local_file_edit.setFixedWidth(600) local_file_layout.addWidget(self.local_file_edit) self.explain_label = QLabel("说明:[本地文件]或[网络文件]只能选择一种,相关信息共享。", self) self.explain_label.setStyleSheet("color:rgb(66,233,66)") local_file_layout.addWidget(self.explain_label) local_file_layout.addStretch() main_layout.addLayout(local_file_layout) network_file_layout = QHBoxLayout() network_file_layout.addWidget(QLabel('网络文件:', self)) self.filename = QLabel("从表格选择文件", self) self.filename.setTextInteractionFlags(Qt.TextSelectableByMouse) self.filename.setAlignment(Qt.AlignLeft) self.filename.setFixedWidth(600) network_file_layout.addWidget(self.filename) self.explain_label = QLabel("说明:[本地文件]或[网络文件]只能选择一种,相关信息共享。", self) self.explain_label.setStyleSheet("color:rgb(66,233,66)") network_file_layout.addWidget(self.explain_label) network_file_layout.addStretch() main_layout.addLayout(network_file_layout) option_layout = QHBoxLayout() option_layout.addWidget(QLabel("报告日期:", self)) self.date_edit = QDateEdit(self) self.date_edit.setCalendarPopup(True) self.date_edit.setDisplayFormat("yyyy-MM-dd") self.date_edit.setDate(QDate.currentDate()) option_layout.addWidget(self.date_edit) option_layout.addWidget(QLabel("报告类型:", self)) self.report_type = QComboBox(self) option_layout.addWidget(self.report_type) option_layout.addWidget(QLabel("备选品种:", self)) self.variety_combobox = QComboBox(self) option_layout.addWidget(self.variety_combobox) option_layout.addWidget(QLabel("关联品种:", self)) self.relative_variety = QLabel("下拉框选择品种(多选)", self) option_layout.addWidget(self.relative_variety) self.clear_relative_button = QPushButton("清除", self) option_layout.addWidget(self.clear_relative_button) self.rename_edit = QLineEdit(self) self.rename_edit.setPlaceholderText("重命名文件(无需重命名请留空),无需填后缀.") self.rename_edit.setFixedWidth(266) option_layout.addWidget(self.rename_edit) self.confirm_button = QPushButton("确定添加", self) option_layout.addWidget(self.confirm_button) option_layout.addStretch() main_layout.addLayout(option_layout) self.file_table = QTableWidget(self) self.file_table.setColumnCount(7) self.file_table.verticalHeader().hide() self.file_table.setEditTriggers(QHeaderView.NoEditTriggers) self.file_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.file_table.setHorizontalHeaderLabels( ["序号", "文件名", "大小", "创建时间", "", "", ""]) self.file_table.horizontalHeader().setDefaultSectionSize(55) self.file_table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.ResizeToContents) self.file_table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.ResizeToContents) self.file_table.horizontalHeader().setSectionResizeMode( 3, QHeaderView.ResizeToContents) main_layout.addWidget(self.file_table) upload_widget.setLayout(main_layout) self.addTab(upload_widget, "上传报告") # 管理报告 manager_widget = QWidget(self) manager_layout = QVBoxLayout() manager_option_layout = QHBoxLayout() self.manager_date = QDateEdit(self) self.manager_date.setDate(QDate.currentDate()) self.manager_date.setDisplayFormat("yyyy-MM-dd") self.manager_date.setCalendarPopup(True) manager_option_layout.addWidget(self.manager_date) manager_option_layout.addWidget(QLabel("报告类型:", self)) self.manager_report_type = QComboBox(self) manager_option_layout.addWidget(self.manager_report_type) manager_option_layout.addWidget(QLabel("相关品种:", self)) self.manager_variety_combobox = QComboBox(self) manager_option_layout.addWidget(self.manager_variety_combobox) manager_layout.addLayout(manager_option_layout) self.manager_query_button = QPushButton("查询", self) manager_option_layout.addWidget(self.manager_query_button) manager_option_layout.addStretch() self.manager_table = QTableWidget(self) self.manager_table.setColumnCount(7) self.manager_table.setHorizontalHeaderLabels( ["日期", "关联品种", "报告类型", "报告名称", "", "是否公开", ""]) self.manager_table.horizontalHeader().setDefaultSectionSize(80) self.manager_table.horizontalHeader().setSectionResizeMode( 3, QHeaderView.ResizeToContents) manager_layout.addWidget(self.manager_table) manager_widget.setLayout(manager_layout) self.addTab(manager_widget, "管理报告") self.no_selected_file() self.no_relative_variety() def has_selected_file(self): self.filename.setStyleSheet("color:rgb(66,66,233);font-size:13px") def no_selected_file(self): self.filename.setStyleSheet("color:rgb(233,66,66);font-size:13px") def has_relative_variety(self): self.relative_variety.setStyleSheet( "color:rgb(66,66,233);font-size:13px") def no_relative_variety(self): self.relative_variety.setStyleSheet( "color:rgb(233,66,66);font-size:13px")
class AddResultsForm(QVBoxLayout): """ Form with several entries to add a result on the database """ resultAdded = pyqtSignal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Title self.title = QLabel(self.tr("Add Results")) self.title.setFont(TitleFont()) self.title.setAlignment(Qt.AlignCenter) # First line: Date self.label1 = QLabel(self.tr("Date")) self.label1.setFixedWidth(80) self.date_edit = QDateEdit(datetime.now()) self.date_edit.setDisplayFormat("dd/MM/yyyy") self.date_edit.setCalendarPopup(True) self.label1_checkbox = QPushButton(self.tr("Today")) self.label1_checkbox.setMaximumWidth(50) self.label1_checkbox.clicked.connect(self.setToday) self.line1 = QHBoxLayout() self.line1.addWidget(self.label1) self.line1.addWidget(self.date_edit) self.line1.addWidget(self.label1_checkbox) # Second Line: Account self.label2 = QLabel(self.tr("Account")) self.label2.setFixedWidth(80) self.account_select = QComboBox() currentaccounts = [a[0] for a in balances.get_all_accounts()] self.account_select.addItems(currentaccounts) self.line2 = QHBoxLayout() self.line2.addWidget(self.label2) self.line2.addWidget(self.account_select, Qt.AlignLeft) # Third Line: Strategy self.label3 = QLabel(self.tr("Strategy")) self.label3.setFixedWidth(80) self.strategy_select = QComboBox() self.strategy_select.setEditable(True) self.strategy_select.setDuplicatesEnabled(False) currentstrategies = [i[0] for i in strategies.get_all_strategies()] self.strategy_select.addItems(currentstrategies) self.line3 = QHBoxLayout() self.line3.addWidget(self.label3) self.line3.addWidget(self.strategy_select, Qt.AlignLeft) # Fourth Line: Amount self.label4 = QLabel(self.tr("Amount")) self.label4.setFixedWidth(80) self.amount_select = QSpinBox() self.amount_select.setSuffix(" €") self.amount_select.setMinimum(-2147483647) self.amount_select.setMaximum(2147483647) self.amount_select.setAccelerated(True) self.adjust_by_new_balance = QPushButton(self.tr("Adjust")) self.adjust_by_new_balance.clicked.connect(self.showAdjustDialog) self.line4 = QHBoxLayout() self.line4.addWidget(self.label4) self.line4.addWidget(self.amount_select, Qt.AlignLeft) self.line4.addWidget(self.adjust_by_new_balance) # Fifth Line: Description self.label5 = QLabel(self.tr("Description")) self.label5.setFixedWidth(80) self.description_select = QLineEdit() self.line5 = QHBoxLayout() self.line5.addWidget(self.label5) self.line5.addWidget(self.description_select, Qt.AlignLeft) # Buttons self.button_layout = QHBoxLayout() self.insert_button = QPushButton(self.tr("Insert")) self.insert_button.setMaximumWidth(50) self.button_layout.setAlignment(Qt.AlignHCenter | Qt.AlignTop) # Centering it self.button_layout.setContentsMargins(QMargins( 10, 10, 10, 10)) # A little bit of margin self.insert_button.clicked.connect(self.insertResult) self.button_layout.addWidget(self.insert_button, Qt.AlignVCenter) self.addWidget(self.title) self.addLayout(self.line1) self.addLayout(self.line2) self.addLayout(self.line3) self.addLayout(self.line4) self.addLayout(self.line5) self.addLayout(self.button_layout) self.addWidget(self.insert_button) def setToday(self): self.date_edit.setDate(datetime.now()) def insertResult(self): """ Insert current form state as a result on the database """ current_date = datetime(self.date_edit.date().year(), self.date_edit.date().month(), self.date_edit.date().day()).timestamp() current_account = self.account_select.currentText() current_strategy = self.strategy_select.currentText() current_amount = self.amount_select.text()[:-2] current_description = self.description_select.text() results.add_result(current_date, current_account, current_strategy, current_amount, description=current_description) # Resetting Account and Strategy QComboBoxes self.account_select.clear() self.strategy_select.clear() currentaccounts = [a[0] for a in balances.get_all_accounts()] self.account_select.addItems(currentaccounts) currentstrategies = [i[0] for i in strategies.get_all_strategies()] self.strategy_select.addItems(currentstrategies) self.resultAdded.emit() def showAdjustDialog(self): """ Shows Dialog to add a result by new balance """ currentdate = self.date_edit.text() currentaccount = self.account_select.currentText() self.adjust_by_new_balance_dlg = AdjustResultNewBalanceDialog( currentdate, currentaccount) self.adjust_by_new_balance_dlg.show()
class SpotCommodityPage(QWidget): def __init__(self, *args, **kwargs): super(SpotCommodityPage, self).__init__(*args, **kwargs) layout = QVBoxLayout(margin=0, spacing=2) # 日期选择、信息展示与新增按钮 message_button_layout = QHBoxLayout() self.date_edit = QDateEdit(QDate.currentDate(), dateChanged=self.getCurrentSpotCommodity) self.date_edit.setDisplayFormat('yyyy-MM-dd') self.date_edit.setCalendarPopup(True) message_button_layout.addWidget(QLabel('日期:')) message_button_layout.addWidget(self.date_edit) self.network_message_label = QLabel() message_button_layout.addWidget(self.network_message_label) message_button_layout.addStretch() # 伸缩 message_button_layout.addWidget(QPushButton('新增', clicked=self.create_spot_table), alignment=Qt.AlignRight) layout.addLayout(message_button_layout) # 当前数据显示表格 self.spot_table = SpotCommodityTable() layout.addWidget(self.spot_table) self.setLayout(layout) # 上传数据的进度条 self.process_widget = QWidget(self) self.process_widget.resize(self.width(), self.height()) process_layout = QVBoxLayout(self.process_widget) process_layout.addStretch() self.process_message = QLabel("数据上传处理中..", self.process_widget) process_layout.addWidget(self.process_message) process = QProgressBar(parent=self.process_widget) process.setMinimum(0) process.setMaximum(0) process.setTextVisible(False) process_layout.addWidget(process) process_layout.addStretch() self.process_widget.setLayout(process_layout) self.process_widget.hide() self.process_widget.setStyleSheet("background:rgb(200,200,200);opacity:0.6") # 获取当前时间的现货报表 def getCurrentSpotCommodity(self): current_date = self.date_edit.text() current_page = 1 try: user_id = pickle.loads(settings.app_dawn.value("UKEY")) r = requests.get( url=settings.SERVER_ADDR + 'user/'+str(user_id) + '/spot/?page=' +str(current_page) +'&page_size=50&date=' + current_date ) response = json.loads(r.content.decode('utf-8')) if r.status_code != 200: raise ValueError(response['message']) except Exception as e: self.network_message_label.setText(str(e)) else: print(response) self.spot_table.showRowContents(response['spots']) self.network_message_label.setText(response['message']) # 新增现货报表数据 def create_spot_table(self): self.popup = CreateNewSpotTablePopup(parent=self) self.popup.exec_()
class WindowOption(QWidget): def __init__(self): super(WindowOption, self).__init__() self.initUI() def initUI(self): """# Global """ self.setWindowTitle('Option') self.setFixedSize(800, 450) self.list_option = QListWidget(self) self.stack_window = QStackedWidget(self) self.style_list_option = "QListWidget{\ min-width: 120px;\ max-width: 120px;\ color: white;\ background: grey;}" self.style_groupbox = "QGroupBox{\ border: None;}" self.style_groupbox_font = "QGroupBox{\ font-family: MonoxRegular;\ font-size: 20px;}" layout_main = QHBoxLayout(spacing=0) layout_main.setContentsMargins(0, 0, 0, 0) layout_main.addWidget(self.list_option) layout_main.addWidget(self.stack_window) self.setLayout(layout_main) self.list_option.setStyleSheet(self.style_list_option) """# List Option""" self.list_option.setFrameShape(QListWidget.NoFrame) self.list_option.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.list_option.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.list_option.currentRowChanged.connect( self.stack_window.setCurrentIndex) font = QFont() font.setFamily('MonoxLight') font.setPointSize(20) item = QListWidgetItem() item.setFont(font) item.setText('DIY') item.setSizeHint(QSize(0, 60)) item.setTextAlignment(Qt.AlignCenter) self.list_option.addItem(item) item = QListWidgetItem() item.setFont(font) item.setText('PRO') item.setSizeHint(QSize(0, 60)) item.setTextAlignment(Qt.AlignCenter) self.list_option.addItem(item) """# Stack Window""" """# Page 0""" self.page0 = QWidget() self.tabwidget_page0 = QTabWidget(self.page0) self.tab0_page0 = QWidget(self.page0) self.tab1_page0 = QWidget(self.page0) self.tabwidget_page0.addTab(self.tab0_page0, 'Info') self.tabwidget_page0.addTab(self.tab1_page0, 'Option') self.page0tab0() self.page0tab1() self.page0global() self.page1tab0() self.page1tab1() self.page1global() def keyReleaseEvent(self, event): """DocString for pressKeyEwent""" #@todo: to be defined. if event.key() == Qt.Key_D: self.list_option.setCurrentRow(0) self.stack_window.setCurrentIndex(0) if event.key() == Qt.Key_P: self.list_option.setCurrentRow(1) self.stack_window.setCurrentIndex(1) if event.key() == Qt.Key_O: if self.stack_window.currentIndex() == 1: self.tabwidget_page1.setCurrentIndex(1) else: self.tabwidget_page0.setCurrentIndex(1) if event.key() == Qt.Key_I: if self.stack_window.currentIndex() == 1: self.tabwidget_page1.setCurrentIndex(0) else: self.tabwidget_page0.setCurrentIndex(0) if event.key() == Qt.Key_Return: if self.stack_window.currentIndex() == 1: self.pushbutton_ok_page1.click() else: self.pushbutton_ok_page0.click() if event.key() == Qt.Key_R: if self.stack_window.currentIndex() == 1: self.pushbutton_re_page1.click() else: self.pushbutton_re_page0.click() if event.key() == Qt.Key_Q: self.close() def page0tab0(self): """DocString for page0tab0""" #@todo: to be defined. font = QFont() font.setFamily('MonoxLight') font.setPointSize(12) label_date_page0 = QLabel('Date ') label_date_page0.setFont(font) label_time_page0 = QLabel('Time ') label_time_page0.setFont(font) label_loc_page0 = QLabel('Location ') label_loc_page0.setFont(font) label_users_name_page0 = QLabel('Name ') label_users_name_page0.setFont(font) font_spe = QFont() font_spe.setFamily('MonoxRegular Bold') font_spe.setPointSize(12) label_users_gender_page0 = QLabel('Gender') label_users_gender_page0.setFont(font_spe) label_note_page0 = QLabel('Note') label_note_page0.setFont(font) self.dateedit_date_page0 = QDateEdit(QDate.currentDate()) self.dateedit_date_page0.setDisplayFormat('yyyy/MM/dd') self.dateedit_date_page0.setCalendarPopup(True) self.dateedit_date_page0.setFont(font) self.timeedit_time_page0 = QTimeEdit(QTime.currentTime()) self.timeedit_time_page0.setDisplayFormat('HH : mm') self.timeedit_time_page0.setFont(font) self.lineedit_loc_page0 = QLineEdit('Mars') self.lineedit_loc_page0.setFont(font) self.lineedit_users_name_page0 = QLineEdit('Object') self.lineedit_users_name_page0.setFont(font) self.radiobutton_users_gender_male_page0 = QRadioButton('Male') self.radiobutton_users_gender_female_page0 = QRadioButton('Female') self.radiobutton_users_gender_secret_page0 = QRadioButton('Secret') self.textedit_note_page0 = QTextEdit('None') self.textedit_note_page0.setFont(font) line_split_page0 = QFrame() line_split_page0.setFrameShape(QFrame.VLine) line_split_page0.setFrameShadow(QFrame.Sunken) groupbox_radio_button = QGroupBox() groupbox_radio_button.setStyleSheet(self.style_groupbox) layout_groupbox_radio_button = QHBoxLayout() layout_groupbox_radio_button.addWidget( self.radiobutton_users_gender_male_page0) layout_groupbox_radio_button.addWidget( self.radiobutton_users_gender_female_page0) layout_groupbox_radio_button.addWidget( self.radiobutton_users_gender_secret_page0) groupbox_radio_button.setLayout(layout_groupbox_radio_button) layout_tab0_page0_global = QVBoxLayout(self.tab0_page0) layout_info_page0 = QHBoxLayout() layout_note_page0 = QVBoxLayout() layout_time_page0 = QVBoxLayout() layout_user_page0 = QVBoxLayout() layout_date_page0 = QHBoxLayout() layout_date_page0.setAlignment(Qt.AlignLeft) layout_clock_page0 = QHBoxLayout() layout_clock_page0.setAlignment(Qt.AlignLeft) layout_loc_page0 = QHBoxLayout() layout_loc_page0.setAlignment(Qt.AlignLeft) layout_name_page0 = QHBoxLayout() layout_gender_page0 = QVBoxLayout() layout_date_page0.addWidget(label_date_page0) layout_date_page0.addWidget(self.dateedit_date_page0) layout_clock_page0.addWidget(label_time_page0) layout_clock_page0.addWidget(self.timeedit_time_page0) layout_loc_page0.addWidget(label_loc_page0) layout_loc_page0.addWidget(self.lineedit_loc_page0) layout_name_page0.addWidget(label_users_name_page0) layout_name_page0.addWidget(self.lineedit_users_name_page0) layout_gender_page0.addWidget(label_users_gender_page0) layout_gender_page0.addWidget(groupbox_radio_button) layout_time_page0.addLayout(layout_date_page0) layout_time_page0.addLayout(layout_clock_page0) layout_time_page0.addLayout(layout_loc_page0) layout_user_page0.addLayout(layout_name_page0) layout_user_page0.addLayout(layout_gender_page0) layout_info_page0.addLayout(layout_time_page0) layout_info_page0.addWidget(line_split_page0) layout_info_page0.addLayout(layout_user_page0) layout_note_page0.addWidget(label_note_page0) layout_note_page0.addWidget(self.textedit_note_page0) layout_tab0_page0_global.addLayout(layout_info_page0) layout_tab0_page0_global.addLayout(layout_note_page0) self.tab0_page0.setLayout(layout_tab0_page0_global) def page0tab1(self): """DocString for page0tab1""" #@todo: to be defined. font = QFont() font.setFamily('MonoxLight') font.setPointSize(12) def page0global(self): """DocString for page0global""" #@todo: to be defined. self.pushbutton_ok_page0 = QPushButton('&Ok') self.pushbutton_re_page0 = QPushButton('&Reset') self.pushbutton_de_page0 = QPushButton('&Cancel') layout_page0_option = QHBoxLayout() layout_page0_option.addStretch(1) layout_page0_option.addWidget(self.pushbutton_ok_page0) layout_page0_option.addWidget(self.pushbutton_re_page0) layout_page0_option.addWidget(self.pushbutton_de_page0) layout_page0_global = QVBoxLayout(self.page0) layout_page0_global.addWidget(self.tabwidget_page0) layout_page0_global.addLayout(layout_page0_option) self.stack_window.addWidget(self.page0) self.page1 = QWidget() self.tabwidget_page1 = QTabWidget(self.page1) self.tab0_page1 = QWidget(self.page1) self.tab1_page1 = QWidget(self.page1) self.tabwidget_page1.addTab(self.tab0_page1, 'Info') self.tabwidget_page1.addTab(self.tab1_page1, 'Option') def page1tab0(self): """DocString for page1tab0""" #@todo: to be defined. font = QFont() font.setFamily('MonoxLight') font.setPointSize(12) label_date_page1 = QLabel('Date ') label_date_page1.setFont(font) label_time_page1 = QLabel('Time ') label_time_page1.setFont(font) label_loc_page1 = QLabel('Location ') label_loc_page1.setFont(font) label_users_name_page1 = QLabel('Name ') label_users_name_page1.setFont(font) label_users_gender_page1 = QLabel('Gender') label_users_gender_page1.setFont(font) label_note_page1 = QLabel('Note') label_note_page1.setFont(font) line_split_page1 = QFrame() line_split_page1.setFrameShape(QFrame.VLine) line_split_page1.setFrameShadow(QFrame.Sunken) self.dateedit_date_page1 = QDateEdit(QDate.currentDate()) self.dateedit_date_page1.setDisplayFormat('yyyy/MM/dd') self.dateedit_date_page1.setCalendarPopup(True) self.dateedit_date_page1.setFont(font) self.timeedit_time_page1 = QTimeEdit(QTime.currentTime()) self.timeedit_time_page1.setDisplayFormat('HH : mm') self.timeedit_time_page1.setFont(font) self.lineedit_loc_page1 = QLineEdit('Mars') self.lineedit_loc_page1.setFont(font) self.lineedit_users_name_page1 = QLineEdit('Object') self.lineedit_users_name_page1.setFont(font) self.radiobutton_users_gender_male_page1 = QRadioButton('Male') self.radiobutton_users_gender_female_page1 = QRadioButton('Female') self.radiobutton_users_gender_secret_page1 = QRadioButton('Secret') self.textedit_note_page1 = QTextEdit('None') self.textedit_note_page1.setFont(font) groupbox_radio_button = QGroupBox() groupbox_radio_button.setStyleSheet(self.style_groupbox) layout_groupbox_radio_button = QHBoxLayout() layout_groupbox_radio_button.addWidget( self.radiobutton_users_gender_male_page1) layout_groupbox_radio_button.addWidget( self.radiobutton_users_gender_female_page1) layout_groupbox_radio_button.addWidget( self.radiobutton_users_gender_secret_page1) groupbox_radio_button.setLayout(layout_groupbox_radio_button) layout_tab0_page1_global = QVBoxLayout(self.tab0_page1) layout_info_page1 = QHBoxLayout() layout_note_page1 = QVBoxLayout() layout_time_page1 = QVBoxLayout() layout_user_page1 = QVBoxLayout() layout_date_page1 = QHBoxLayout() layout_date_page1.setAlignment(Qt.AlignLeft) layout_clock_page1 = QHBoxLayout() layout_clock_page1.setAlignment(Qt.AlignLeft) layout_loc_page1 = QHBoxLayout() layout_loc_page1.setAlignment(Qt.AlignLeft) layout_name_page1 = QHBoxLayout() layout_gender_page1 = QVBoxLayout() layout_date_page1.addWidget(label_date_page1) layout_date_page1.addWidget(self.dateedit_date_page1) layout_clock_page1.addWidget(label_time_page1) layout_clock_page1.addWidget(self.timeedit_time_page1) layout_loc_page1.addWidget(label_loc_page1) layout_loc_page1.addWidget(self.lineedit_loc_page1) layout_name_page1.addWidget(label_users_name_page1) layout_name_page1.addWidget(self.lineedit_users_name_page1) layout_gender_page1.addWidget(label_users_gender_page1) layout_gender_page1.addWidget(groupbox_radio_button) layout_time_page1.addLayout(layout_date_page1) layout_time_page1.addLayout(layout_clock_page1) layout_time_page1.addLayout(layout_loc_page1) layout_user_page1.addLayout(layout_name_page1) layout_user_page1.addLayout(layout_gender_page1) layout_info_page1.addLayout(layout_time_page1) layout_info_page1.addWidget(line_split_page1) layout_info_page1.addLayout(layout_user_page1) layout_note_page1.addWidget(label_note_page1) layout_note_page1.addWidget(self.textedit_note_page1) layout_tab0_page1_global.addLayout(layout_info_page1) layout_tab0_page1_global.addLayout(layout_note_page1) self.tab0_page1.setLayout(layout_tab0_page1_global) def page1tab1(self): """DocString for page1tab1""" #@todo: to be defined. font = QFont() font.setFamily('MonoxLight') font.setPointSize(12) label_filter_or_not = QLabel('Filter') label_filter_or_not.setFont(font) label_filter_hz1 = QLabel('Hz') label_filter_hz1.setFont(font) label_filter_hz2 = QLabel('Hz') label_filter_hz2.setFont(font) label_filter_hz3 = QLabel('Hz') label_filter_hz3.setFont(font) label_filter_hz4 = QLabel('Hz') label_filter_hz4.setFont(font) label_sampling_freq = QLabel('Sampling Frequency') label_sampling_freq.setFont(font) label_notch_filter = QLabel('Notch Filter') label_notch_filter.setFont(font) label_bandpass_filter = QLabel('Bandpass Filter') label_bandpass_filter.setFont(font) label_bandpass_filter_to = QLabel('to') label_bandpass_filter_to.setFont(font) label_set_num = QLabel('Set Number') label_set_num.setFont(font) label_set_time = QLabel('Set Time') label_set_time.setFont(font) label_set_interval = QLabel('Auto Restart') label_set_interval.setFont(font) label_set_interval_s = QLabel('s') label_set_interval_s.setFont(font) label_tcp_address = QLabel('TCP Address') label_tcp_address.setFont(font) label_tcp_port = QLabel('TCP Port') label_tcp_port.setFont(font) label_filetype_save = QLabel('Filetype') label_filetype_save.setFont(font) label_channel_num = QLabel('Channel Number') label_channel_num.setFont(font) self.spinbox_set_num = QSpinBox() self.spinbox_set_time = QSpinBox() self.lineedit_tcp_address = QLineEdit() self.lineedit_tcp_address.setFont(font) self.lineedit_tcp_port = QLineEdit() self.lineedit_tcp_port.setFont(font) self.combobox_bandpass_high = QComboBox() self.combobox_bandpass_high.addItem('1') self.combobox_bandpass_high.addItem('5') self.combobox_bandpass_high.addItem('10') self.combobox_bandpass_high.addItem('20') self.combobox_bandpass_low = QComboBox() self.combobox_bandpass_low.addItem('50') self.combobox_bandpass_low.addItem('100') self.combobox_bandpass_low.addItem('200') self.combobox_bandpass_low.addItem('450') self.combobox_sampling_freq = QComboBox() self.combobox_sampling_freq.addItem('250') self.combobox_sampling_freq.addItem('500') self.combobox_sampling_freq.addItem('1000') self.combobox_sampling_freq.addItem('2000') self.combobox_notch_filter = QComboBox() self.combobox_notch_filter.addItem('50') self.combobox_notch_filter.addItem('60') self.combobox_filetype_save = QComboBox() self.combobox_filetype_save.addItem('csv') self.combobox_filetype_save.addItem('npy') self.combobox_channel_num = QComboBox() self.combobox_channel_num.addItem('64') self.combobox_channel_num.addItem('128') self.combobox_channel_num.addItem('192') self.checkbox_notch_filter = QCheckBox('Notch Filter') self.checkbox_bandpass_filter = QCheckBox('Bandpass Filter') self.radiobutton_restart_auto = QRadioButton('Auto Restart') self.radiobutton_restart_press = QRadioButton('Manual Restart') self.spinbox_restart_auto = QSpinBox() groupbox_filter_page1 = QGroupBox('Filter') groupbox_filter_page1.setStyleSheet(self.style_groupbox_font) groupbox_data_page1 = QGroupBox('Data') groupbox_data_page1.setStyleSheet(self.style_groupbox_font) groupbox_tcpip_page1 = QGroupBox('TCP/IP') groupbox_tcpip_page1.setStyleSheet(self.style_groupbox_font) layout_filter_or_not = QHBoxLayout() layout_filter_notch = QHBoxLayout() layout_filter_bandpass = QHBoxLayout() layout_sampling_freq = QHBoxLayout() layout_button_filter_reset = QHBoxLayout() layout_filter_or_not.addWidget(label_filter_or_not) layout_filter_or_not.addWidget(self.checkbox_notch_filter) layout_filter_or_not.addWidget(self.checkbox_bandpass_filter) layout_filter_notch.addWidget(label_notch_filter) layout_filter_notch.addWidget(self.combobox_notch_filter) layout_filter_notch.addWidget(label_filter_hz1) layout_filter_bandpass.addWidget(label_bandpass_filter) layout_filter_bandpass.addWidget(self.combobox_bandpass_high) layout_filter_bandpass.addWidget(label_filter_hz2) layout_filter_bandpass.addWidget(label_bandpass_filter_to) layout_filter_bandpass.addWidget(self.combobox_bandpass_low) layout_filter_bandpass.addWidget(label_filter_hz3) layout_sampling_freq.addWidget(label_sampling_freq) layout_sampling_freq.addWidget(self.combobox_sampling_freq) layout_sampling_freq.addWidget(label_filter_hz4) layout_data_channel_num = QHBoxLayout() layout_data_set = QHBoxLayout() layout_data_interval = QVBoxLayout() layout_data_filetype = QHBoxLayout() layout_button_data_reset = QHBoxLayout() layout_data_channel_num.addWidget(label_channel_num) layout_data_channel_num.addWidget(self.combobox_channel_num) layout_data_interval_auto = QHBoxLayout() layout_data_interval_press = QHBoxLayout() layout_data_interval_auto.addWidget(self.radiobutton_restart_auto) layout_data_interval_auto.addWidget(self.spinbox_restart_auto) layout_data_interval_auto.addWidget(label_set_interval_s) layout_data_interval_press.addWidget(self.radiobutton_restart_press) layout_data_interval.addLayout(layout_data_interval_auto) layout_data_interval.addLayout(layout_data_interval_press) layout_data_set.addWidget(label_set_num) layout_data_set.addWidget(self.spinbox_set_num) layout_data_set.addWidget(label_set_time) layout_data_set.addWidget(self.spinbox_set_time) layout_data_filetype.addWidget(label_filetype_save) layout_data_filetype.addWidget(self.combobox_filetype_save) layout_filter_page1 = QVBoxLayout() layout_filter_page1.addLayout(layout_filter_or_not) layout_filter_page1.addLayout(layout_filter_notch) layout_filter_page1.addLayout(layout_filter_bandpass) layout_filter_page1.addLayout(layout_sampling_freq) layout_data_page1 = QVBoxLayout() layout_data_page1.addLayout(layout_data_channel_num) layout_data_page1.addLayout(layout_data_set) layout_data_page1.addLayout(layout_data_interval) layout_data_page1.addLayout(layout_data_filetype) layout_tcpip_page1_global = QVBoxLayout() layout_tcpip_data = QHBoxLayout() layout_tcpip_button_reset = QHBoxLayout() layout_tcpip_data.addWidget(label_tcp_address) layout_tcpip_data.addWidget(self.lineedit_tcp_address) layout_tcpip_data.addWidget(label_tcp_port) layout_tcpip_data.addWidget(self.lineedit_tcp_port) layout_tcpip_page1_global.addLayout(layout_tcpip_data) groupbox_filter_page1.setLayout(layout_filter_page1) groupbox_data_page1.setLayout(layout_data_page1) groupbox_tcpip_page1.setLayout(layout_tcpip_page1_global) layout_tab1_page1_up = QHBoxLayout() layout_tab1_page1_down = QHBoxLayout() layout_tab1_page1_up.addWidget(groupbox_filter_page1) layout_tab1_page1_up.addWidget(groupbox_data_page1) layout_tab1_page1_down.addWidget(groupbox_tcpip_page1) layout_tab1_page1_global = QVBoxLayout() layout_tab1_page1_global.addLayout(layout_tab1_page1_up) layout_tab1_page1_global.addLayout(layout_tab1_page1_down) self.tab1_page1.setLayout(layout_tab1_page1_global) def page1global(self): """DocString for page1global""" #@todo: to be defined. self.pushbutton_ok_page1 = QPushButton('&Ok') self.pushbutton_de_page1 = QPushButton('&Cancel') self.pushbutton_re_page1 = QPushButton('&Reset') layout_page1_option = QHBoxLayout() layout_page1_option.addStretch(1) layout_page1_option.addWidget(self.pushbutton_ok_page1) layout_page1_option.addWidget(self.pushbutton_re_page1) layout_page1_option.addWidget(self.pushbutton_de_page1) layout_page1_global = QVBoxLayout() layout_page1_global.addWidget(self.tabwidget_page1) layout_page1_global.addLayout(layout_page1_option) self.page1.setLayout(layout_page1_global) self.stack_window.addWidget(self.page1)
class CadastroProduto(BaseSubWindow): def __init__(self, parent=None, categorias=None, unidades=None): '''Inicia a classe com os seguintes parametros: -parent: classe que instanciou esta classe''' super().__init__("Cadastro de Produto", 300) self.parent = parent self.categorias = self.parent.categoria.getCategorias() self.unidades = self.parent.unidade.getUnidades() self.base_form = BaseFormulario(self) self.setWidgets() self.base_form.setStyleSheetForm() self.setLayoutCadastro() self.setActionButton() self.base_form.connectValidaCampo() def setWidgets(self): '''Cria os Widgets da tela da área do gerente''' self.conteudo = QWidget() self.lbl_title = QLabel("DADOS DO PRODUTO") self.lbl_title.setStyleSheet("QLabel{font:bold}") self.edit_codigo = QLineEdit() self.edit_codigo.setValidator(QRegExpValidator( QRegExp("[0-9]{1,99}" ))) #Valida Numeros inteiros no min 1 digito e no max 99 self.edit_lote = QLineEdit() #Cria o selectbox e insere os valores do banco de dados no mesmo self.cb_categoria = QComboBox() for id_categoria, categoria in self.categorias: self.cb_categoria.addItem(categoria, id_categoria) self.edit_nome = QLineEdit() self.edit_descricao = QLineEdit() self.edit_quantidade = QLineEdit() self.edit_quantidade.setValidator( QRegExpValidator(QRegExp("\-?\d+\.\d+"))) self.cb_unidade = QComboBox() #Cria o selectbox e insere os valores do banco de dados no mesmo for id_unidade, sigla, unidade in self.unidades: self.cb_unidade.addItem(unidade, id_unidade) self.edit_peso = QLineEdit() self.edit_peso.setValidator(QRegExpValidator(QRegExp("\-?\d+\.\d+"))) self.edit_local = QLineEdit() self.edit_data = QDateEdit(QDate.currentDate()) self.edit_data.setDisplayFormat("yyyy/MM/dd") self.edit_data.setCalendarPopup(True) self.btn_cadastrar = QPushButton("Cadastrar") self.btn_cadastrar.setAutoDefault(True) def setLayoutCadastro(self): '''Posiciona os Widgets da tela da área do gerente''' self.layout_form = QFormLayout() self.layout_form.setRowWrapPolicy(QFormLayout.WrapAllRows) self.layout_form.addRow(self.lbl_title) self.layout_form.addRow("Código de Barras", self.edit_codigo) self.layout_form.addRow("Lote", self.edit_lote) self.layout_form.addRow("Categoria", self.cb_categoria) self.layout_form.addRow("Nome", self.edit_nome) self.layout_form.addRow("Descriçao", self.edit_descricao) self.layout_form.addRow("Quantidade", self.edit_quantidade) self.layout_form.addRow("Unidade", self.cb_unidade) self.layout_form.addRow("Peso(kg)", self.edit_peso) self.layout_form.addRow("Local de Armazenamento", self.edit_local) self.layout_form.addRow("Data de Vencimento", self.edit_data) self.layout_form.addRow(self.btn_cadastrar) self.conteudo.setLayout(self.layout_form) self.setWidget(self.conteudo) def setActionButton(self): self.btn_cadastrar.clicked.connect(self.parent.cadastrarProduto) def showMessageSucesso(self): '''Exibe uma Dialog com a menssagem de sucesso ao cadastro Retorno: False - Se o usuario não for mais fazer cadastros ''' result = QMessageBox.question( self, "Sucesso", "Produto cadastrado com sucesso! \nCadastrar novo produto?", QMessageBox.Yes, QMessageBox.No) if (result == QMessageBox.Yes): self.base_form.clearLineEdit() self.base_form.setStyleSheetForm() else: self.base_form.clearLineEdit() return False
class ClientEditor(QWidget): def __init__(self, win): QWidget.__init__(self) self.win = win self.id = 0 title = QLabel("Client Data") fnt = title.font() fnt.setPointSize(20) fnt.setBold(True) title.setFont(fnt) self.layout = QGridLayout() self.layout.setColumnStretch(0, 1) self.number = QLineEdit() self.name = QLineEdit() self.email = QLineEdit() self.profession = QLineEdit() self.address = QLineEdit() self.mobile = QLineEdit() self.reason = QLineEdit() self.how = QLineEdit() self.fiscal = QLineEdit() self.notes = QTextEdit() self.birthday = QDateEdit() self.birthday.setCalendarPopup(True) self.birthday.setDisplayFormat("dd.MM.yyyy") self.firstcontact = QDateEdit(QDate.currentDate()) self.firstcontact.setDisplayFormat("dd.MM.yyyy") self.firstcontact.setCalendarPopup(True) self.image = ImageSelector() self.image.setImage(QImage(":/images/image_placeholder.png")) self.image.setMinimumWidth(250) self.layout.addWidget(title, 0, 0, 1, 2) self.layout.addWidget(QLabel("Number"), 1, 0) self.layout.addWidget(self.number, 2, 0) self.layout.addWidget(QLabel("Name"), 3, 0) self.layout.addWidget(self.name, 4, 0) self.layout.addWidget(QLabel("Address"), 5, 0) self.layout.addWidget(self.address, 6, 0) self.layout.addWidget(QLabel("Email"), 7, 0) self.layout.addWidget(self.email, 8, 0) self.layout.addWidget(QLabel("Mobile"), 9, 0) self.layout.addWidget(self.mobile, 10, 0) self.layout.addWidget(QLabel("Profession"), 11, 0) self.layout.addWidget(self.profession, 12, 0) self.layout.addWidget(QLabel("Reason"), 13, 0) self.layout.addWidget(self.reason, 14, 0) self.layout.addWidget(QLabel("How did you get here?"), 15, 0) self.layout.addWidget(self.how, 16, 0) self.layout.addWidget(QLabel("Notes"), 17, 0) self.layout.addWidget(self.notes, 18, 0, 1, 2) self.layout.addWidget(self.image, 2, 1, 7, 1) self.layout.addWidget(QLabel("Birhday"), 9, 1) self.layout.addWidget(self.birthday, 10, 1) self.layout.addWidget(QLabel("First Contact"), 11, 1) self.layout.addWidget(self.firstcontact, 12, 1) self.layout.addWidget(QLabel("Fiscal"), 13, 1) self.layout.addWidget(self.fiscal, 14, 1, 1, 1) self.setLayout(self.layout) self.reload() self.number.textEdited.connect(self.clientChanged) self.name.textEdited.connect(self.clientChanged) self.address.textEdited.connect(self.clientChanged) self.email.textEdited.connect(self.clientChanged) self.mobile.textEdited.connect(self.clientChanged) self.profession.textEdited.connect(self.clientChanged) self.reason.textEdited.connect(self.clientChanged) self.how.textEdited.connect(self.clientChanged) self.notes.textChanged.connect(self.clientChanged) self.fiscal.textEdited.connect(self.clientChanged) self.birthday.dateChanged.connect(self.clientChanged) self.firstcontact.dateChanged.connect(self.clientChanged) def reload(self): self.loading = True if self.win.client: self.number.setText(self.win.client["number"]) self.name.setText(self.win.client["name"]) self.address.setText(self.win.client["address"]) self.email.setText(self.win.client["email"]) self.mobile.setText(self.win.client["mobile"]) self.profession.setText(self.win.client["profession"]) self.reason.setText(self.win.client["reason"]) self.how.setText(self.win.client["how"]) self.notes.setText(self.win.client["notes"]) self.birthday.setDate( QDate(self.win.client["birthday_year"], self.win.client["birthday_month"], self.win.client["birthday_day"])) self.firstcontact.setDate( QDate(self.win.client["first_contact_year"], self.win.client["first_contact_month"], self.win.client["first_contact_day"])) self.fiscal.setText(self.win.client["fiscal"]) else: self.number.setText("") self.name.setText("") self.address.setText("") self.email.setText("") self.mobile.setText("") self.profession.setText("") self.reason.setText("") self.how.setText("") self.notes.setText("") self.fiscal.setText("") self.birthday.setDate(QDate(1900, 1, 1)) self.firstcontact.setDate(QDate(1900, 1, 1)) self.loading = False def clientChanged(self): if self.loading: return self.win.client["number"] = self.number.text() self.win.client["name"] = self.name.text() self.win.client["address"] = self.address.text() self.win.client["email"] = self.email.text() self.win.client["mobile"] = self.mobile.text() self.win.client["profession"] = self.profession.text() self.win.client["reason"] = self.reason.text() self.win.client["how"] = self.how.text() self.win.client["notes"] = self.notes.toPlainText() self.win.client["fiscal"] = self.fiscal.text() self.win.client["birthday_year"] = self.birthday.date().year() self.win.client["birthday_month"] = self.birthday.date().month() self.win.client["birthday_day"] = self.birthday.date().day() self.win.client["first_contact_year"] = self.firstcontact.date().year() self.win.client["first_contact_month"] = self.firstcontact.date( ).month() self.win.client["first_contact_day"] = self.firstcontact.date().day() self.win.clients.update(self.win.client, doc_ids=[self.win.client.doc_id]) self.win.updateClient()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.lastyear = int(time.strftime('%Y', time.localtime(time.time()))) - 1 self.in_parameters = {u'datetime': str(self.lastyear) + u'年', u'target_area': u'绍兴市', u'density_cell': u'10', u'density_class': 10, u'day_cell': u'15', u'day_class': 10, u'out_type': u'tiff'} self.setupUi() def setupUi(self): self.setObjectName("MainWindow") self.setFixedSize(1040, 915) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) icon = QIcon() icon.addPixmap(QPixmap('./resource/weather-thunder.png'),QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.centralwidget = QWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) self.centralwidget.setSizePolicy(sizePolicy) self.centralwidget.setObjectName("centralwidget") self.layoutWidget = QWidget(self.centralwidget) self.layoutWidget.setGeometry(QRect(32, 10, 979, 851)) self.layoutWidget.setObjectName("layoutWidget") self.verticalLayout_5 =QVBoxLayout(self.layoutWidget) self.verticalLayout_5.setContentsMargins(0, 0, 0, 0) self.verticalLayout_5.setObjectName("verticalLayout_5") self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.datetime_label = QLabel(self.layoutWidget) self.datetime_label.setObjectName("datetime_label") self.horizontalLayout.addWidget(self.datetime_label) self.datetime = QDateEdit(self.layoutWidget) self.datetime.setDateTime(QDateTime(QDate(self.lastyear, 1, 1), QTime(0, 0, 0))) self.datetime.setObjectName("datetime") self.horizontalLayout.addWidget(self.datetime) spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem1) self.target_area_label = QLabel(self.layoutWidget) self.target_area_label.setObjectName("target_area_label") self.horizontalLayout.addWidget(self.target_area_label) self.target_area = QComboBox(self.layoutWidget) self.target_area.setObjectName("target_area") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.horizontalLayout.addWidget(self.target_area) spacerItem2 = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.verticalLayout_5.addLayout(self.horizontalLayout) self.tabWidget = QTabWidget(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) self.tabWidget.setSizePolicy(sizePolicy) self.tabWidget.setObjectName("tabWidget") self.density_tab = QWidget() self.density_tab.setObjectName("density_tab") self.verticalLayout_3 =QVBoxLayout(self.density_tab) self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_2 =QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.density_cell_label = QLabel(self.density_tab) self.density_cell_label.setObjectName("density_cell_label") self.horizontalLayout_2.addWidget(self.density_cell_label) self.density_cell = QSpinBox(self.density_tab) self.density_cell.setProperty("value", 10) self.density_cell.setObjectName("density_cell") self.horizontalLayout_2.addWidget(self.density_cell) spacerItem3 = QSpacerItem(40, 0, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem3) self.density_class_label = QLabel(self.density_tab) self.density_class_label.setObjectName("density_class_label") self.horizontalLayout_2.addWidget(self.density_class_label) self.density_class = QSpinBox(self.density_tab) self.density_class.setProperty("value", 10) self.density_class.setObjectName("density_class") self.horizontalLayout_2.addWidget(self.density_class) spacerItem4 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem4) self.density_mxd = QPushButton(self.density_tab) self.density_mxd.setObjectName("density_mxd") self.horizontalLayout_2.addWidget(self.density_mxd) self.verticalLayout_2.addLayout(self.horizontalLayout_2) self.density_view = QGraphicsView(self.density_tab) self.density_view.setObjectName("density_view") self.verticalLayout_2.addWidget(self.density_view) self.verticalLayout_3.addLayout(self.verticalLayout_2) self.tabWidget.addTab(self.density_tab, "") self.day_tab = QWidget() self.day_tab.setObjectName("day_tab") self.verticalLayout_4 =QVBoxLayout(self.day_tab) self.verticalLayout_4.setObjectName("verticalLayout_4") self.verticalLayout =QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout_3 =QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.day_cell_label = QLabel(self.day_tab) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.day_cell_label.sizePolicy().hasHeightForWidth()) self.day_cell_label.setSizePolicy(sizePolicy) self.day_cell_label.setObjectName("day_cell_label") self.horizontalLayout_3.addWidget(self.day_cell_label) self.day_cell = QSpinBox(self.day_tab) self.day_cell.setProperty("value", 15) self.day_cell.setObjectName("day_cell") self.horizontalLayout_3.addWidget(self.day_cell) spacerItem5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem5) self.day_class_label = QLabel(self.day_tab) self.day_class_label.setObjectName("day_class_label") self.horizontalLayout_3.addWidget(self.day_class_label) self.day_class = QSpinBox(self.day_tab) self.day_class.setProperty("value", 10) self.day_class.setObjectName("day_class") self.horizontalLayout_3.addWidget(self.day_class) spacerItem6 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem6) self.day_mxd = QPushButton(self.day_tab) self.day_mxd.setObjectName("day_mxd") self.horizontalLayout_3.addWidget(self.day_mxd) self.verticalLayout.addLayout(self.horizontalLayout_3) self.day_view = QGraphicsView(self.day_tab) self.day_view.setObjectName("day_view") self.verticalLayout.addWidget(self.day_view) self.verticalLayout_4.addLayout(self.verticalLayout) self.tabWidget.addTab(self.day_tab, "") self.verticalLayout_5.addWidget(self.tabWidget) self.horizontalLayout_4 =QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.progressBar = QProgressBar(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth()) self.progressBar.setSizePolicy(sizePolicy) self.progressBar.setProperty("value", 0) self.progressBar.setObjectName("progressBar") self.horizontalLayout_4.addWidget(self.progressBar) self.execute_button = QPushButton(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.execute_button.sizePolicy().hasHeightForWidth()) self.execute_button.setSizePolicy(sizePolicy) self.execute_button.setObjectName("execute_button") self.horizontalLayout_4.addWidget(self.execute_button) self.verticalLayout_5.addLayout(self.horizontalLayout_4) self.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(self) self.menubar.setGeometry(QRect(0, 0, 1040, 26)) self.menubar.setObjectName("menubar") self.file_menu = QMenu(self.menubar) self.file_menu.setObjectName("file_menu") self.help_menu = QMenu(self.menubar) self.help_menu.setObjectName("help_menu") self.setMenuBar(self.menubar) self.statusbar = QStatusBar(self) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.action_add_data = QAction(self) self.action_add_data.setObjectName("action_add_data") self.action_help = QAction(self) self.action_help.setObjectName("action_help") self.action_about = QAction(self) self.action_about.setObjectName("action_about") self.action_save_pic = QAction(self) self.action_save_pic.setObjectName("action_save_pic") self.file_menu.addAction(self.action_add_data) self.file_menu.addAction(self.action_save_pic) self.help_menu.addAction(self.action_help) self.help_menu.addAction(self.action_about) self.menubar.addAction(self.file_menu.menuAction()) self.menubar.addAction(self.help_menu.menuAction()) self.retranslateUi() self.tabWidget.setCurrentIndex(0) QMetaObject.connectSlotsByName(self) self.center() self.show() self.target_area.activated[str].connect(self.updateTargetArea) self.datetime.dateChanged.connect(self.updateDatetime) self.density_cell.valueChanged.connect(self.updateDensityCell) self.density_class.valueChanged.connect(self.updateDensityClass) self.day_cell.valueChanged.connect(self.updateDayCell) self.day_class.valueChanged.connect(self.updateDayClass) self.action_add_data.triggered.connect(self.addData) self.action_save_pic.triggered.connect(self.savePic) self.action_about.triggered.connect(self.showAbout) self.action_help.triggered.connect(self.showHelp) self.execute_button.clicked.connect(self.execute) self.density_mxd.clicked.connect(self.openMxdDensity) self.day_mxd.clicked.connect(self.openMxdDay) self.density_mxd.setDisabled(True) self.day_mxd.setDisabled(True) self.action_save_pic.setDisabled(True) def execute(self): dir = u"E:/Documents/工作/雷电公报/闪电定位原始文本数据/" + self.in_parameters[u'datetime'] if os.path.exists(dir): datafiles = os.listdir(dir) datafiles = map(lambda x:os.path.join(dir,x),datafiles) self.in_parameters[u'origin_data_path'] = datafiles if not self.in_parameters.has_key(u'origin_data_path'): message = u"请加载%s的数据" % self.in_parameters[u'datetime'] msgBox = QMessageBox() msgBox.setText(message) msgBox.setIcon(QMessageBox.Information) icon = QIcon() icon.addPixmap(QPixmap('./resource/weather-thunder.png'), QIcon.Normal, QIcon.Off) msgBox.setWindowIcon(icon) msgBox.setWindowTitle(" ") msgBox.exec_() return self.execute_button.setDisabled(True) self.execute_button.setText(u'正在制图中……') self.progressBar.setMaximum(0) self.progressBar.setMinimum(0) self.action_add_data.setDisabled(True) self.target_area.setDisabled(True) self.datetime.setDisabled(True) self.density_cell.setDisabled(True) self.density_class.setDisabled(True) self.day_cell.setDisabled(True) self.day_class.setDisabled(True) # for outfile in self.in_parameters[u'origin_data_path']: # infile = # try: # with open(infile, 'w+') as in_f: # for line in in_f: # line = line.replace(u":",":") # in_f.write(line) # except Exception,inst: # print infile self.process_thread = WorkThread() self.process_thread.trigger.connect(self.finished) self.process_thread.beginRun(self.in_parameters) def finished(self): #绘制闪电密度图 ##清除上一次的QGraphicsView对象,防止其记录上一次图片结果,影响显示效果 self.density_view.setAttribute(Qt.WA_DeleteOnClose) self.verticalLayout_2.removeWidget(self.density_view) size = self.density_view.size() self.density_view.close() self.density_view = QGraphicsView(self.density_tab) self.density_view.setObjectName("density_view") self.density_view.resize(size) self.verticalLayout_2.addWidget(self.density_view) densityPic = ''.join([cwd,u'/bulletinTemp/', self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'闪电密度空间分布.tif']) scene = QGraphicsScene() pixmap_density = QPixmap(densityPic) scene.addPixmap(pixmap_density) self.density_view.setScene(scene) scale = float(self.density_view.width()) / pixmap_density.width() self.density_view.scale(scale, scale) #绘制雷暴日图 self.day_view.setAttribute(Qt.WA_DeleteOnClose) self.verticalLayout.removeWidget(self.day_view) size = self.day_view.size() self.day_view.close() self.day_view = QGraphicsView(self.day_tab) self.day_view.setObjectName("day_view") self.day_view.resize(size) self.verticalLayout.addWidget(self.day_view) dayPic = ''.join([cwd,u'/bulletinTemp/', self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif']) pixmap_day = QPixmap(dayPic) scene = QGraphicsScene() scene.addPixmap(pixmap_day) self.day_view.resize(self.density_view.width(),self.density_view.height()) self.day_view.setScene(scene) scale = float(self.day_view.width()) / pixmap_day.width() self.day_view.scale(scale, scale) #处理进度条和执行按钮状态 self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(100) self.progressBar.setFormat(u'完成!') self.execute_button.setDisabled(False) self.execute_button.setText(u'执行') #改变一些控件的状态 self.action_add_data.setDisabled(False) self.target_area.setDisabled(False) self.datetime.setDisabled(False) self.density_cell.setDisabled(False) self.density_class.setDisabled(False) self.day_cell.setDisabled(False) self.day_class.setDisabled(False) self.density_mxd.setDisabled(False) self.day_mxd.setDisabled(False) self.action_save_pic.setDisabled(False) def addData(self): fnames = QFileDialog.getOpenFileNames(self, u'请选择原始的电闪数据', u'E:/Documents/工作/雷电公报/闪电定位原始文本数据', 'Text files (*.txt);;All(*.*)') self.in_parameters[u'origin_data_path'] = fnames[0] def savePic(self): densityPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/', self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'闪电密度空间分布.tif']) dayPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/', self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif']) directory = QFileDialog.getExistingDirectory(self,u'请选择图片保存位置', u'E:/Documents/工作/雷电公报', QFileDialog.ShowDirsOnly|QFileDialog.DontResolveSymlinks) dest_density = os.path.join(directory,os.path.basename(densityPic)) dest_day = os.path.join(directory,os.path.basename(dayPic)) if os.path.isfile(dest_day) or os.path.isfile(dest_density): message = u"文件已经存在!" msgBox = QMessageBox() msgBox.setText(message) msgBox.setIcon(QMessageBox.Information) icon = QIcon() icon.addPixmap(QPixmap("./resource/weather-thunder.png"), QIcon.Normal, QIcon.Off) msgBox.setWindowIcon(icon) msgBox.setWindowTitle(" ") msgBox.exec_() return move(dayPic,directory) move(densityPic,directory) def openMxdDay(self): program = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe' src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb']) dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']]) src_file = ''.join([self.in_parameters[u'target_area'] , u"地闪雷暴日空间分布模板.mxd"]) copy(os.path.join(src_dir,src_file),dest_dir) arguments = [os.path.join(dest_dir,src_file)] self.process = QProcess(self) self.process.start(program,arguments) def openMxdDensity(self): program = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe' src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb']) dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']]) src_file = ''.join([self.in_parameters[u'target_area'] ,u"闪电密度空间分布模板.mxd"]) copy(os.path.join(src_dir,src_file),dest_dir) arguments = [os.path.join(dest_dir,src_file)] self.process = QProcess(self) self.process.start(program,arguments) def showAbout(self): self.about = About_Dialog() def showHelp(self): program = u'C:/Windows/hh.exe' arguments = [''.join([cwd,'/help/help.CHM'])] self.process = QProcess(self) self.process.start(program,arguments) def updateTargetArea(self, area): self.in_parameters[u'target_area'] = area def updateDatetime(self, date): self.in_parameters[u'datetime'] = str(date.year()) + u'年' if self.in_parameters.has_key(u'origin_data_path'): self.in_parameters.__delitem__(u'origin_data_path') def updateDensityCell(self, cell): self.in_parameters[u'density_cell'] = str(cell) def updateDensityClass(self, nclass): self.in_parameters[u'density_class'] = nclass def updateDayCell(self, cell): self.in_parameters[u'day_cell'] = str(cell) def updateDayClass(self, nclass): self.in_parameters[u'day_class'] = nclass def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def retranslateUi(self): _translate = QCoreApplication.translate self.setWindowTitle(_translate("MainWindow", "绍兴防雷中心 雷电公报制图")) self.datetime_label.setText(_translate("MainWindow", "年份")) self.datetime.setDisplayFormat(_translate("MainWindow", "yyyy")) self.target_area_label.setText(_translate("MainWindow", "地区")) self.target_area.setItemText(0, _translate("MainWindow", "绍兴市")) self.target_area.setItemText(1, _translate("MainWindow", "柯桥区")) self.target_area.setItemText(2, _translate("MainWindow", "上虞区")) self.target_area.setItemText(3, _translate("MainWindow", "诸暨市")) self.target_area.setItemText(4, _translate("MainWindow", "嵊州市")) self.target_area.setItemText(5, _translate("MainWindow", "新昌县")) self.density_cell_label.setText(_translate("MainWindow", "插值网格大小")) self.density_class_label.setText(_translate("MainWindow", "制图分类数目")) self.density_mxd.setText(_translate("MainWindow", "ArcGIS文档")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.density_tab), _translate("MainWindow", "电闪密度")) self.day_cell_label.setText(_translate("MainWindow", "插值网格大小")) self.day_class_label.setText(_translate("MainWindow", "制图分类数目")) self.day_mxd.setText(_translate("MainWindow", "ArcGIS文档")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.day_tab), _translate("MainWindow", "雷暴日")) self.execute_button.setText(_translate("MainWindow", "执行")) self.file_menu.setTitle(_translate("MainWindow", "文件")) self.help_menu.setTitle(_translate("MainWindow", "帮助")) self.action_add_data.setText(_translate("MainWindow", "加载数据")) self.action_help.setText(_translate("MainWindow", "使用说明")) self.action_about.setText(_translate("MainWindow", "关于")) self.action_save_pic.setText(_translate("MainWindow", "图片另存为"))
class NetPositionRateWidget(QWidget): def __init__(self, *args, **kwargs): super(NetPositionRateWidget, self).__init__(*args, **kwargs) lt = QVBoxLayout(self) lt.setContentsMargins(0, 0, 0, 0) self.setLayout(lt) # 操作头 opt_widget = TitleOptionWidget(self) opt_lt = QHBoxLayout(opt_widget) opt_widget.setLayout(opt_lt) opt_widget.setFixedHeight(45) lt.addWidget(opt_widget) # 显示表格 self.data_table = QTableWidget(self) self.data_table.setFrameShape(QFrame.NoFrame) self.data_table.verticalHeader().setDefaultSectionSize(22) self.data_table.setSelectionMode(QAbstractItemView.SingleSelection) self.data_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.data_table.setEditTriggers(QAbstractItemView.NoEditTriggers) # self.data_table.setFocusPolicy(Qt.NoFocus) lt.addWidget(self.data_table) self.start_date = QDateEdit(opt_widget) self.start_date.setDisplayFormat('yyyy-MM-dd') self.start_date.setCalendarPopup(True) year = QDate.currentDate().year() - 3 self.start_date.setDate(QDate(year, 1, 1)) self.end_date = QDateEdit(opt_widget) self.end_date.setDisplayFormat('yyyy-MM-dd') self.end_date.setCalendarPopup(True) self.end_date.setDate(QDate.currentDate()) opt_lt.addWidget(QLabel('开始日期:', opt_widget)) opt_lt.addWidget(self.start_date) opt_lt.addWidget(QLabel('结束日期:', opt_widget)) opt_lt.addWidget(self.end_date) self.query_button = QPushButton('查询', opt_widget) opt_lt.addWidget(self.query_button) self.query_status = QLabel(self) self.query_status.setStyleSheet('color:rgb(233,66,66)') opt_lt.addWidget(self.query_status) opt_lt.addStretch() # 网管器 self.network_manager = getattr(qApp, 'network') self.query_button.clicked.connect(self.query_net_position_analysis) self.query_net_position_analysis() # 点击表头排序 self.data_table.horizontalHeader().sectionClicked.connect( self.table_horizontal_clicked) def table_horizontal_clicked(self, col): if col < 7: return self.data_table.sortItems(col) self.set_row_colors() def query_net_position_analysis(self): self.query_status.setText('正在查询数据,请稍候...') url = SERVER_2_0 + 'dsas/pos/net-rate/?ds={}&de={}'.format( self.start_date.text(), self.end_date.text()) reply = self.network_manager.get(QNetworkRequest(QUrl(url))) reply.finished.connect(self.net_rate_position_reply) def net_rate_position_reply(self): reply = self.sender() if reply.error(): self.query_status.setText('查询数据失败了!{}'.format(reply.error())) else: data = json.loads(reply.readAll().data().decode('utf8')) self.table_show_data(data.get('data', [])) self.query_status.setText('查询数据成功!') def table_show_data(self, data): title = [ '日期', '品种', '主力收盘价', '权重价格', '前20多单', '前20空单', '前20净持仓', '最大净持率%', '最小净持率%', '当前净持率%', '百分位%' ] columns = [ 'quote_date', 'variety_name', 'close_price', 'weight_price', 'long_position', 'short_position', 'net_position', 'max_rate', 'min_rate', 'pos_rate', 'cur_pos' ] self.data_table.clear() self.data_table.setRowCount(len(data)) self.data_table.setColumnCount(len(columns)) self.data_table.setHorizontalHeaderLabels(title) for row, item in enumerate(data): for col, key in enumerate(columns): t_ = QTableWidgetItem() value = item[key] if key in ['max_rate', 'min_rate', 'pos_rate', 'cur_pos']: t_.setText(f'{value}%') t_.setData(Qt.DisplayRole, item[key]) if key == 'cur_pos': t_.setForeground(QBrush(QColor(234, 85, 4))) else: t_.setText(str(value)) t_.setTextAlignment(Qt.AlignCenter) self.data_table.setItem(row, col, t_) if row % 2 == 0: t_.setBackground(QBrush(QColor(221, 235, 247))) def set_row_colors(self): # 设置行颜色 row_count = self.data_table.rowCount() col_count = self.data_table.columnCount() for row in range(row_count): for col in range(col_count): item = self.data_table.item(row, col) if row % 2 == 0: item.setBackground(QBrush(QColor(221, 235, 247))) else: item.setBackground(QBrush(QColor(255, 255, 255)))
class Window(QWidget): def __init__(self): super(Window, self).__init__() self.createPreviewGroupBox() self.createGeneralOptionsGroupBox() self.createDatesGroupBox() self.createTextFormatsGroupBox() layout = QGridLayout() layout.addWidget(self.previewGroupBox, 0, 0) layout.addWidget(self.generalOptionsGroupBox, 0, 1) layout.addWidget(self.datesGroupBox, 1, 0) layout.addWidget(self.textFormatsGroupBox, 1, 1) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.previewLayout.setRowMinimumHeight(0, self.calendar.sizeHint().height()) self.previewLayout.setColumnMinimumWidth(0, self.calendar.sizeHint().width()) self.setWindowTitle("Calendar Widget") def localeChanged(self, index): self.calendar.setLocale(self.localeCombo.itemData(index)) def firstDayChanged(self, index): self.calendar.setFirstDayOfWeek( Qt.DayOfWeek(self.firstDayCombo.itemData(index))) def selectionModeChanged(self, index): self.calendar.setSelectionMode( QCalendarWidget.SelectionMode( self.selectionModeCombo.itemData(index))) def horizontalHeaderChanged(self, index): self.calendar.setHorizontalHeaderFormat( QCalendarWidget.HorizontalHeaderFormat( self.horizontalHeaderCombo.itemData(index))) def verticalHeaderChanged(self, index): self.calendar.setVerticalHeaderFormat( QCalendarWidget.VerticalHeaderFormat( self.verticalHeaderCombo.itemData(index))) def selectedDateChanged(self): self.currentDateEdit.setDate(self.calendar.selectedDate()) def minimumDateChanged(self, date): self.calendar.setMinimumDate(date) self.maximumDateEdit.setDate(self.calendar.maximumDate()) def maximumDateChanged(self, date): self.calendar.setMaximumDate(date) self.minimumDateEdit.setDate(self.calendar.minimumDate()) def weekdayFormatChanged(self): format = QTextCharFormat() format.setForeground( Qt.GlobalColor( self.weekdayColorCombo.itemData( self.weekdayColorCombo.currentIndex()))) self.calendar.setWeekdayTextFormat(Qt.Monday, format) self.calendar.setWeekdayTextFormat(Qt.Tuesday, format) self.calendar.setWeekdayTextFormat(Qt.Wednesday, format) self.calendar.setWeekdayTextFormat(Qt.Thursday, format) self.calendar.setWeekdayTextFormat(Qt.Friday, format) def weekendFormatChanged(self): format = QTextCharFormat() format.setForeground( Qt.GlobalColor( self.weekendColorCombo.itemData( self.weekendColorCombo.currentIndex()))) self.calendar.setWeekdayTextFormat(Qt.Saturday, format) self.calendar.setWeekdayTextFormat(Qt.Sunday, format) def reformatHeaders(self): text = self.headerTextFormatCombo.currentText() format = QTextCharFormat() if text == "Bold": format.setFontWeight(QFont.Bold) elif text == "Italic": format.setFontItalic(True) elif text == "Green": format.setForeground(Qt.green) self.calendar.setHeaderTextFormat(format) def reformatCalendarPage(self): if self.firstFridayCheckBox.isChecked(): firstFriday = QDate(self.calendar.yearShown(), self.calendar.monthShown(), 1) while firstFriday.dayOfWeek() != Qt.Friday: firstFriday = firstFriday.addDays(1) firstFridayFormat = QTextCharFormat() firstFridayFormat.setForeground(Qt.blue) self.calendar.setDateTextFormat(firstFriday, firstFridayFormat) # May 1st in Red takes precedence. if self.mayFirstCheckBox.isChecked(): mayFirst = QDate(self.calendar.yearShown(), 5, 1) mayFirstFormat = QTextCharFormat() mayFirstFormat.setForeground(Qt.red) self.calendar.setDateTextFormat(mayFirst, mayFirstFormat) def createPreviewGroupBox(self): self.previewGroupBox = QGroupBox("Preview") self.calendar = QCalendarWidget() self.calendar.setMinimumDate(QDate(1900, 1, 1)) self.calendar.setMaximumDate(QDate(3000, 1, 1)) self.calendar.setGridVisible(True) self.calendar.currentPageChanged.connect(self.reformatCalendarPage) self.previewLayout = QGridLayout() self.previewLayout.addWidget(self.calendar, 0, 0, Qt.AlignCenter) self.previewGroupBox.setLayout(self.previewLayout) def createGeneralOptionsGroupBox(self): self.generalOptionsGroupBox = QGroupBox("General Options") self.localeCombo = QComboBox() curLocaleIndex = -1 index = 0 this_language = self.locale().nativeLanguageName() this_country = self.locale().nativeCountryName() for locale in QLocale.matchingLocales(QLocale.AnyLanguage, QLocale.AnyScript, QLocale.AnyCountry): language = locale.nativeLanguageName() country = locale.nativeCountryName() if language == this_language and country == this_country: curLocaleIndex = index self.localeCombo.addItem('%s/%s' % (language, country), locale) index += 1 if curLocaleIndex != -1: self.localeCombo.setCurrentIndex(curLocaleIndex) self.localeLabel = QLabel("&Locale") self.localeLabel.setBuddy(self.localeCombo) self.firstDayCombo = QComboBox() self.firstDayCombo.addItem("Sunday", Qt.Sunday) self.firstDayCombo.addItem("Monday", Qt.Monday) self.firstDayCombo.addItem("Tuesday", Qt.Tuesday) self.firstDayCombo.addItem("Wednesday", Qt.Wednesday) self.firstDayCombo.addItem("Thursday", Qt.Thursday) self.firstDayCombo.addItem("Friday", Qt.Friday) self.firstDayCombo.addItem("Saturday", Qt.Saturday) self.firstDayLabel = QLabel("Wee&k starts on:") self.firstDayLabel.setBuddy(self.firstDayCombo) self.selectionModeCombo = QComboBox() self.selectionModeCombo.addItem("Single selection", QCalendarWidget.SingleSelection) self.selectionModeCombo.addItem("None", QCalendarWidget.NoSelection) self.selectionModeLabel = QLabel("&Selection mode:") self.selectionModeLabel.setBuddy(self.selectionModeCombo) self.gridCheckBox = QCheckBox("&Grid") self.gridCheckBox.setChecked(self.calendar.isGridVisible()) self.navigationCheckBox = QCheckBox("&Navigation bar") self.navigationCheckBox.setChecked(True) self.horizontalHeaderCombo = QComboBox() self.horizontalHeaderCombo.addItem("Single letter day names", QCalendarWidget.SingleLetterDayNames) self.horizontalHeaderCombo.addItem("Short day names", QCalendarWidget.ShortDayNames) self.horizontalHeaderCombo.addItem("Long day names", QCalendarWidget.LongDayNames) self.horizontalHeaderCombo.addItem("None", QCalendarWidget.NoHorizontalHeader) self.horizontalHeaderCombo.setCurrentIndex(1) self.horizontalHeaderLabel = QLabel("&Horizontal header:") self.horizontalHeaderLabel.setBuddy(self.horizontalHeaderCombo) self.verticalHeaderCombo = QComboBox() self.verticalHeaderCombo.addItem("ISO week numbers", QCalendarWidget.ISOWeekNumbers) self.verticalHeaderCombo.addItem("None", QCalendarWidget.NoVerticalHeader) self.verticalHeaderLabel = QLabel("&Vertical header:") self.verticalHeaderLabel.setBuddy(self.verticalHeaderCombo) self.localeCombo.currentIndexChanged.connect(self.localeChanged) self.firstDayCombo.currentIndexChanged.connect(self.firstDayChanged) self.selectionModeCombo.currentIndexChanged.connect( self.selectionModeChanged) self.gridCheckBox.toggled.connect(self.calendar.setGridVisible) self.navigationCheckBox.toggled.connect( self.calendar.setNavigationBarVisible) self.horizontalHeaderCombo.currentIndexChanged.connect( self.horizontalHeaderChanged) self.verticalHeaderCombo.currentIndexChanged.connect( self.verticalHeaderChanged) checkBoxLayout = QHBoxLayout() checkBoxLayout.addWidget(self.gridCheckBox) checkBoxLayout.addStretch() checkBoxLayout.addWidget(self.navigationCheckBox) outerLayout = QGridLayout() outerLayout.addWidget(self.localeLabel, 0, 0) outerLayout.addWidget(self.localeCombo, 0, 1) outerLayout.addWidget(self.firstDayLabel, 1, 0) outerLayout.addWidget(self.firstDayCombo, 1, 1) outerLayout.addWidget(self.selectionModeLabel, 2, 0) outerLayout.addWidget(self.selectionModeCombo, 2, 1) outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) outerLayout.addWidget(self.horizontalHeaderLabel, 4, 0) outerLayout.addWidget(self.horizontalHeaderCombo, 4, 1) outerLayout.addWidget(self.verticalHeaderLabel, 5, 0) outerLayout.addWidget(self.verticalHeaderCombo, 5, 1) self.generalOptionsGroupBox.setLayout(outerLayout) self.firstDayChanged(self.firstDayCombo.currentIndex()) self.selectionModeChanged(self.selectionModeCombo.currentIndex()) self.horizontalHeaderChanged(self.horizontalHeaderCombo.currentIndex()) self.verticalHeaderChanged(self.verticalHeaderCombo.currentIndex()) def createDatesGroupBox(self): self.datesGroupBox = QGroupBox(self.tr("Dates")) self.minimumDateEdit = QDateEdit() self.minimumDateEdit.setDisplayFormat('MMM d yyyy') self.minimumDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.minimumDateEdit.setDate(self.calendar.minimumDate()) self.minimumDateLabel = QLabel("&Minimum Date:") self.minimumDateLabel.setBuddy(self.minimumDateEdit) self.currentDateEdit = QDateEdit() self.currentDateEdit.setDisplayFormat('MMM d yyyy') self.currentDateEdit.setDate(self.calendar.selectedDate()) self.currentDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.currentDateLabel = QLabel("&Current Date:") self.currentDateLabel.setBuddy(self.currentDateEdit) self.maximumDateEdit = QDateEdit() self.maximumDateEdit.setDisplayFormat('MMM d yyyy') self.maximumDateEdit.setDateRange(self.calendar.minimumDate(), self.calendar.maximumDate()) self.maximumDateEdit.setDate(self.calendar.maximumDate()) self.maximumDateLabel = QLabel("Ma&ximum Date:") self.maximumDateLabel.setBuddy(self.maximumDateEdit) self.currentDateEdit.dateChanged.connect(self.calendar.setSelectedDate) self.calendar.selectionChanged.connect(self.selectedDateChanged) self.minimumDateEdit.dateChanged.connect(self.minimumDateChanged) self.maximumDateEdit.dateChanged.connect(self.maximumDateChanged) dateBoxLayout = QGridLayout() dateBoxLayout.addWidget(self.currentDateLabel, 1, 0) dateBoxLayout.addWidget(self.currentDateEdit, 1, 1) dateBoxLayout.addWidget(self.minimumDateLabel, 0, 0) dateBoxLayout.addWidget(self.minimumDateEdit, 0, 1) dateBoxLayout.addWidget(self.maximumDateLabel, 2, 0) dateBoxLayout.addWidget(self.maximumDateEdit, 2, 1) dateBoxLayout.setRowStretch(3, 1) self.datesGroupBox.setLayout(dateBoxLayout) def createTextFormatsGroupBox(self): self.textFormatsGroupBox = QGroupBox("Text Formats") self.weekdayColorCombo = self.createColorComboBox() self.weekdayColorCombo.setCurrentIndex( self.weekdayColorCombo.findText("Black")) self.weekdayColorLabel = QLabel("&Weekday color:") self.weekdayColorLabel.setBuddy(self.weekdayColorCombo) self.weekendColorCombo = self.createColorComboBox() self.weekendColorCombo.setCurrentIndex( self.weekendColorCombo.findText("Red")) self.weekendColorLabel = QLabel("Week&end color:") self.weekendColorLabel.setBuddy(self.weekendColorCombo) self.headerTextFormatCombo = QComboBox() self.headerTextFormatCombo.addItem("Bold") self.headerTextFormatCombo.addItem("Italic") self.headerTextFormatCombo.addItem("Plain") self.headerTextFormatLabel = QLabel("&Header text:") self.headerTextFormatLabel.setBuddy(self.headerTextFormatCombo) self.firstFridayCheckBox = QCheckBox("&First Friday in blue") self.mayFirstCheckBox = QCheckBox("May &1 in red") self.weekdayColorCombo.currentIndexChanged.connect( self.weekdayFormatChanged) self.weekendColorCombo.currentIndexChanged.connect( self.weekendFormatChanged) self.headerTextFormatCombo.currentIndexChanged.connect( self.reformatHeaders) self.firstFridayCheckBox.toggled.connect(self.reformatCalendarPage) self.mayFirstCheckBox.toggled.connect(self.reformatCalendarPage) checkBoxLayout = QHBoxLayout() checkBoxLayout.addWidget(self.firstFridayCheckBox) checkBoxLayout.addStretch() checkBoxLayout.addWidget(self.mayFirstCheckBox) outerLayout = QGridLayout() outerLayout.addWidget(self.weekdayColorLabel, 0, 0) outerLayout.addWidget(self.weekdayColorCombo, 0, 1) outerLayout.addWidget(self.weekendColorLabel, 1, 0) outerLayout.addWidget(self.weekendColorCombo, 1, 1) outerLayout.addWidget(self.headerTextFormatLabel, 2, 0) outerLayout.addWidget(self.headerTextFormatCombo, 2, 1) outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) self.textFormatsGroupBox.setLayout(outerLayout) self.weekdayFormatChanged() self.weekendFormatChanged() self.reformatHeaders() self.reformatCalendarPage() def createColorComboBox(self): comboBox = QComboBox() comboBox.addItem("Red", Qt.red) comboBox.addItem("Blue", Qt.blue) comboBox.addItem("Black", Qt.black) comboBox.addItem("Magenta", Qt.magenta) return comboBox
class HydroprintGUI(myqt.DialogWindow): ConsoleSignal = QSignal(str) def __init__(self, datamanager, parent=None): super(HydroprintGUI, self).__init__(parent, maximize=True) self.__updateUI = True # Child widgets: self.dmngr = datamanager self.dmngr.wldsetChanged.connect(self.wldset_changed) self.dmngr.wxdsetChanged.connect(self.wxdset_changed) self.page_setup_win = PageSetupWin(self) self.page_setup_win.newPageSetupSent.connect(self.layout_changed) self.color_palette_win = ColorsSetupWin(self) self.color_palette_win.newColorSetupSent.connect(self.update_colors) # Memory path variable: self.save_fig_dir = self.workdir # Generate UI: self.__initUI__() def __initUI__(self): # ---- Toolbar self.btn_save = btn_save = QToolButtonNormal(icons.get_icon('save')) btn_save.setToolTip('Save the well hydrograph') # btn_draw is usefull for debugging purposes btn_draw = QToolButtonNormal(icons.get_icon('refresh')) btn_draw.setToolTip('Force a refresh of the well hydrograph') btn_draw.hide() self.btn_load_layout = QToolButtonNormal( icons.get_icon('load_graph_config')) self.btn_load_layout.setToolTip( "<p>Load graph layout for the current water level " " datafile if it exists</p>") self.btn_load_layout.clicked.connect(self.load_layout_isClicked) self.btn_save_layout = QToolButtonNormal( icons.get_icon('save_graph_config')) self.btn_save_layout.setToolTip('Save current graph layout') self.btn_save_layout.clicked.connect(self.save_layout_isClicked) btn_bestfit_waterlvl = QToolButtonNormal(icons.get_icon('fit_y')) btn_bestfit_waterlvl.setToolTip('Best fit the water level scale') btn_bestfit_time = QToolButtonNormal(icons.get_icon('fit_x')) btn_bestfit_time.setToolTip('Best fit the time scale') self.btn_page_setup = QToolButtonNormal(icons.get_icon('page_setup')) self.btn_page_setup.setToolTip('Show the page setup window') self.btn_page_setup.clicked.connect(self.page_setup_win.show) btn_color_pick = QToolButtonNormal(icons.get_icon('color_picker')) btn_color_pick.setToolTip('<p>Show a window to setup the color palette' ' used to draw the hydrograph</p.') btn_color_pick.clicked.connect(self.color_palette_win.show) self.btn_language = LangToolButton() self.btn_language.setToolTip( "Set the language of the text shown in the graph.") self.btn_language.sig_lang_changed.connect(self.layout_changed) self.btn_language.setIconSize(icons.get_iconsize('normal')) # ---- Zoom Panel btn_zoom_out = QToolButtonSmall(icons.get_icon('zoom_out')) btn_zoom_out.setToolTip('Zoom out (ctrl + mouse-wheel-down)') btn_zoom_out.clicked.connect(self.zoom_out) btn_zoom_in = QToolButtonSmall(icons.get_icon('zoom_in')) btn_zoom_in.setToolTip('Zoom in (ctrl + mouse-wheel-up)') btn_zoom_in.clicked.connect(self.zoom_in) self.zoom_disp = QSpinBox() self.zoom_disp.setAlignment(Qt.AlignCenter) self.zoom_disp.setButtonSymbols(QAbstractSpinBox.NoButtons) self.zoom_disp.setReadOnly(True) self.zoom_disp.setSuffix(' %') self.zoom_disp.setRange(0, 9999) self.zoom_disp.setValue(100) zoom_pan = myqt.QFrameLayout() zoom_pan.setSpacing(3) zoom_pan.addWidget(btn_zoom_out, 0, 0) zoom_pan.addWidget(btn_zoom_in, 0, 1) zoom_pan.addWidget(self.zoom_disp, 0, 2) # LAYOUT : btn_list = [ btn_save, btn_draw, self.btn_load_layout, self.btn_save_layout, VSep(), btn_bestfit_waterlvl, btn_bestfit_time, VSep(), self.btn_page_setup, btn_color_pick, self.btn_language, VSep(), zoom_pan ] subgrid_toolbar = QGridLayout() toolbar_widget = QWidget() row = 0 for col, btn in enumerate(btn_list): subgrid_toolbar.addWidget(btn, row, col) subgrid_toolbar.setSpacing(5) subgrid_toolbar.setContentsMargins(0, 0, 0, 0) subgrid_toolbar.setColumnStretch(col + 1, 100) toolbar_widget.setLayout(subgrid_toolbar) # ---- LEFT PANEL # SubGrid Hydrograph Frame : self.hydrograph = hydrograph.Hydrograph() self.hydrograph_scrollarea = mplFigViewer.ImageViewer() self.hydrograph_scrollarea.zoomChanged.connect(self.zoom_disp.setValue) grid_hydrograph = QGridLayout() grid_hydrograph.addWidget(self.hydrograph_scrollarea, 0, 0) grid_hydrograph.setRowStretch(0, 500) grid_hydrograph.setColumnStretch(0, 500) grid_hydrograph.setContentsMargins(0, 0, 0, 0) # (L, T, R, B) # ASSEMBLING SubGrids : grid_layout = QGridLayout() self.grid_layout_widget = QFrame() row = 0 grid_layout.addWidget(toolbar_widget, row, 0) row += 1 grid_layout.addLayout(grid_hydrograph, row, 0) grid_layout.setContentsMargins(0, 0, 0, 0) # (L, T, R, B) grid_layout.setSpacing(5) grid_layout.setColumnStretch(0, 500) grid_layout.setRowStretch(1, 500) self.grid_layout_widget.setLayout(grid_layout) # ---- Right Panel self.tabscales = self.__init_scalesTabWidget__() self.right_panel = myqt.QFrameLayout() self.right_panel.addWidget(self.dmngr, 0, 0) self.right_panel.addWidget(self.tabscales, 1, 0) self.right_panel.setRowStretch(2, 100) self.right_panel.setSpacing(15) # ---- MAIN GRID mainGrid = QGridLayout() mainGrid.addWidget(self.grid_layout_widget, 0, 0) mainGrid.addWidget(VSep(), 0, 1) mainGrid.addWidget(self.right_panel, 0, 2) mainGrid.setContentsMargins(10, 10, 10, 10) # (L, T, R, B) mainGrid.setSpacing(15) mainGrid.setColumnStretch(0, 500) mainGrid.setColumnMinimumWidth(2, 250) self.setLayout(mainGrid) # ---- EVENTS # Toolbox Layout : btn_bestfit_waterlvl.clicked.connect(self.best_fit_waterlvl) btn_bestfit_time.clicked.connect(self.best_fit_time) btn_draw.clicked.connect(self.draw_hydrograph) btn_save.clicked.connect(self.select_save_path) # Hydrograph Layout : self.Ptot_scale.valueChanged.connect(self.layout_changed) self.qweather_bin.currentIndexChanged.connect(self.layout_changed) # ---- Init Image self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def __init_scalesTabWidget__(self): class QRowLayout(QGridLayout): def __init__(self, items, parent=None): super(QRowLayout, self).__init__(parent) for col, item in enumerate(items): self.addWidget(item, 0, col) self.setContentsMargins(0, 0, 0, 0) self.setColumnStretch(0, 100) # ---- Time axis properties # Generate the widgets : self.date_start_widget = QDateEdit() self.date_start_widget.setDisplayFormat('01 / MM / yyyy') self.date_start_widget.setAlignment(Qt.AlignCenter) self.date_start_widget.dateChanged.connect(self.layout_changed) self.date_end_widget = QDateEdit() self.date_end_widget.setDisplayFormat('01 / MM / yyyy') self.date_end_widget.setAlignment(Qt.AlignCenter) self.date_end_widget.dateChanged.connect(self.layout_changed) self.time_scale_label = QComboBox() self.time_scale_label.setEditable(False) self.time_scale_label.setInsertPolicy(QComboBox.NoInsert) self.time_scale_label.addItems(['Month', 'Year']) self.time_scale_label.setCurrentIndex(0) self.time_scale_label.currentIndexChanged.connect(self.layout_changed) self.dateDispFreq_spinBox = QSpinBox() self.dateDispFreq_spinBox.setSingleStep(1) self.dateDispFreq_spinBox.setMinimum(1) self.dateDispFreq_spinBox.setMaximum(100) self.dateDispFreq_spinBox.setValue(self.hydrograph.date_labels_pattern) self.dateDispFreq_spinBox.setAlignment(Qt.AlignCenter) self.dateDispFreq_spinBox.setKeyboardTracking(False) self.dateDispFreq_spinBox.valueChanged.connect(self.layout_changed) # Setting up the layout : widget_time_scale = QFrame() widget_time_scale.setFrameStyle(0) grid_time_scale = QGridLayout() GRID = [[QLabel('From :'), self.date_start_widget], [QLabel('To :'), self.date_end_widget], [QLabel('Scale :'), self.time_scale_label], [QLabel('Date Disp. Pattern:'), self.dateDispFreq_spinBox]] for i, ROW in enumerate(GRID): grid_time_scale.addLayout(QRowLayout(ROW), i, 1) grid_time_scale.setVerticalSpacing(5) grid_time_scale.setContentsMargins(10, 10, 10, 10) widget_time_scale.setLayout(grid_time_scale) # ----- Water level axis properties # Widget : self.waterlvl_scale = QDoubleSpinBox() self.waterlvl_scale.setSingleStep(0.05) self.waterlvl_scale.setMinimum(0.05) self.waterlvl_scale.setSuffix(' m') self.waterlvl_scale.setAlignment(Qt.AlignCenter) self.waterlvl_scale.setKeyboardTracking(False) self.waterlvl_scale.valueChanged.connect(self.layout_changed) self.waterlvl_scale.setFixedWidth(100) self.waterlvl_max = QDoubleSpinBox() self.waterlvl_max.setSingleStep(0.1) self.waterlvl_max.setSuffix(' m') self.waterlvl_max.setAlignment(Qt.AlignCenter) self.waterlvl_max.setMinimum(-1000) self.waterlvl_max.setMaximum(1000) self.waterlvl_max.setKeyboardTracking(False) self.waterlvl_max.valueChanged.connect(self.layout_changed) self.waterlvl_max.setFixedWidth(100) self.NZGridWL_spinBox = QSpinBox() self.NZGridWL_spinBox.setSingleStep(1) self.NZGridWL_spinBox.setMinimum(1) self.NZGridWL_spinBox.setMaximum(50) self.NZGridWL_spinBox.setValue(self.hydrograph.NZGrid) self.NZGridWL_spinBox.setAlignment(Qt.AlignCenter) self.NZGridWL_spinBox.setKeyboardTracking(False) self.NZGridWL_spinBox.valueChanged.connect(self.layout_changed) self.NZGridWL_spinBox.setFixedWidth(100) self.datum_widget = QComboBox() self.datum_widget.addItems(['Ground Surface', 'Sea Level']) self.datum_widget.currentIndexChanged.connect(self.layout_changed) # Layout : subgrid_WLScale = QGridLayout() GRID = [[QLabel('Minimum :'), self.waterlvl_max], [QLabel('Scale :'), self.waterlvl_scale], [QLabel('Grid Divisions :'), self.NZGridWL_spinBox], [QLabel('Datum :'), self.datum_widget]] for i, ROW in enumerate(GRID): subgrid_WLScale.addLayout(QRowLayout(ROW), i, 1) subgrid_WLScale.setVerticalSpacing(5) subgrid_WLScale.setContentsMargins(10, 10, 10, 10) # (L, T, R, B) WLScale_widget = QFrame() WLScale_widget.setFrameStyle(0) WLScale_widget.setLayout(subgrid_WLScale) # ---- Weather Axis # Widgets : self.Ptot_scale = QSpinBox() self.Ptot_scale.setSingleStep(5) self.Ptot_scale.setMinimum(5) self.Ptot_scale.setMaximum(500) self.Ptot_scale.setValue(20) self.Ptot_scale.setSuffix(' mm') self.Ptot_scale.setAlignment(Qt.AlignCenter) self.qweather_bin = QComboBox() self.qweather_bin.setEditable(False) self.qweather_bin.setInsertPolicy(QComboBox.NoInsert) self.qweather_bin.addItems(['day', 'week', 'month']) self.qweather_bin.setCurrentIndex(1) # Layout : layout = QGridLayout() GRID = [[QLabel('Precip. Scale :'), self.Ptot_scale], [QLabel('Resampling :'), self.qweather_bin]] for i, row in enumerate(GRID): layout.addLayout(QRowLayout(row), i, 1) layout.setVerticalSpacing(5) layout.setContentsMargins(10, 10, 10, 10) # (L,T,R,B) layout.setRowStretch(i + 1, 100) widget_weather_scale = QFrame() widget_weather_scale.setFrameStyle(0) widget_weather_scale.setLayout(layout) # ---- ASSEMBLING TABS tabscales = QTabWidget() tabscales.addTab(widget_time_scale, 'Time') tabscales.addTab(WLScale_widget, 'Water Level') tabscales.addTab(widget_weather_scale, 'Weather') return tabscales @property def workdir(self): return self.dmngr.workdir # ---- Utilities def zoom_in(self): self.hydrograph_scrollarea.zoomIn() def zoom_out(self): self.hydrograph_scrollarea.zoomOut() def update_colors(self): self.hydrograph.update_colors() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) # ---- Datasets Handlers @property def wldset(self): return self.dmngr.get_current_wldset() @property def wxdset(self): return self.dmngr.get_current_wxdset() def wldset_changed(self): """Handle when the water level dataset of the datamanager changes.""" if self.wldset is None: self.clear_hydrograph() return else: self.hydrograph.set_wldset(self.wldset) self.hydrograph.gluedf = self.wldset.get_glue_at(-1) # Load the manual measurements. fname = os.path.join(self.workdir, "Water Levels", 'waterlvl_manual_measurements') tmeas, wlmeas = load_waterlvl_measures(fname, self.wldset['Well']) self.wldset.set_wlmeas(tmeas, wlmeas) # Setup the layout of the hydrograph. layout = self.wldset.get_layout() if layout is not None: msg = ("Loading existing graph layout for well %s." % self.wldset['Well']) print(msg) self.ConsoleSignal.emit('<font color=black>%s</font>' % msg) self.load_graph_layout(layout) else: print('No graph layout exists for well %s.' % self.wldset['Well']) # Fit Water Level in Layout : self.__updateUI = False self.best_fit_waterlvl() self.best_fit_time() if self.dmngr.set_closest_wxdset() is None: self.draw_hydrograph() self.__updateUI = True def wxdset_changed(self): """Handle when the weather dataset of the datamanager changes.""" if self.wldset is None: self.clear_hydrograph() else: self.hydrograph.set_wxdset(self.wxdset) QCoreApplication.processEvents() self.draw_hydrograph() # ---- Draw Hydrograph Handlers def best_fit_waterlvl(self): wldset = self.dmngr.get_current_wldset() if wldset is not None: WLscale, WLmin = self.hydrograph.best_fit_waterlvl() self.waterlvl_scale.setValue(WLscale) self.waterlvl_max.setValue(WLmin) def best_fit_time(self): wldset = self.dmngr.get_current_wldset() if wldset is not None: date0, date1 = self.hydrograph.best_fit_time(wldset.xldates) self.date_start_widget.setDate(QDate(date0[0], date0[1], date0[2])) self.date_end_widget.setDate(QDate(date1[0], date1[1], date1[2])) @QSlot() def mrc_wl_changed(self): """ Force a redraw of the MRC water levels after the results have changed for the dataset. """ self.hydrograph.draw_mrc_wl() self.hydrograph.setup_legend() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) @QSlot(GLUEDataFrameBase) def glue_wl_changed(self, gluedf): """ Force a redraw of the GLUE water levels after the results have changed for the dataset. """ self.hydrograph.set_gluedf(gluedf) self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def layout_changed(self): """ When an element of the graph layout is changed in the UI. """ if self.__updateUI is False: return self.update_graph_layout_parameter() if self.hydrograph.isHydrographExists is False: return sender = self.sender() if sender == self.btn_language: self.hydrograph.draw_ylabels() self.hydrograph.setup_xticklabels() self.hydrograph.setup_legend() elif sender in [self.waterlvl_max, self.waterlvl_scale]: self.hydrograph.setup_waterlvl_scale() self.hydrograph.draw_ylabels() elif sender == self.NZGridWL_spinBox: self.hydrograph.setup_waterlvl_scale() self.hydrograph.update_precip_scale() self.hydrograph.draw_ylabels() elif sender == self.Ptot_scale: self.hydrograph.update_precip_scale() self.hydrograph.draw_ylabels() elif sender == self.datum_widget: yoffset = int(self.wldset['Elevation'] / self.hydrograph.WLscale) yoffset *= self.hydrograph.WLscale self.hydrograph.WLmin = (yoffset - self.hydrograph.WLmin) self.waterlvl_max.blockSignals(True) self.waterlvl_max.setValue(self.hydrograph.WLmin) self.waterlvl_max.blockSignals(False) # This is calculated so that trailing zeros in the altitude of the # well is not carried to the y axis labels, so that they remain a # int multiple of *WLscale*. self.hydrograph.setup_waterlvl_scale() self.hydrograph.draw_waterlvl() self.hydrograph.draw_ylabels() elif sender in [self.date_start_widget, self.date_end_widget]: self.hydrograph.set_time_scale() self.hydrograph.draw_weather() self.hydrograph.draw_figure_title() elif sender == self.dateDispFreq_spinBox: self.hydrograph.set_time_scale() self.hydrograph.setup_xticklabels() elif sender == self.page_setup_win: self.hydrograph.update_fig_size() # Implicitly call : set_margins() # draw_ylabels() # set_time_scale() # draw_figure_title self.hydrograph.draw_waterlvl() self.hydrograph.setup_legend() elif sender == self.qweather_bin: self.hydrograph.resample_bin() self.hydrograph.draw_weather() self.hydrograph.draw_ylabels() elif sender == self.time_scale_label: self.hydrograph.set_time_scale() self.hydrograph.draw_weather() else: print('No action for this widget yet.') # !!!! temporary fix until I can find a better solution !!!! # sender.blockSignals(True) if type(sender) in [QDoubleSpinBox, QSpinBox]: sender.setReadOnly(True) for i in range(10): QCoreApplication.processEvents() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) for i in range(10): QCoreApplication.processEvents() if type(sender) in [QDoubleSpinBox, QSpinBox]: sender.setReadOnly(False) # sender.blockSignals(False) def update_graph_layout_parameter(self): # language : self.hydrograph.language = self.btn_language.language # Scales : self.hydrograph.WLmin = self.waterlvl_max.value() self.hydrograph.WLscale = self.waterlvl_scale.value() self.hydrograph.RAINscale = self.Ptot_scale.value() self.hydrograph.NZGrid = self.NZGridWL_spinBox.value() # WL Datum : self.hydrograph.WLdatum = self.datum_widget.currentIndex() # Dates : self.hydrograph.datemode = self.time_scale_label.currentText() year = self.date_start_widget.date().year() month = self.date_start_widget.date().month() self.hydrograph.TIMEmin = xldate_from_date_tuple((year, month, 1), 0) year = self.date_end_widget.date().year() month = self.date_end_widget.date().month() self.hydrograph.TIMEmax = xldate_from_date_tuple((year, month, 1), 0) self.hydrograph.date_labels_pattern = self.dateDispFreq_spinBox.value() # Page Setup : self.hydrograph.fwidth = self.page_setup_win.pageSize[0] self.hydrograph.fheight = self.page_setup_win.pageSize[1] self.hydrograph.va_ratio = self.page_setup_win.va_ratio self.hydrograph.trend_line = self.page_setup_win.isTrendLine self.hydrograph.isLegend = self.page_setup_win.isLegend self.hydrograph.isGraphTitle = self.page_setup_win.isGraphTitle self.hydrograph.set_meteo_on(self.page_setup_win.is_meteo_on) self.hydrograph.set_glue_wl_on(self.page_setup_win.is_glue_wl_on) self.hydrograph.set_mrc_wl_on(self.page_setup_win.is_mrc_wl_on) self.hydrograph.set_figframe_lw(self.page_setup_win.figframe_lw) # Weather bins : self.hydrograph.bwidth_indx = self.qweather_bin.currentIndex() def clear_hydrograph(self): """Clear the hydrograph figure to show only a blank canvas.""" self.hydrograph.clf() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) def draw_hydrograph(self): if self.dmngr.wldataset_count() == 0: msg = 'Please import a valid water level data file first.' self.ConsoleSignal.emit('<font color=red>%s</font>' % msg) self.emit_warning(msg) return self.update_graph_layout_parameter() # Generate and Display Graph : for i in range(5): QCoreApplication.processEvents() QApplication.setOverrideCursor(Qt.WaitCursor) self.hydrograph.set_wldset(self.dmngr.get_current_wldset()) self.hydrograph.set_wxdset(self.dmngr.get_current_wxdset()) self.hydrograph.generate_hydrograph() self.hydrograph_scrollarea.load_mpl_figure(self.hydrograph) QApplication.restoreOverrideCursor() def select_save_path(self): """ Open a dialog where the user can select a file name to save the hydrograph. """ if self.wldset is None: return ffmat = "*.pdf;;*.svg;;*.png" fname = find_unique_filename( osp.join(self.save_fig_dir, 'hydrograph_%s.pdf' % self.wldset['Well'])) fname, ftype = QFileDialog.getSaveFileName(self, "Save Figure", fname, ffmat) if fname: ftype = ftype.replace('*', '') fname = fname if fname.endswith(ftype) else fname + ftype self.save_fig_dir = os.path.dirname(fname) try: self.save_figure(fname) except PermissionError: msg = "The file is in use by another application or user." QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) self.select_save_path() def save_figure(self, fname): """Save the hydrograph figure in a file.""" self.hydrograph.generate_hydrograph() self.hydrograph.savefig(fname) # ---- Graph Layout Handlers def load_layout_isClicked(self): """Handle when the button to load the graph layout is clicked.""" if self.wldset is None: self.emit_warning( "Please import a valid water level data file first.") return layout = self.wldset.get_layout() if layout is None: self.emit_warning("No graph layout exists for well %s." % self.wldset['Well']) else: self.load_graph_layout(layout) def load_graph_layout(self, layout): """Load the graph layout into the GUI.""" self.__updateUI = False # Scales : date = layout['TIMEmin'] date = xldate_as_tuple(date, 0) self.date_start_widget.setDate(QDate(date[0], date[1], date[2])) date = layout['TIMEmax'] date = xldate_as_tuple(date, 0) self.date_end_widget.setDate(QDate(date[0], date[1], date[2])) self.dateDispFreq_spinBox.setValue(layout['date_labels_pattern']) self.waterlvl_scale.setValue(layout['WLscale']) self.waterlvl_max.setValue(layout['WLmin']) self.NZGridWL_spinBox.setValue(layout['NZGrid']) self.Ptot_scale.setValue(layout['RAINscale']) x = ['mbgs', 'masl'].index(layout['WLdatum']) self.datum_widget.setCurrentIndex(x) self.qweather_bin.setCurrentIndex(layout['bwidth_indx']) self.time_scale_label.setCurrentIndex( self.time_scale_label.findText(layout['datemode'])) # ---- Language and colors self.btn_language.set_language(layout['language']) self.color_palette_win.load_colors() # ---- Page Setup self.page_setup_win.pageSize = (layout['fwidth'], layout['fheight']) self.page_setup_win.va_ratio = layout['va_ratio'] self.page_setup_win.isLegend = layout['legend_on'] self.page_setup_win.isGraphTitle = layout['title_on'] self.page_setup_win.isTrendLine = layout['trend_line'] self.page_setup_win.is_meteo_on = layout['meteo_on'] self.page_setup_win.is_glue_wl_on = layout['glue_wl_on'] self.page_setup_win.is_mrc_wl_on = layout['mrc_wl_on'] self.page_setup_win.figframe_lw = layout['figframe_lw'] self.page_setup_win.legend_on.set_value(layout['legend_on']) self.page_setup_win.title_on.set_value(layout['title_on']) self.page_setup_win.wltrend_on.set_value(layout['trend_line']) self.page_setup_win.meteo_on.set_value(layout['meteo_on']) self.page_setup_win.glue_wl_on.set_value(layout['glue_wl_on']) self.page_setup_win.mrc_wl_on.set_value(layout['mrc_wl_on']) self.page_setup_win.fframe_lw_widg.setValue(layout['figframe_lw']) self.page_setup_win.fwidth.setValue(layout['fwidth']) self.page_setup_win.fheight.setValue(layout['fheight']) self.page_setup_win.va_ratio_spinBox.setValue(layout['va_ratio']) # Check if Weather Dataset : if layout['wxdset'] in self.dmngr.wxdsets: self.dmngr.set_current_wxdset(layout['wxdset']) else: if self.dmngr.set_closest_wxdset() is None: self.draw_hydrograph() self.__updateUI = True def save_layout_isClicked(self): wldset = self.wldset if wldset is None: self.emit_warning( "Please import a valid water level data file first.") return layout = wldset.get_layout() if layout is not None: msg = ('A graph layout already exists for well %s.Do you want to' ' you want to replace it?') % wldset['Well'] reply = QMessageBox.question(self, 'Save Graph Layout', msg, QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.save_graph_layout() elif reply == QMessageBox.No: msg = "Graph layout not saved for well %s." % wldset['Well'] self.ConsoleSignal.emit('<font color=black>%s' % msg) else: self.save_graph_layout() def save_graph_layout(self): """Save the graph layout in the project hdf5 file.""" print("Saving the graph layout for well %s..." % self.wldset['Well'], end=" ") layout = { 'WLmin': self.waterlvl_max.value(), 'WLscale': self.waterlvl_scale.value(), 'RAINscale': self.Ptot_scale.value(), 'fwidth': self.page_setup_win.pageSize[0], 'fheight': self.page_setup_win.pageSize[1], 'va_ratio': self.page_setup_win.va_ratio, 'NZGrid': self.NZGridWL_spinBox.value(), 'bwidth_indx': self.qweather_bin.currentIndex(), 'date_labels_pattern': self.dateDispFreq_spinBox.value(), 'datemode': self.time_scale_label.currentText() } layout['wxdset'] = None if self.wxdset is None else self.wxdset.name year = self.date_start_widget.date().year() month = self.date_start_widget.date().month() layout['TIMEmin'] = xldate_from_date_tuple((year, month, 1), 0) year = self.date_end_widget.date().year() month = self.date_end_widget.date().month() layout['TIMEmax'] = xldate_from_date_tuple((year, month, 1), 0) if self.datum_widget.currentIndex() == 0: layout['WLdatum'] = 'mbgs' else: layout['WLdatum'] = 'masl' # ---- Page Setup layout['title_on'] = bool(self.page_setup_win.isGraphTitle) layout['legend_on'] = bool(self.page_setup_win.isLegend) layout['language'] = self.btn_language.language layout['trend_line'] = bool(self.page_setup_win.isTrendLine) layout['meteo_on'] = bool(self.page_setup_win.is_meteo_on) layout['glue_wl_on'] = bool(self.page_setup_win.is_glue_wl_on) layout['mrc_wl_on'] = bool(self.page_setup_win.is_mrc_wl_on) layout['figframe_lw'] = self.page_setup_win.figframe_lw # Save the colors : cdb = ColorsReader() cdb.load_colors_db() layout['colors'] = cdb.RGB # Save the layout : self.wldset.save_layout(layout) msg = 'Layout saved successfully for well %s.' % self.wldset['Well'] self.ConsoleSignal.emit('<font color=black>%s</font>' % msg) print("done")
class ResultsQueryForm(QFormLayout): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # First line: Start Date self.label1 = QLabel(self.tr("Start Date")) self.start_date_edit = QDateEdit(datetime.now()) self.start_date_edit.setDisplayFormat("dd/MM/yyyy") self.start_date_edit.setCalendarPopup(True) # Just making sure that the start date is always before the end date self.start_date_edit.dateTimeChanged.connect(self.checkDates_startdate) self.setWidget(0, self.LabelRole, self.label1) self.setWidget(0, self.FieldRole, self.start_date_edit) # Second line: End Date self.label2 = QLabel(self.tr("End Date")) self.end_date_edit = QDateEdit(datetime.now()) self.end_date_edit.setDisplayFormat("dd/MM/yyyy") self.end_date_edit.setCalendarPopup(True) # Just making sure that the end date is always after the start date self.end_date_edit.dateTimeChanged.connect(self.checkDates_enddate) self.setWidget(1, self.LabelRole, self.label2) self.setWidget(1, self.FieldRole, self.end_date_edit) # Third line: Account selection self.label3 = QLabel(self.tr("Account")) self.account_select = QComboBox() all_accounts = balances.get_all_account_names() self.account_select.addItem("All") self.account_select.addItems(all_accounts) self.setWidget(2, self.LabelRole, self.label3) self.setWidget(2, self.FieldRole, self.account_select) # Fourth Line: Strategy Selection self.label4 = QLabel(self.tr("Strategy")) self.strategy_select = QComboBox() all_strategies = strategies.get_all_strategy_names() self.strategy_select.addItem("All") self.strategy_select.addItems(all_strategies) self.setWidget(3, self.LabelRole, self.label4) self.setWidget(3, self.FieldRole, self.strategy_select) def checkDates_startdate(self): """ Making sure that the start date is not bigger than the end date """ if self.end_date_edit.dateTime() < self.start_date_edit.dateTime(): # set end date same as start date self.end_date_edit.setDate(self.start_date_edit.date()) def checkDates_enddate(self): """ Making sure that the start date is not bigger than the end date """ if self.start_date_edit.dateTime() > self.end_date_edit.dateTime(): # viceversa self.start_date_edit.setDate(self.end_date_edit.date())
class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(664, 500) self.gridLayoutWidget = QtWidgets.QWidget(Form) self.gridLayoutWidget.setGeometry(QtCore.QRect(9, 9, 641, 79)) self.gridLayoutWidget.setObjectName("gridLayoutWidget") self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") # 项目 self.label = QtWidgets.QLabel(self.gridLayoutWidget) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 1, 1, 1, 1) self.comboBox = QtWidgets.QComboBox(self.gridLayoutWidget) self.comboBox.setObjectName("comboBox") self.comboBox.addItem("") self.comboBox.addItem("") self.gridLayout.addWidget(self.comboBox, 1, 2, 1, 1) # 模块 self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 3, 1, 1) self.comboBox_2 = QtWidgets.QComboBox(self.gridLayoutWidget) self.comboBox_2.setObjectName("comboBox_2") self.comboBox_2.addItem("") self.comboBox_2.addItem("") self.gridLayout.addWidget(self.comboBox_2, 1, 4, 1, 1) # 创建时间 self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_3.setObjectName("label_3") self.gridLayout.addWidget(self.label_3, 2, 1, 1, 1) self.dateEdit = QDateEdit(self) self.dateEdit.setCalendarPopup(True) self.dateEdit.setDisplayFormat("yyyy-MM-dd") # self.dateEdit.dateChanged.connect(self.showdate) self.gridLayout.addWidget(self.dateEdit, 2, 2, 1, 1) # 结束时间 self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget) self.label_4.setObjectName("label_4") self.gridLayout.addWidget(self.label_4, 2, 3, 1, 1) self.dateEdit_2 = QDateEdit(self) self.dateEdit_2.setCalendarPopup(True) self.dateEdit_2.setDisplayFormat("yyyy-MM-dd") # self.dateEdit_2.dateChanged.connect(self.showdate) self.gridLayout.addWidget(self.dateEdit_2, 2, 4, 1, 1) #水平布局 self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") # 查询 self.pushButton = QtWidgets.QPushButton(self.gridLayoutWidget) self.pushButton.setObjectName("pushButton") self.horizontalLayout.addWidget(self.pushButton) self.pushButton.clicked.connect(self.showdate) # 关闭 self.pushButton_2 = QtWidgets.QPushButton(self.gridLayoutWidget) self.pushButton_2.setObjectName("pushButton_2") self.horizontalLayout.addWidget(self.pushButton_2) self.gridLayout.addLayout(self.horizontalLayout, 3, 4, 1, 1) # 输出 self.groupBox = QtWidgets.QGroupBox(Form) self.groupBox.setGeometry(QtCore.QRect(10, 110, 641, 360)) self.groupBox.setObjectName("groupBox") self.retranslateUi(Form) self.pushButton_2.clicked.connect(Form.close) QtCore.QMetaObject.connectSlotsByName(Form) def showdate(self): print(self.comboBox.currentText()) print(self.comboBox_2.currentText()) print(self.dateEdit.text()) print(self.dateEdit_2.text()) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "项目")) self.comboBox.setItemText(0, _translate("Form", "项目A")) self.comboBox.setItemText(1, _translate("Form", "项目B")) self.label_2.setText(_translate("Form", "模块")) self.comboBox_2.setItemText(0, _translate("Form", "模块A")) self.comboBox_2.setItemText(1, _translate("Form", "模块B")) self.label_3.setText(_translate("Form", "创建时间")) self.label_4.setText(_translate("Form", "结束时间")) self.pushButton.setText(_translate("Form", "查询")) self.pushButton_2.setText(_translate("Form", "关闭")) self.groupBox.setTitle(_translate("Form", "输出"))