class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.datetime_1 = QDateTimeEdit(self) # 1 self.datetime_1.dateChanged.connect(lambda: print('Date Changed!')) self.datetime_2 = QDateTimeEdit(QDateTime.currentDateTime(), self) # 2 self.datetime_2.setDisplayFormat('yyyy-MM-dd HH:mm:ss') self.datetime_2.timeChanged.connect(lambda: print('Time Changed!')) print(self.datetime_2.date()) print(self.datetime_2.time()) print(self.datetime_2.dateTime()) self.datetime_3 = QDateTimeEdit(QDateTime.currentDateTime(), self) # 3 self.datetime_3.dateTimeChanged.connect(lambda: print('DateTimeChanged!')) self.datetime_3.setCalendarPopup(True) self.datetime_4 = QDateTimeEdit(QDate.currentDate(), self) # 4 self.datetime_5 = QDateTimeEdit(QTime.currentTime(), self) self.date = QDateEdit(QDate.currentDate(), self) # 5 self.date.setDisplayFormat('yyyy/MM/dd') print(self.date.date()) self.time = QTimeEdit(QTime.currentTime(), self) # 6 self.time.setDisplayFormat('HH:mm:ss') print(self.time.time()) self.v_layout = QVBoxLayout() self.v_layout.addWidget(self.datetime_1) self.v_layout.addWidget(self.datetime_2) self.v_layout.addWidget(self.datetime_3) self.v_layout.addWidget(self.datetime_4) self.v_layout.addWidget(self.datetime_5) self.v_layout.addWidget(self.date) self.v_layout.addWidget(self.time) self.setLayout(self.v_layout)
class DateEditField(DataEditField): """ Class for editing date fields. """ def __init__(self, parent, title, help_text): self.field = QDateTimeEdit(datetime.now().date()) self.field.setCalendarPopup(True) self.field.setDisplayFormat("dd-MM-yyyy") DataEditField.__init__(self, parent, title, help_text, self.field) def clearField(self): """ Set field to current date """ self.field.setDate(datetime.now().date()) def getValue(self): """ Get value of DateEditField """ return qDate2Date(self.field.date())
class BRFManager(myqt.QFrameLayout): def __init__(self, wldset=None, parent=None): super(BRFManager, self).__init__(parent) self.viewer = BRFViewer(wldset, parent) self.kgs_brf_installer = None self.__initGUI__() def __initGUI__(self): self.setContentsMargins(10, 10, 10, 10) self._bplag = {} self._bplag['label'] = QLabel('BP Lags Nbr:') self._bplag['widget'] = myqt.QDoubleSpinBox(100, 0) self._bplag['widget'].setRange(1, 9999) self._bplag['widget'].setValue(300) self._bplag['widget'].setKeyboardTracking(True) self._etlag = {} self._etlag['label'] = QLabel('ET Lags Nbr:') self._etlag['widget'] = myqt.QDoubleSpinBox(300, 0) self._etlag['widget'].setRange(-1, 9999) self._etlag['widget'].setValue(300) self._etlag['widget'].setKeyboardTracking(True) # ---- BRF Data Range ---- self._datastart = QDateTimeEdit() self._datastart.setCalendarPopup(True) self._datastart.setDisplayFormat('dd/MM/yyyy') self._dataend = QDateTimeEdit() self._dataend.setCalendarPopup(True) self._dataend.setDisplayFormat('dd/MM/yyyy') self.btn_seldata = QToolButtonSmall(icons.get_icon('select_range')) self.btn_seldata.clicked.connect(self.get_datarange) # ---- Detrend and Correct Options ---- self._detrend = QCheckBox('Detrend') self._detrend.setCheckState(Qt.Checked) self._correct = QCheckBox('Correct WL') self._correct.setEnabled(False) # ---- Toolbar btn_comp = QPushButton('Compute BRF') btn_comp.clicked.connect(self.calc_brf) btn_comp.setFocusPolicy(Qt.NoFocus) self.btn_show = btn_show = QToolButtonSmall(icons.get_icon('search')) btn_show.clicked.connect(self.viewer.show) # Layout tbar = myqt.QFrameLayout() tbar.addWidget(btn_comp, 0, 0) tbar.addWidget(btn_show, 0, 1) tbar.setColumnStretch(0, 100) # ---- Main Layout row = 0 self.addWidget(self._bplag['label'], row, 0) self.addWidget(self._bplag['widget'], row, 1) row += 1 self.addWidget(self._etlag['label'], row, 0) self.addWidget(self._etlag['widget'], row, 1) row += 1 self.setRowMinimumHeight(row, 15) row += 1 self.addWidget(QLabel('BRF Start :'), row, 0) self.addWidget(self._datastart, row, 1) self.addWidget(self.btn_seldata, row, 2) row += 1 self.addWidget(QLabel('BRF End :'), row, 0) self.addWidget(self._dataend, row, 1) row += 1 self.setRowMinimumHeight(row, 15) row += 1 self.addWidget(self._detrend, row, 0, 1, 2) row += 1 self.addWidget(self._correct, row, 0, 1, 2) row += 1 self.setRowMinimumHeight(row, 5) self.setRowStretch(row, 100) row += 1 self.addWidget(tbar, row, 0, 1, 3) self.setColumnStretch(self.columnCount(), 100) # ---- Install Panel if not KGSBRFInstaller().kgsbrf_is_installed(): self.__install_kgs_brf_installer() # ---- Properties @property def lagBP(self): return self._bplag['widget'].value() @property def lagET(self): return self._etlag['widget'].value() @property def detrend(self): if self._detrend.checkState(): return 'Yes' else: return 'No' @property def correct_WL(self): return 'No' @property def brfperiod(self): y, m, d = self._datastart.date().getDate() dstart = xldate_from_date_tuple((y, m, d), 0) y, m, d = self._dataend.date().getDate() dend = xldate_from_date_tuple((y, m, d), 0) return (dstart, dend) # ---- KGS BRF installer def __install_kgs_brf_installer(self): """ Installs a KGSBRFInstaller that overlays the whole brf tool layout until the KGS_BRF program is installed correctly. """ self.kgs_brf_installer = KGSBRFInstaller() self.kgs_brf_installer.sig_kgs_brf_installed.connect( self.__uninstall_kgs_brf_installer) self.addWidget(self.kgs_brf_installer, 0, 0, self.rowCount(), self.columnCount()) def __uninstall_kgs_brf_installer(self): """ Uninstall the KGSBRFInstaller after the KGS_BRF program has been installed properly. """ self.kgs_brf_installer.sig_kgs_brf_installed.disconnect() self.kgs_brf_installer = None def set_wldset(self, wldset): """Set the namespace for the wldset in the widget.""" self.wldset = wldset self.viewer.set_wldset(wldset) self.setEnabled(wldset is not None) if wldset is not None: date_start, date_end = self.set_datarange( self.wldset['Time'][[0, -1]]) self._datastart.setMinimumDate(date_start) self._dataend.setMaximumDate(date_end) def get_datarange(self): child = self while True: try: child.parent().raise_() except Exception: break else: child = child.parent() def set_datarange(self, times): date_start = xldate_as_tuple(times[0], 0) date_start = QDate(date_start[0], date_start[1], date_start[2]) self._datastart.setDate(date_start) date_end = xldate_as_tuple(times[1], 0) date_end = QDate(date_end[0], date_end[1], date_end[2]) self._dataend.setDate(date_end) return date_start, date_end def calc_brf(self): """Prepare the data, calcul the brf, and save and plot the results.""" # Prepare the datasets. well = self.wldset['Well'] t1 = min(self.brfperiod) i1 = np.where(self.wldset['Time'] >= t1)[0][0] t2 = max(self.brfperiod) i2 = np.where(self.wldset['Time'] <= t2)[0][-1] time = np.copy(self.wldset['Time'][i1:i2 + 1]) wl = np.copy(self.wldset['WL'][i1:i2 + 1]) bp = np.copy(self.wldset['BP'][i1:i2 + 1]) if len(bp) == 0: msg = ("The barometric response function cannot be computed" " because the currently selected water level dataset does" " not contain any barometric data for the selected period.") QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return et = np.copy(self.wldset['ET'][i1:i2 + 1]) if len(et) == 0: et = np.zeros(len(wl)) lagBP = self.lagBP lagET = self.lagET detrend = self.detrend correct = self.correct_WL # Fill the gaps in the dataset. dt = np.min(np.diff(time)) tc = np.arange(t1, t2 + dt / 2, dt) if len(tc) != len(time): print('Filling gaps in data with linear interpolation.') indx = np.where(~np.isnan(wl))[0] wl = np.interp(tc, time[indx], wl[indx]) indx = np.where(~np.isnan(bp))[0] bp = np.interp(tc, time[indx], bp[indx]) indx = np.where(~np.isnan(et))[0] et = np.interp(tc, time[indx], et[indx]) time = tc QApplication.setOverrideCursor(Qt.WaitCursor) print('calculating BRF') bm.produce_BRFInputtxt(well, time, wl, bp, et) msg = 'Not enough data. Try enlarging the selected period' msg += ' or reduce the number of BP and ET lags.' if lagBP >= len(time) or lagET >= len(time): QApplication.restoreOverrideCursor() QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return bm.produce_par_file(lagBP, lagET, detrend, correct) bm.run_kgsbrf() try: lag, A, err = bm.read_BRFOutput() date_start = self._datastart.date().getDate() date_end = self._dataend.date().getDate() self.wldset.save_brf(lag, A, err, date_start, date_end) self.viewer.new_brf_added() self.viewer.show() QApplication.restoreOverrideCursor() except Exception: QApplication.restoreOverrideCursor() QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return
class App(QMainWindow): switch_window = QtCore.pyqtSignal() def __init__(self): super().__init__() self.title = "To-Do List" # set title.. self.left = 70 # x-pos when you open application.. self.top = 60 # y-pos when you open application.. self.width = 500 # width of the application.. self.height = 500 # height of the application.. self.fName = 'To-Do List File.txt' # set file name when you save your file.. self.uncompletedTaskFile, self.completedTaskFile = 'UncompletedTask.txt', 'CompletedTask.txt' self.initUI() # initialize the UI of the application.. def makeLabel(self, x, y, text): # make label method... self.taskLabel = QLabel(self) self.taskLabel.setText(text) self.taskLabel.move(x, y) def createTaskFile(self): if not os.path.exists(self.uncompletedTaskFile) and not os.path.exists( self.completedTaskFile): with open(self.uncompletedTaskFile, 'w') as f: f.close() with open(self.completedTaskFile, 'w') as g: g.close() def setMenuBarAction(self): # add Action to the menu bar... self.saveAction = QAction('Save', self) # save Action.. self.saveAction.setStatusTip('Sae The To-Do') self.saveAction.setShortcut("Ctrl+S") self.saveAction.triggered.connect(self.saveFile) self.saveAllAction = QAction('Save All', self) # save All Action.. self.saveAllAction.setStatusTip('Save All To-Do') self.saveAllAction.triggered.connect(self.saveAllFile) self.exitAction = QAction('Exit', self) # Exit Action.. self.exitAction.setStatusTip('Exit') self.exitAction.triggered.connect(self.exitApp) self.aboutToDo = QAction('About To-Do List', self) # About Action.. self.aboutToDo.triggered.connect(self.aboutInfo) def appMenuBar(self): menuBar = self.menuBar() # Create Menu Bar.. self.setMenuBarAction() # Set Action for Menu Bar.. self.homeMenu = menuBar.addMenu( 'File') # Set File Menu to The MenuBar.. self.helpMenu = menuBar.addMenu( 'Help') # Set Help Menu to The MenuBar.. self.homeMenu.addAction( self.saveAction) # Save Action Added to File Menu.. self.homeMenu.addAction( self.saveAllAction) # Save All Action Added to File Menu.. self.homeMenu.addAction( self.exitAction) # Exit Action Added to File Menu.. self.helpMenu.addAction( self.aboutToDo) # Abouut Action Added to Help Menu.. def initUI(self): self.setWindowTitle(self.title) # Set title for the Application.. self.setWindowIcon(QIcon("./logo.png")) # set Icon for the Application self.setGeometry(self.left, self.top, self.width, self.height) # set app size.. self.setMaximumSize(QtCore.QSize( self.width, self.height)) # disabling Application Maximize button.. self.appMenuBar() # Set application MenuBar.. self.createTaskFile() # creating Task File for application.. # Task Text Input.. self.taskText = QLineEdit(self) self.taskText.move(10, 45) self.taskText.resize(self.width // 2 - 20, 50) self.taskText.setPlaceholderText('Enter Task Here..') # setting up uncompleted task text Area... self.textArea = QTextEdit(self) self.textArea.setReadOnly(True) # readonly text area.. self.textArea.move(self.width // 2, 45) self.textArea.resize(self.width // 2 - 2, self.height - 50) self.textArea.setLineWrapMode(QTextEdit.NoWrap) self.textArea.setTextColor(QColor(180, 0, 0)) # give font color to red.. self.textArea.setFontPointSize(10) # font size = 10.. # make Labels..... self.makeLabel(10, 21, 'Add Task Here') self.makeLabel(self.width // 2, 20, 'Uncompleted Task') self.makeLabel(5, self.height // 2 - 15, 'Completed Task List') self.makeLabel(10, 95, 'Set Reminder') # setting up completed task text Area.. self.completedtextArea = QTextEdit(self) self.completedtextArea.setReadOnly(True) # readonly text area.. self.completedtextArea.move(5, self.height // 2 + 10) self.completedtextArea.resize(self.width // 2 - 13, self.height // 2 - 15) self.completedtextArea.setLineWrapMode(QTextEdit.NoWrap) self.completedtextArea.setTextColor(QColor( 0, 180, 0)) # give font color to green.. self.completedtextArea.setFontPointSize(10) # font size = 10.. self.dateTimeBox = QDateTimeEdit(self) self.dateTimeBox.setGeometry(10, 125, 140, 25) self.loadTask() # loading preveiously stord To-Do Task.. self.Buttons() # make all the buttons for the Application.. self.show() # display the application..a def Buttons(self): # Add To-Do Button self.addButton = QPushButton("Add To-Do", self) self.addButton.move(15, 164) # Add Clear All Button self.clearAllButton = QPushButton("Clear All", self) self.clearAllButton.move(130, 164) # Adding Mark All Completed Button.. self.completedButton = QPushButton("Mark All Completed", self) self.completedButton.move(58, 203) self.completedButton.resize(140, 30) # Button events.. self.addButton.clicked.connect(self.onClick) self.clearAllButton.clicked.connect(self.clearAll) self.completedButton.clicked.connect(self.completeTask) def loadTask(self): if os.path.exists(self.uncompletedTaskFile): with open(self.uncompletedTaskFile, 'r') as f: text = f.read() if text != '': self.textArea.append(text) if os.path.exists(self.completedTaskFile): with open(self.completedTaskFile, 'r') as g: texts = g.read().split('\n') for text in texts: if text != '': self.completedtextArea.append(text) @pyqtSlot() def saveFile(self): file = self.textArea.toPlainText() try: fHandle = open(self.fName, 'a') fHandle.write(file) except: with open(self.fName, 'w') as f: f.write(file) fHandle.close() @pyqtSlot() def saveAllFile(self): uncompletedToDOText = self.textArea.toPlainText() completedToDOText = self.completedtextArea.toPlainText() if uncompletedToDOText == '': # if there is no task in uncompleted task list then skip it.. with open(self.fName, 'w') as f: f.write('Completed To-Do Task:\n\n') f.write(completedToDOText) elif completedToDOText == '': # if there is no task in completed task list then skip it.. with open(self.fName, 'w') as f: f.write('Uncompleted To-Do Task:\n\n') f.write(uncompletedToDOText + '\n\n') else: with open(self.fName, 'w') as f: # both.. f.write('Uncompleted To-Do Task:\n\n') f.write(uncompletedToDOText + '\n\n') f.write('Completed To-Do Task:\n\n') f.write(completedToDOText) @pyqtSlot() def aboutInfo(self): msg = QMessageBox() msg.setWindowTitle('To-Do List') msg.setGeometry(280, 190, 500, 420) msg.setWindowIcon(QIcon('logo.png')) msg.setText( '''Add Your Daily To-Do Task \n Bulid With Python & PyQt5. ''') msg.exec_() @pyqtSlot() def exitApp(self): sys.exit() # exit from the App.. @pyqtSlot() def onClick(self): textvalue = self.taskText.text() date = self.dateTimeBox.date() time = self.dateTimeBox.time() text = f'{textvalue} Date: {date.toPyDate()} Time: {time.toPyTime()}\n' # convert to string.. if textvalue == '': # If textvalue in taskText is blank then return don't update textArea.. return else: if os.path.exists(self.uncompletedTaskFile): with open(self.uncompletedTaskFile, 'a') as f: f.write(text) else: with open(self.uncompletedTaskFile, 'w') as f: f.write(text) self.textArea.append(text) # else update textArea.. self.taskText.setText('') #clear taskText.. @pyqtSlot() def clearAll(self): self.textArea.setText('') # clear uncompleted task list textArea.. self.completedtextArea.setText( '') # clear completed task list textArea.. with open(self.uncompletedTaskFile, 'w') as f, open(self.completedTaskFile, 'w') as g: f.close() g.close() @pyqtSlot() def completeTask(self): textValue = self.textArea.toPlainText( ) # get uncompleted task list text.. with open(self.uncompletedTaskFile, 'r+') as g: dataFile = g.read().split('\n') texts = textValue.split('\n') for text in texts: for data in dataFile: if data.startswith(text): g.truncate(0) if textValue == '': return else: if os.path.exists(self.completedTaskFile): with open(self.completedTaskFile, 'a') as f: texts = textValue.split('\n') for text in texts: if text != '': f.write(textValue) else: with open(self.completedTaskFile, 'w') as f: texts = textValue.split('\n') for text in texts: if text != '': f.write(textValue) texts = textValue.split('\n') for text in texts: if text != '': self.completedtextArea.append( text) # append to completed task list section.. self.textArea.setText('')
class DailyLockManager(QWidget): """ This class contains the functionality for locking and unlocking a certain day for the user and protecting the database for simultaneous changes by concurrent users. """ def __init__(self, parent, database_access): super(QWidget, self).__init__(parent) self.setFixedWidth(650) self.layout = QHBoxLayout(self) self.layout.setAlignment(Qt.AlignRight) self.__database_access = database_access self.events_date = (datetime.datetime.now() - datetime.timedelta(days=1)).date() self.lock_status = self.__database_access.isDateLockedToUser(self.events_date) self.__lock_label = QLabel("<b>Automatic Event Date:</b>", self) self.__lock_button = QPushButton('', self) if self.lock_status: self.__lock_button.setIcon(QIcon('{0}/resources/icons/unlock.png'.format(PROJECT_FILE_PATH))) else: self.__lock_button.setIcon(QIcon('{0}/resources/icons/lock.png'.format(PROJECT_FILE_PATH))) self.__lock_button.setFixedSize(30, 30) self.__lock_button.clicked.connect(self.lockButtonPressed) self.__daily_lock_date = QDateTimeEdit(self.events_date) self.__daily_lock_date.setCalendarPopup(True) self.__daily_lock_date.setDisplayFormat("dd-MM-yyyy") self.__daily_lock_date.setFixedWidth(150) self.__daily_lock_date.dateTimeChanged.connect(self.setEventDateToDateTimeEditValue) self.layout.addWidget(self.__lock_label) self.layout.addWidget(self.__daily_lock_date) self.layout.addWidget(self.__lock_button) def setDailyLockForDate(self, chosen_date): """ Function for setting this lock into the correct position for this date """ if self.__database_access.isDateLockedToUser(chosen_date): self.lock_status = True self.__lock_button.setIcon(QIcon('{0}/resources/icons/lock.png'.format(PROJECT_FILE_PATH))) else: self.lock_status = False self.__lock_button.setIcon(QIcon('{0}/resources/icons/unlock.png'.format(PROJECT_FILE_PATH))) def setEventDateToDateTimeEditValue(self): """ Function that sets a new value to event_date from the DateTimeEdit widget """ self.events_date = self.__daily_lock_date.date().toPyDate() self.setNewEventsDate() def setNewEventsDate(self): """ Function for setting the date for the tool and spreading the information around the program """ self.parent().parent().parent().parent().setEventsForChosenDate(self.events_date) def lockButtonPressed(self): """ Function for locking the chosen date of the daily lock manager """ if self.lock_status: self.parent().parent().parent().parent().saveChanges() self.__database_access.unlockDayForUser(self.events_date) else: self.__database_access.lockDayForUser(self.events_date) self.parent().parent().parent().parent().setEventsForChosenDate(self.events_date)
class ri(QWidget): #日报table框组建 def __init__(self, config, parent=None): super(ri, self).__init__(parent) self.workThread = WorkThread() #多线程 self.workThread.sinOut.connect(self.setp) #多线程链接信号输出 layout = QGridLayout() #创建一个表格排列 self.sheetbox = QGroupBox("表名") self.sheetbox_lo = QGridLayout() self.sheetbox.setLayout(self.sheetbox_lo) self.rp_config = QGroupBox("日报配置") self.rp_config_lo = QGridLayout() self.rp_config.setLayout(self.rp_config_lo) layout.addWidget(self.sheetbox, 0, 0) layout.addWidget(self.rp_config, 1, 0) self.fileName1 = '' ###############第一行 文件选择框 ######## self.rp_config_lo.addWidget(QLabel('报表文件', self.rp_config), 0, 0) self.qtfile = QLineEdit('', self.rp_config) self.qtfile.insert(config['sheet_day']['filename'] if 'filename' in config['sheet_day'].keys() else '') self.qtfile.editingFinished.connect(self.creatsheetCheckBox) self.qbfile = QPushButton('选择文件', self.rp_config) self.qbfile.clicked.connect(self.button_click) self.qbfile.setEnabled(True) self.rp_config_lo.addWidget(self.qtfile, 0, 1, 1, 6) self.rp_config_lo.addWidget(self.qbfile, 0, 7) ######################第二行################################################ self.rp_config_lo.addWidget(QLabel('规则行', self.rp_config), 1, 0) self.gzh = QLineEdit('', self.rp_config) self.gzh.insert(config['sheet_day']['gzh']) self.gzh.setFixedWidth(40) self.rp_config_lo.addWidget(QLabel('时间列', self.rp_config), 1, 2) self.sjl = QLineEdit('', self.rp_config) self.sjl.insert(config['sheet_day']['sjl']) self.sjl.setFixedWidth(40) self.rp_config_lo.addWidget(QLabel('BMS厂家', self.rp_config), 1, 4) jslist = ['共济', '中联', '栅格'] self.jsComboBox = QComboBox(self.rp_config) #下拉菜单 for i in jslist: self.jsComboBox.addItem(i) self.jsComboBox.setCurrentIndex(int(config['sheet_day']['cj'])) self.rp_config_lo.addWidget(QLabel('模式', self.rp_config), 1, 6) jslist2 = ['0--寻找日期', '1--最后填充'] self.js2ComboBox = QComboBox(self.rp_config) #下拉菜单 for i in jslist2: self.js2ComboBox.addItem(i) self.js2ComboBox.setCurrentIndex(int(config['sheet_day']['mode'])) self.rp_config_lo.addWidget(self.gzh, 1, 1) self.rp_config_lo.addWidget(self.sjl, 1, 3) self.rp_config_lo.addWidget(self.jsComboBox, 1, 5) self.rp_config_lo.addWidget(self.js2ComboBox, 1, 7) ######################第三行时间选择行############################# self.rp_config_lo.addWidget(QLabel('起始时间', self.rp_config), 2, 0) self.dt1 = QDateTimeEdit(QDate.currentDate(), self.rp_config) # 创建日期,并初始值 self.dt1.setDisplayFormat('yyyy-MM-dd') #self.dt1.setMinimumDate(QDate.currentDate().addDays(-90)) # 限定时间最小值,当前时间-365天 self.dt1.setMaximumDate( QDate.currentDate().addDays(1)) # 限定时间最大值,当前时间+365天 self.dt1.setCalendarPopup( True) # 允许弹出窗口选择日期,setMinimumDate()的限定对这个窗口也有效 # #############结束时间选择 self.rp_config_lo.addWidget(QLabel('结束时间', self.rp_config), 2, 4) self.dt2 = QDateTimeEdit(QDate.currentDate(), self.rp_config) # 创建日期,并初始值 self.dt2.setDate(QDate.currentDate()) #self.dt2.setMinimumDate(QDate.currentDate().addDays(-90)) # 限定时间最小值,当前时间-365天 self.dt2.setMaximumDate( QDate.currentDate().addDays(1)) # 限定时间最大值,当前时间+365天 self.dt2.setCalendarPopup( True) # 允许弹出窗口选择日期,setMinimumDate()的限定对这个窗口也有效 ###########查询按钮########### self.qtb1 = QPushButton('查询', self.rp_config) self.qtb1.clicked.connect(self.work) self.rp_config_lo.addWidget(self.dt1, 2, 1, 1, 3) self.rp_config_lo.addWidget(self.dt2, 2, 5, 1, 2) self.rp_config_lo.addWidget(self.qtb1, 2, 7) #######第四行进度条 self.rp_config_lo.addWidget(QLabel('进度', self.rp_config), 3, 0) self.pbar = QProgressBar(self.rp_config) #self.pbar.setFixedWidth(560) self.rp_config_lo.addWidget(self.pbar, 3, 1, 1, 6) self.setLayout(layout) self.creatsheetCheckBox() def creatsheetCheckBox(self): qlist = self.sheetbox.findChildren((QCheckBox, QLabel)) #print(help(self.sheetbox_lo)) for i in qlist: self.sheetbox_lo.removeWidget(i) sip.delete(i) filename = str(self.qtfile.text()) if not path.exists(filename): self.sheetbox_lo.addWidget(QLabel('文件不存在', self.sheetbox), 0, 0) else: wb = load_workbook(filename) sheetname = wb.get_sheet_names() for index, i in enumerate(sheetname): lc[i] = QCheckBox(self.sheetbox) lc[i].setObjectName(i) lc[i].setText(i) lc[i].setStatusTip(i) lc[i].setChecked(True) a, b = divmod(index, 5) self.sheetbox_lo.addWidget(lc[i], a, b) gc.collect() def initserverinfo(self, host, port, user, passwd, db): self.workThread.init1(host, port, user, passwd, db) def setp(self, num): if num < 100: self.pbar.setValue(num) elif num == 1000: self.qtb1.setEnabled(True) self.pbar.setValue(0) self.workThread.quit() QMessageBox.information(self, "错误", "文件保存失败,检查文件是否被打开", QMessageBox.Yes) elif num == 2000: self.qtb1.setEnabled(True) self.pbar.setValue(0) #self.workThread.quit() QMessageBox.information(self, "错误", "无法导入pymysql依赖包", QMessageBox.Yes) elif num == 2001: self.qtb1.setEnabled(True) self.pbar.setValue(0) #self.workThread.quit() QMessageBox.information(self, "错误", "无法导入msmysql依赖包", QMessageBox.Yes) elif num >= 100 and num < 101: self.qtb1.setEnabled(True) self.pbar.setValue(num) QMessageBox.information(self, "提示", "报表导出成功1", QMessageBox.Yes) def work(self): self.t1 = time.mktime( time.strptime(self.dt1.date().toString(Qt.ISODate), "%Y-%m-%d")) self.t2 = time.mktime( time.strptime(self.dt2.date().toString(Qt.ISODate), "%Y-%m-%d")) + 60 * 60 * 24 c_cheetname = [] for i in self.sheetbox.findChildren(QCheckBox): if i.isChecked(): c_cheetname.append(i.statusTip()) if time.mktime( time.strptime(self.dt1.date().toString( Qt.ISODate), "%Y-%m-%d")) > time.mktime( time.strptime(self.dt2.date().toString(Qt.ISODate), "%Y-%m-%d")): QMessageBox.information(self, "信息", "起始时间不能大于结束时间", QMessageBox.Yes) else: gzh = self.gzh.text() sjl = self.sjl.text() cj = self.jsComboBox.currentText() self.fileName1 = self.qtfile.text() mode = int(self.js2ComboBox.currentText().split('--')[0]) if not path.exists(self.fileName1): QMessageBox.information(self, "提示", "检查配置,找不到模板文件", QMessageBox.No) elif len(c_cheetname) == 0: QMessageBox.information(self, "提示", "没有选中任何工作表", QMessageBox.No) else: self.qtb1.setEnabled(False) self.workThread.init2(self.fileName1, self.t1, self.t2, gzh, sjl, cj, mode, c_cheetname) self.workThread.start() #计时开始 #self.workThread.trigger.connect(over) #当获得循环完毕的信号时,停止计数 def button_click(self): # absolute_path is a QString object self.fileName1, self.filetype = QFileDialog.getOpenFileName( self, "选取文件", "", "xlsx (*.xlsx)") #设置文件扩展名过滤,注意用双分号间隔 if self.fileName1 == '': pass else: self.qtfile.clear() self.qtfile.insert(self.fileName1) self.creatsheetCheckBox()
class BRFManager(myqt.QFrameLayout): sig_brfperiod_changed = QSignal(list) def __init__(self, wldset=None, parent=None): super(BRFManager, self).__init__(parent) self.viewer = BRFViewer(wldset, parent) self.kgs_brf_installer = None self.__initGUI__() def __initGUI__(self): self.setContentsMargins(10, 10, 10, 10) # ---- Detrend and Correct Options self.baro_spinbox = myqt.QDoubleSpinBox(100, 0, show_buttons=True) self.baro_spinbox.setRange(0, 9999) self.baro_spinbox.setKeyboardTracking(True) self.earthtides_spinbox = myqt.QDoubleSpinBox(100, 0, show_buttons=True) self.earthtides_spinbox.setRange(0, 9999) self.earthtides_spinbox.setKeyboardTracking(True) self.earthtides_cbox = QCheckBox('Nbr of ET lags :') self.earthtides_cbox.setChecked(True) self.earthtides_cbox.stateChanged.connect( lambda: self.earthtides_spinbox.setEnabled(self.earthtides_cbox. isChecked())) self.detrend_waterlevels_cbox = QCheckBox('Detrend water levels') self.detrend_waterlevels_cbox.setChecked(True) # Setup options layout. options_layout = QGridLayout() options_layout.addWidget(QLabel('Nbr of BP lags :'), 0, 0) options_layout.addWidget(self.baro_spinbox, 0, 2) options_layout.addWidget(self.earthtides_cbox, 1, 0) options_layout.addWidget(self.earthtides_spinbox, 1, 2) options_layout.addWidget(self.detrend_waterlevels_cbox, 2, 0, 1, 3) options_layout.setColumnStretch(1, 100) options_layout.setContentsMargins(0, 0, 0, 0) # ---- BRF date range self.date_start_edit = QDateTimeEdit() self.date_start_edit.setCalendarPopup(True) self.date_start_edit.setDisplayFormat('dd/MM/yyyy hh:mm') self.date_start_edit.dateChanged.connect( lambda: self.sig_brfperiod_changed.emit(self.get_brfperiod())) self.date_start_edit.dateChanged.connect( lambda: self.wldset.save_brfperiod(self.get_brfperiod())) self.date_end_edit = QDateTimeEdit() self.date_end_edit.setCalendarPopup(True) self.date_end_edit.setDisplayFormat('dd/MM/yyyy hh:mm') self.date_end_edit.dateChanged.connect( lambda: self.sig_brfperiod_changed.emit(self.get_brfperiod())) self.date_end_edit.dateChanged.connect( lambda: self.wldset.save_brfperiod(self.get_brfperiod())) self.btn_seldata = OnOffToolButton('select_range', size='small') self.btn_seldata.setToolTip("Select a BRF calculation period with " "the mouse cursor on the graph.") # Setup BRF date range layout. daterange_layout = QGridLayout() daterange_layout.addWidget(QLabel('BRF Start :'), 0, 0) daterange_layout.addWidget(self.date_start_edit, 0, 2) daterange_layout.addWidget(QLabel('BRF End :'), 1, 0) daterange_layout.addWidget(self.date_end_edit, 1, 2) daterange_layout.setColumnStretch(1, 100) daterange_layout.setContentsMargins(0, 0, 0, 0) seldata_layout = QGridLayout() seldata_layout.addWidget(self.btn_seldata, 0, 0) seldata_layout.setRowStretch(1, 100) seldata_layout.setContentsMargins(0, 0, 0, 0) # ---- Toolbar btn_comp = QPushButton('Compute BRF') btn_comp.clicked.connect(self.calc_brf) btn_comp.setFocusPolicy(Qt.NoFocus) self.btn_show = QToolButtonSmall(icons.get_icon('search')) self.btn_show.clicked.connect(self.viewer.show) # ---- Main Layout self.addLayout(daterange_layout, 0, 0) self.addLayout(seldata_layout, 0, 1) self.setRowMinimumHeight(1, 15) self.addLayout(options_layout, 2, 0) self.setRowMinimumHeight(3, 15) self.setRowStretch(3, 100) self.addWidget(btn_comp, 4, 0) self.addWidget(self.btn_show, 4, 1) self.setColumnStretch(0, 100) # ---- Install Panel if not KGSBRFInstaller().kgsbrf_is_installed(): self.__install_kgs_brf_installer() # ---- Properties @property def nlag_baro(self): """Return the number of lags to use for barometric correction.""" return self.baro_spinbox.value() @property def nlag_earthtides(self): """Return the number of lags to use for Earth tides correction.""" return (self.earthtides_spinbox.value() if self.earthtides_cbox.isChecked() else -1) @property def detrend_waterlevels(self): return self.detrend_waterlevels_cbox.isChecked() @property def correct_waterlevels(self): return True def get_brfperiod(self): """ Get the period over which the BRF would be evaluated as a list of two numerical Excel date values. """ year, month, day = self.date_start_edit.date().getDate() hour = self.date_start_edit.time().hour() minute = self.date_start_edit.time().minute() dstart = xldate_from_datetime_tuple( (year, month, day, hour, minute, 0), 0) year, month, day = self.date_end_edit.date().getDate() hour = self.date_end_edit.time().hour() minute = self.date_end_edit.time().minute() dend = xldate_from_datetime_tuple((year, month, day, hour, minute, 0), 0) return [dstart, dend] def set_brfperiod(self, period): """ Set the value of the date_start_edit and date_end_edit widgets used to define the period over which the BRF is evaluated. Also save the period to the waterlevel dataset. """ period = np.sort(period).tolist() widgets = (self.date_start_edit, self.date_end_edit) for xldate, widget in zip(period, widgets): if xldate is not None: widget.blockSignals(True) widget.setDateTime(qdatetime_from_xldate(xldate)) widget.blockSignals(False) self.wldset.save_brfperiod(period) # ---- KGS BRF installer def __install_kgs_brf_installer(self): """ Installs a KGSBRFInstaller that overlays the whole brf tool layout until the KGS_BRF program is installed correctly. """ self.kgs_brf_installer = KGSBRFInstaller() self.kgs_brf_installer.sig_kgs_brf_installed.connect( self.__uninstall_kgs_brf_installer) self.addWidget(self.kgs_brf_installer, 0, 0, self.rowCount(), self.columnCount()) def __uninstall_kgs_brf_installer(self): """ Uninstall the KGSBRFInstaller after the KGS_BRF program has been installed properly. """ self.kgs_brf_installer.sig_kgs_brf_installed.disconnect() self.kgs_brf_installer = None def set_wldset(self, wldset): """Set the namespace for the wldset in the widget.""" self.wldset = wldset self.viewer.set_wldset(wldset) self.btn_seldata.setAutoRaise(True) self.setEnabled(wldset is not None) if wldset is not None: xldates = self.wldset.xldates self.set_daterange((xldates[0], xldates[-1])) # Set the period over which the BRF would be evaluated. saved_brfperiod = wldset.get_brfperiod() self.set_brfperiod( (saved_brfperiod[0] or np.floor(xldates[0]), saved_brfperiod[1] or np.floor(xldates[-1]))) def set_daterange(self, daterange): """ Set the minimum and maximum value of date_start_edit and date_end_edit widgets from the specified list of Excel numeric dates. """ for widget in (self.date_start_edit, self.date_end_edit): widget.blockSignals(True) widget.setMinimumDateTime(qdatetime_from_xldate(daterange[0])) widget.setMaximumDateTime(qdatetime_from_xldate(daterange[1])) widget.blockSignals(False) def calc_brf(self): """Prepare the data, calcul the brf, and save and plot the results.""" # Prepare the datasets. well = self.wldset['Well'] brfperiod = self.get_brfperiod() t1 = min(brfperiod) i1 = np.where(self.wldset.xldates >= t1)[0][0] t2 = max(brfperiod) i2 = np.where(self.wldset.xldates <= t2)[0][-1] time = np.copy(self.wldset.xldates[i1:i2 + 1]) wl = np.copy(self.wldset['WL'][i1:i2 + 1]) bp = np.copy(self.wldset['BP'][i1:i2 + 1]) if len(bp) == 0: msg = ("The barometric response function cannot be computed" " because the currently selected water level dataset does" " not contain any barometric data for the selected period.") QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return et = np.copy(self.wldset['ET'][i1:i2 + 1]) if len(et) == 0: et = np.zeros(len(wl)) # Fill the gaps in the waterlevel data. dt = np.min(np.diff(time)) tc = np.arange(t1, t2 + dt / 2, dt) if len(tc) != len(time) or np.any(np.isnan(wl)): print('Filling gaps in data with linear interpolation.') indx = np.where(~np.isnan(wl))[0] wl = np.interp(tc, time[indx], wl[indx]) indx = np.where(~np.isnan(bp))[0] bp = np.interp(tc, time[indx], bp[indx]) indx = np.where(~np.isnan(et))[0] et = np.interp(tc, time[indx], et[indx]) time = tc QApplication.setOverrideCursor(Qt.WaitCursor) print('calculating the BRF') bm.produce_BRFInputtxt(well, time, wl, bp, et) msg = ("Not enough data. Try enlarging the selected period " "or reduce the number of BP lags.") if self.nlag_baro >= len(time) or self.nlag_earthtides >= len(time): QApplication.restoreOverrideCursor() QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return bm.produce_par_file(self.nlag_baro, self.nlag_earthtides, self.detrend_waterlevels, self.correct_waterlevels) bm.run_kgsbrf() try: dataf = bm.read_brf_output() date_start, date_end = (xldate_as_datetime(xldate, 0) for xldate in self.get_brfperiod()) self.wldset.save_brf(dataf, date_start, date_end, self.detrend_waterlevels) self.viewer.new_brf_added() self.viewer.show() QApplication.restoreOverrideCursor() except Exception: QApplication.restoreOverrideCursor() QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return
class LessonLoadingWidget(AbstractLoadingWizard, IAcceptDrop, ISelectFile): label = "Загрузить занятия" description = "Открывает интерфейс загрузки занятия" steps = [ Step('Выбрать дату начала семестра', ''), Step('Загрузить файл с расписанием', 'требуется загрузить файл с распсианием занятий', False), Step('Загрузить данные для всех групп', '', False) ] group_steps: Dict[str, Step] def setupUi(self): main_layout = QVBoxLayout() date_input_layout = QHBoxLayout() self.select_date_label = QLabel("Выберите дату начала семестра") self.date_input = QDateTimeEdit( Semester.closest_semester_start().date()) self.date_input.setCalendarPopup(True) self.accept_date_button = QPushButton("Подтвердить") date_input_layout.addWidget(self.select_date_label) date_input_layout.addWidget(self.date_input, stretch=9) date_input_layout.addWidget(self.accept_date_button) self.hello_message = QLabel( "Выберите файл с расписанием или перетащите его в окно.") self.select_button = QPushButton("Выбрать") main_layout.addLayout(date_input_layout) main_layout.addWidget(self.hello_message, alignment=Qt.AlignHCenter | Qt.AlignVCenter) main_layout.addWidget(self.select_button, alignment=Qt.AlignHCenter | Qt.AlignTop) self.setLayout(main_layout) def __init__(self, professor, loading_session, parent=None): QWidget.__init__(self, parent) IAcceptDrop.__init__(self) ISelectFile.__init__(self) self.professor = professor self.session = professor.session() self.loading_session = loading_session self.setupUi() def change_date(): self.date_input.setEnabled(True) self.revoke_step.emit(self.steps[0]) self.accept_date_button.setText("Подтвердить") self.accept_date_button.clicked.connect(accept_date) with suppress(TypeError): self.accept_date_button.clicked.disconnect(change_date) self.select_button.setEnabled(False) self.select_button.setToolTip("Укажите дату начала семестра") def accept_date(): self.date_input.setEnabled(False) self.step.emit(self.steps[0]) self.accept_date_button.setText("Изменить") self.accept_date_button.clicked.connect(change_date) self.accept_date_button.clicked.disconnect(accept_date) self.select_button.setEnabled(True) self.select_button.setToolTip( "Выберите файл с расписанием занятий") self.accept_date_button.clicked.connect(accept_date) self.select_button.clicked.connect( lambda: self.select_file.emit(self.read_file)) self.drop.connect(self.on_drop) self.requested = False self.group_steps: Dict[Group, Step] = dict() change_date() def on_drop(self, files): if not self.date_input.isEnabled(): for file in files: self.read_file(file) else: QMessageBox().information(self, "", "Сначала укажите дату начала семестра.") def read_file(self, file: QUrl): self.worker = LessonLoader.auto(file=file.path(), start_day=datetime( self.date_input.date().year(), self.date_input.date().month(), self.date_input.date().day()), professor=self.professor, session=self.loading_session) main_layout = self.layout() main_layout.removeWidget(self.hello_message) main_layout.removeWidget(self.select_button) self.hello_message.deleteLater() self.select_button.deleteLater() self.info_message = QLabel( "Предоставте необходимые данные для завершения загрузки") data_layout = QHBoxLayout() discipline_layout = QVBoxLayout() self.discipline_title = QLabel("Обнаружены следующие дисциплины") self.discipline_list = QNewItemsTable(self.session, self.loading_session) for discipline in self.worker.get_disciplines(): self.discipline_list.addItem(discipline) discipline_layout.addWidget(self.discipline_title) discipline_layout.addWidget(self.discipline_list) group_layout = QVBoxLayout() self.group_title = QLabel("Обнаружены следующие группы") self.group_list = QNewItemsTable(self.session, self.loading_session) self.steps = self.steps[:-1] for group in self.worker.get_groups(): self.group_list.addItem(group) group_step = Step(f'Загрузить данные группы {group.name}', '') self.group_steps[group.name]: Dict[str, Step] = group_step self.steps.append(group_step) self.steps_changed.emit(self.steps) student_layout = QHBoxLayout() control_student_layout = QVBoxLayout() self.description_label = QLabel( "Необходимо загрузить информацию о группах.") self.server_load_button = QPushButton("Загрузить с сервера") self.server_load_button.clicked.connect(self.request_students) self.client_load_button = QPushButton("Выбрать файл") self.client_load_button.clicked.connect( lambda x: self.select_file.emit(self.load_group)) list_student_layout = QVBoxLayout() self.tabs = QTabWidget() self.students_lists: Dict[Group, QListWidget] = dict() for group in self.worker.get_groups(): list_widget = QNewItemsTable(self.session, self.loading_session) self.students_lists[group] = list_widget self.tabs.addTab(list_widget, group.name) for group in self.worker.get_groups(): if len(group.students): self._apply_group(group_name=group.name, students=group.students) self.step.emit(self.group_steps[group.name]) list_student_layout.addWidget(QLabel("Списки групп")) list_student_layout.addWidget(self.tabs) control_student_layout.addWidget(self.description_label) control_student_layout.addWidget(self.server_load_button) control_student_layout.addWidget(self.client_load_button) student_layout.addLayout(control_student_layout) student_layout.addLayout(list_student_layout) group_layout.addWidget(self.group_title) group_layout.addWidget(self.group_list) data_layout.addLayout(discipline_layout) data_layout.addLayout(group_layout) main_layout.addLayout(data_layout, stretch=1) main_layout.addWidget(QSeparator(Qt.Horizontal)) main_layout.addLayout(student_layout, stretch=10) self.step.emit(self.steps[1]) def check_groups(self, groups: List[Group]): for index, group in enumerate(groups): existing_group = self.session.query(Group).filter( Group.name == group.name).first() if existing_group is not None: students = Student.of(existing_group) if len(students) > 0: self._apply_group(existing_group.name, existing_group.students) def load_group(self, file: QUrl): group_loader = GroupLoader.auto(file=file.path(), professor=self.professor, session=self.loading_session) group = group_loader.get_group() self._apply_group(group.name, group_loader.get_students_list()) def _apply_group(self, group_name: str, students: List[Student]): group: Group = list( filter(lambda x: x.name == group_name, self.students_lists.keys()))[0] list_widget = self.students_lists[group] list_widget.clear() for student in students: self.loading_session.add(student) list_widget.addItem(student) self.loading_session.flush() self.step.emit(self.group_steps[group.name]) def request_students(self): def apply_response(group: GroupAPI.GroupResponse): self._apply_group(group_name=group.name, students=group.students) if not self.requested: self.managers = list() for group in self.students_lists.keys(): self.managers.append( QBisitorRequest(address='/api/group', user=self.professor, data={'name': group.name}, on_finish=apply_response)) self.requested = True else: QMessageBox().information( self, "", "Вы уже запросили информацию с сервера.")
class SelectionScreen(QWidget): """ Screen for showing and modifying current selections """ def __init__(self, parent, selection_manager): super().__init__(parent) self.selection_manager = selection_manager layout = QGridLayout(self) layout.setColumnMinimumWidth(0, 0) layout.setColumnMinimumWidth(1, 0) layout.setColumnMinimumWidth(2, 0) layout.setColumnMinimumWidth(3, 400) layout.setSpacing(5) label_size = 200 self.date_label = QLabel('Date ', self) self.date_label.setAlignment(Qt.AlignRight) self.date_widget = QDateTimeEdit(self) self.date_widget.setDisplayFormat("dd-MM-yyyy") self.date_widget.setCalendarPopup(True) self.date_widget.setAlignment(Qt.AlignLeft) self.date_widget.setFixedWidth(label_size) self.date_widget.dateChanged.connect(self.handleSelectDate) self.date_widget.setEnabled(False) self.enable_date_button = QPushButton('Enable', self) self.enable_date_button.clicked.connect(self.enableSelectDate) self.enabled = False self.clear_all_button = QPushButton('Clear', self) self.clear_all_button.clicked.connect(self.clearAllSelections) self.selected_label = QLabel('Selected: ', self) self.selected_label.setAlignment(Qt.AlignRight) self.selected_field = QLabel('None', self) self.selected_field.setAlignment(Qt.AlignLeft) empty_widget = QWidget() empty_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) layout.addWidget( self.date_label, 0, 0, ) layout.addWidget(self.date_widget, 0, 1) layout.addWidget(self.enable_date_button, 0, 2) layout.addWidget(self.selected_label, 1, 0) layout.addWidget(self.selected_field, 1, 1) layout.addWidget(self.clear_all_button, 1, 2) layout.addWidget(empty_widget, 2, 0) self.setLayout(layout) def clearAllSelections(self): """ Function for clearing all selections """ self.parent().parent().clearSelections() def updateViews(self): """ Function for updating all views """ self.parent().parent().updateDataViewWidget() def enableSelectDate(self): """ Function for clearing date selection """ if self.enabled: self.date_widget.setEnabled(False) self.selection_manager.clearDate() self.enabled = False self.enable_date_button.setText('Enable') else: self.date_widget.setEnabled(True) self.selection_manager.selectDate( self.date_widget.date().toPyDate()) self.enabled = True self.enable_date_button.setText('Disable') self.updateViews() def handleSelectDate(self, new_date): """ Function that handles select date changes """ self.selection_manager.selectDate(new_date.toPyDate()) def changeSelectedFieldLabel(self, new_text): """ Function for changing the label text """ self.selected_field.setText(new_text)
class BRFManager(myqt.QFrameLayout): sig_brfperiod_changed = QSignal(list) def __init__(self, wldset=None, parent=None): super(BRFManager, self).__init__(parent) self.viewer = BRFViewer(wldset, parent) self.kgs_brf_installer = None self.__initGUI__() def __initGUI__(self): self.setContentsMargins(10, 10, 10, 10) # ---- Detrend and Correct Options self.baro_spinbox = myqt.QDoubleSpinBox(100, 0, show_buttons=True) self.baro_spinbox.setRange(0, 9999) self.baro_spinbox.setKeyboardTracking(True) self.earthtides_spinbox = myqt.QDoubleSpinBox( 100, 0, show_buttons=True) self.earthtides_spinbox.setRange(0, 9999) self.earthtides_spinbox.setKeyboardTracking(True) self.earthtides_cbox = QCheckBox('Nbr of ET lags :') self.earthtides_cbox.setChecked(True) self.earthtides_cbox.stateChanged.connect( lambda: self.earthtides_spinbox.setEnabled( self.earthtides_cbox.isChecked())) self.detrend_waterlevels_cbox = QCheckBox('Detrend water levels') self.detrend_waterlevels_cbox.setChecked(True) # Setup options layout. options_layout = QGridLayout() options_layout.addWidget(QLabel('Nbr of BP lags :'), 0, 0) options_layout.addWidget(self.baro_spinbox, 0, 2) options_layout.addWidget(self.earthtides_cbox, 1, 0) options_layout.addWidget(self.earthtides_spinbox, 1, 2) options_layout.addWidget(self.detrend_waterlevels_cbox, 2, 0, 1, 3) options_layout.setColumnStretch(1, 100) options_layout.setContentsMargins(0, 0, 0, 0) # ---- BRF date range self.date_start_edit = QDateTimeEdit() self.date_start_edit.setCalendarPopup(True) self.date_start_edit.setDisplayFormat('dd/MM/yyyy hh:mm') self.date_start_edit.dateChanged.connect( lambda: self.sig_brfperiod_changed.emit(self.get_brfperiod())) self.date_start_edit.dateChanged.connect( lambda: self.wldset.save_brfperiod(self.get_brfperiod())) self.date_end_edit = QDateTimeEdit() self.date_end_edit.setCalendarPopup(True) self.date_end_edit.setDisplayFormat('dd/MM/yyyy hh:mm') self.date_end_edit.dateChanged.connect( lambda: self.sig_brfperiod_changed.emit(self.get_brfperiod())) self.date_end_edit.dateChanged.connect( lambda: self.wldset.save_brfperiod(self.get_brfperiod())) self.btn_seldata = OnOffToolButton('select_range', size='small') self.btn_seldata.setToolTip("Select a BRF calculation period with " "the mouse cursor on the graph.") # Setup BRF date range layout. daterange_layout = QGridLayout() daterange_layout.addWidget(QLabel('BRF Start :'), 0, 0) daterange_layout.addWidget(self.date_start_edit, 0, 2) daterange_layout.addWidget(QLabel('BRF End :'), 1, 0) daterange_layout.addWidget(self.date_end_edit, 1, 2) daterange_layout.setColumnStretch(1, 100) daterange_layout.setContentsMargins(0, 0, 0, 0) seldata_layout = QGridLayout() seldata_layout.addWidget(self.btn_seldata, 0, 0) seldata_layout.setRowStretch(1, 100) seldata_layout.setContentsMargins(0, 0, 0, 0) # ---- Toolbar btn_comp = QPushButton('Compute BRF') btn_comp.clicked.connect(self.calc_brf) btn_comp.setFocusPolicy(Qt.NoFocus) self.btn_show = QToolButtonSmall(icons.get_icon('search')) self.btn_show.clicked.connect(self.viewer.show) # ---- Main Layout self.addLayout(daterange_layout, 0, 0) self.addLayout(seldata_layout, 0, 1) self.setRowMinimumHeight(1, 15) self.addLayout(options_layout, 2, 0) self.setRowMinimumHeight(3, 15) self.setRowStretch(3, 100) self.addWidget(btn_comp, 4, 0) self.addWidget(self.btn_show, 4, 1) self.setColumnStretch(0, 100) # ---- Install Panel if not KGSBRFInstaller().kgsbrf_is_installed(): self.__install_kgs_brf_installer() # ---- Properties @property def nlag_baro(self): """Return the number of lags to use for barometric correction.""" return self.baro_spinbox.value() @property def nlag_earthtides(self): """Return the number of lags to use for Earth tides correction.""" return (self.earthtides_spinbox.value() if self.earthtides_cbox.isChecked() else -1) @property def detrend_waterlevels(self): return self.detrend_waterlevels_cbox.isChecked() @property def correct_waterlevels(self): return True def get_brfperiod(self): """ Get the period over which the BRF would be evaluated as a list of two numerical Excel date values. """ year, month, day = self.date_start_edit.date().getDate() hour = self.date_start_edit.time().hour() minute = self.date_start_edit.time().minute() dstart = xldate_from_datetime_tuple( (year, month, day, hour, minute, 0), 0) year, month, day = self.date_end_edit.date().getDate() hour = self.date_end_edit.time().hour() minute = self.date_end_edit.time().minute() dend = xldate_from_datetime_tuple( (year, month, day, hour, minute, 0), 0) return [dstart, dend] def set_brfperiod(self, period): """ Set the value of the date_start_edit and date_end_edit widgets used to define the period over which the BRF is evaluated. Also save the period to the waterlevel dataset. """ period = np.sort(period).tolist() widgets = (self.date_start_edit, self.date_end_edit) for xldate, widget in zip(period, widgets): if xldate is not None: widget.blockSignals(True) widget.setDateTime(qdatetime_from_xldate(xldate)) widget.blockSignals(False) self.wldset.save_brfperiod(period) # ---- KGS BRF installer def __install_kgs_brf_installer(self): """ Installs a KGSBRFInstaller that overlays the whole brf tool layout until the KGS_BRF program is installed correctly. """ self.kgs_brf_installer = KGSBRFInstaller() self.kgs_brf_installer.sig_kgs_brf_installed.connect( self.__uninstall_kgs_brf_installer) self.addWidget(self.kgs_brf_installer, 0, 0, self.rowCount(), self.columnCount()) def __uninstall_kgs_brf_installer(self): """ Uninstall the KGSBRFInstaller after the KGS_BRF program has been installed properly. """ self.kgs_brf_installer.sig_kgs_brf_installed.disconnect() self.kgs_brf_installer = None def set_wldset(self, wldset): """Set the namespace for the wldset in the widget.""" self.wldset = wldset self.viewer.set_wldset(wldset) self.btn_seldata.setAutoRaise(True) self.setEnabled(wldset is not None) if wldset is not None: xldates = self.wldset.xldates self.set_daterange((xldates[0], xldates[-1])) # Set the period over which the BRF would be evaluated. saved_brfperiod = wldset.get_brfperiod() self.set_brfperiod((saved_brfperiod[0] or np.floor(xldates[0]), saved_brfperiod[1] or np.floor(xldates[-1]))) def set_daterange(self, daterange): """ Set the minimum and maximum value of date_start_edit and date_end_edit widgets from the specified list of Excel numeric dates. """ for widget in (self.date_start_edit, self.date_end_edit): widget.blockSignals(True) widget.setMinimumDateTime(qdatetime_from_xldate(daterange[0])) widget.setMaximumDateTime(qdatetime_from_xldate(daterange[1])) widget.blockSignals(False) def calc_brf(self): """Prepare the data, calcul the brf, and save and plot the results.""" # Prepare the datasets. well = self.wldset['Well'] brfperiod = self.get_brfperiod() t1 = min(brfperiod) i1 = np.where(self.wldset.xldates >= t1)[0][0] t2 = max(brfperiod) i2 = np.where(self.wldset.xldates <= t2)[0][-1] time = np.copy(self.wldset.xldates[i1:i2+1]) wl = np.copy(self.wldset['WL'][i1:i2+1]) bp = np.copy(self.wldset['BP'][i1:i2+1]) if len(bp) == 0: msg = ("The barometric response function cannot be computed" " because the currently selected water level dataset does" " not contain any barometric data for the selected period.") QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return et = np.copy(self.wldset['ET'][i1:i2+1]) if len(et) == 0: et = np.zeros(len(wl)) # Fill the gaps in the waterlevel data. dt = np.min(np.diff(time)) tc = np.arange(t1, t2+dt/2, dt) if len(tc) != len(time) or np.any(np.isnan(wl)): print('Filling gaps in data with linear interpolation.') indx = np.where(~np.isnan(wl))[0] wl = np.interp(tc, time[indx], wl[indx]) indx = np.where(~np.isnan(bp))[0] bp = np.interp(tc, time[indx], bp[indx]) indx = np.where(~np.isnan(et))[0] et = np.interp(tc, time[indx], et[indx]) time = tc QApplication.setOverrideCursor(Qt.WaitCursor) print('calculating the BRF') bm.produce_BRFInputtxt(well, time, wl, bp, et) msg = ("Not enough data. Try enlarging the selected period " "or reduce the number of BP lags.") if self.nlag_baro >= len(time) or self.nlag_earthtides >= len(time): QApplication.restoreOverrideCursor() QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return bm.produce_par_file( self.nlag_baro, self.nlag_earthtides, self.detrend_waterlevels, self.correct_waterlevels) bm.run_kgsbrf() try: dataf = bm.read_brf_output() date_start, date_end = (xldate_as_datetime(xldate, 0) for xldate in self.get_brfperiod()) self.wldset.save_brf(dataf, date_start, date_end, self.detrend_waterlevels) self.viewer.new_brf_added() self.viewer.show() QApplication.restoreOverrideCursor() except Exception: QApplication.restoreOverrideCursor() QMessageBox.warning(self, 'Warning', msg, QMessageBox.Ok) return