class DateDialog(QDialog): def __init__(self, parent=None): super(DateDialog, self).__init__(parent) layout = QVBoxLayout(self) # nice widget for editing the date self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.datetime) # OK and Cancel buttons self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) layout.addWidget(self.buttons) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) # get current date and time from the dialog def dateTime(self): return self.datetime.dateTime() # static method to create the dialog and return (date, time, accepted) @staticmethod def getDateTime(parent=None): dialog = DateDialog(parent) result = dialog.exec_() date = dialog.dateTime() return (date.date(), date.time(), result == QDialog.Accepted)
class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) layout = QVBoxLayout(self) self.label = QLabel(self) self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDateTime(QDateTime.currentDateTime()) self.label.setText("请选择日期") layout.addWidget(self.label) layout.addWidget(self.datetime) buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) #点击ok,隐士存在该方法 buttons.rejected.connect(self.reject) #点击cancel,该方法默认隐士存在 layout.addWidget(buttons) #该方法在父类方法中调用,直接打开了子窗体,返回值则用于向父窗体数据的传递 @staticmethod def getResult(self, parent=None): dialog = Dialog(parent) result = dialog.exec_() d = dialog.datetime.dateTime() return (d.date(), d.time(), result)
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)
def initUI(self): self.setWindowTitle('不同风格的日期格式') layout = QVBoxLayout() datetime1 = QDateTimeEdit(QDateTime.currentDateTime()) datetime2 = QDateTimeEdit(QDateTime.currentDateTime()) date = QDateTimeEdit(QDate.currentDate()) time = QDateTimeEdit(QTime.currentTime()) # 设置最大最小日期时间、下拉日期 datetime1.setMaximumDate(QDate.currentDate().addDays(365)) datetime1.setMinimumDate(QDate.currentDate().addDays(-365)) datetime1.setCalendarPopup(True) datetime1.setDisplayFormat('yyyy-MM-dd HH:mm:ss') datetime2.setDisplayFormat('yyyy/MM/dd HH-mm-ss') date.setDisplayFormat('yyyy-MM-dd') time.setDisplayFormat('HH:mm:ss') # 为信号设置槽 self.datetime1 = datetime1 datetime1.dateTimeChanged.connect(self.ChangeDateTime) datetime2.dateChanged.connect(self.ChangeDate) self.btn = QPushButton('点击获取时间') self.btn.clicked.connect(self.Onclick_Button) layout.addWidget(datetime1) layout.addWidget(datetime2) layout.addWidget(date) layout.addWidget(time) layout.addWidget(self.btn) self.setLayout(layout)
class Dialog(QDialog): #自定义消息 dialogSignel = pyqtSignal(int, str) def __init__(self, parent=None): super(Dialog, self).__init__(parent) layout = QVBoxLayout(self) self.label = QLabel(self) self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDateTime(QDateTime.currentDateTime()) self.label.setText("请选择日期") layout.addWidget(self.label) layout.addWidget(self.datetime) buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) #点击ok buttons.rejected.connect(self.reject) #点击cancel layout.addWidget(buttons) def accept(self): #点击ok是发送内置信号 print("accept") self.dialogSignel.emit(0, self.datetime.text()) self.destroy() def reject(self): #点击cancel时,发送自定义信号 print('reject') self.dialogSignel.emit(1, "清空") self.destroy()
def createEditor(self, parent, option, index): date_edit = QDateTimeEdit(parent) date_edit.setDisplayFormat("yyyy/MM/dd HH:mm") date_edit.setDateTime(QDateTime.currentDateTime()) date_edit.setCalendarPopup(True) return date_edit
def __init__(self, parent=None): super(MainWin, self).__init__(parent) dt_ed = QDateTimeEdit(self) dt_ed2 = QDateTimeEdit(QDateTime.currentDateTime(), self) d_ed = QDateTimeEdit(QDate.currentDate(), self) t_ed = QDateTimeEdit(QTime.currentTime(), self) dt_ed.setDisplayFormat('yyyy-MM-dd HH:mm:ss') dt_ed2.setDisplayFormat('yyyy/MM/dd HH-mm-ss') d_ed.setDisplayFormat('yyyy.MM.dd') t_ed.setDisplayFormat('HH:mm:ss') dt_ed.setMinimumDate(QDate.currentDate().addDays(-365)) dt_ed.setMaximumDate(QDate.currentDate().addDays(365)) dt_ed.setCalendarPopup(True) layout = QVBoxLayout(self) layout.addWidget(dt_ed) layout.addWidget(dt_ed2) layout.addWidget(d_ed) layout.addWidget(t_ed) self.setGeometry(100, 100, 250, 150) self.setWindowTitle('DateTimeEdit')
class DateDialog(QDialog): def __init__(self, parent=None): super(DateDialog, self).__init__(parent) self.setWindowTitle("DateDialog") layout = QVBoxLayout(self) self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.datetime) buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons) def dateTime(self): return self.datetime.dateTime() @staticmethod def getDateTime(parent=None): dialog = DateDialog(parent) result = dialog.exec() date = dialog.dateTime() return date.date(), date.time(), result == QDialog.Accepted
class DateTimeEditDemo(QWidget): """主窗口""" def __init__(self, parent=None): super().__init__(parent=parent) self.setWindowTitle("QDateTimeEdit 使用") self.resize(320, 100) date_time = QDateTime.currentDateTime() self.datetime_edit = QDateTimeEdit(date_time) # 初始化时设置初始值为当前日期时间 # self.datetime_edit.setDateTime(date_time) self.datetime_edit.setDisplayFormat("yyyy-MM-dd HH:mm:ss") # 设置显示格式 self.datetime_edit.setDateTimeRange(date_time.addYears(-1), date_time.addYears(1)) # 设置时间范围 self.datetime_edit.setCalendarPopup(True) # 允许使用Calendar self.datetime_edit.dateTimeChanged.connect( self.datetime_change) # 会向槽函数传递QDateTime self.datetime_edit.dateChanged.connect( self.date_change) # 会向槽函数传递QDate self.datetime_edit.timeChanged.connect( self.time_change) # 会向槽函数传递QTime self.button = QPushButton() self.button.setText("获得日期和时间") self.button.clicked.connect(self.btn_click) self.status_bar = QStatusBar() vbox = QVBoxLayout(self) vbox.addWidget(self.datetime_edit) vbox.addWidget(self.button) vbox.addWidget(self.status_bar) def datetime_change(self, date_time): self.status_bar.showMessage(date_time.__str__()) def date_change(self, date): self.status_bar.showMessage(date.__str__()) def time_change(self, time): self.status_bar.showMessage(time.__str__()) def btn_click(self, event): date_time = self.datetime_edit.dateTime() max_date_time = self.datetime_edit.maximumDateTime() max_date = self.datetime_edit.maximumDate() max_time = self.datetime_edit.maximumTime() min_date_time = self.datetime_edit.minimumDateTime() min_date = self.datetime_edit.minimumDate() min_time = self.datetime_edit.minimumTime() format_str = f"max_date_time: {max_date_time}\nmax_date: {max_date}\nmax_time: {max_time}\n\ min_date_time: {min_date_time}\nmin_time: {min_time}\nmin_time: {min_time}\n{event}" _ = QMessageBox.information(self, "显示QDateTime中的一些数据", format_str)
class MainWin(QWidget): def __init__(self, parent=None): super(MainWin, self).__init__(parent) layout = QVBoxLayout(self) self.dateEdit = QDateTimeEdit(QDateTime.currentDateTime(), self) self.dateEdit.setDisplayFormat('yyyy-MM-dd HH:mm:ss') self.dateEdit.setMinimumDate(QDate.currentDate().addDays(-365)) self.dateEdit.setMaximumDate(QDate.currentDate().addDays(365)) self.dateEdit.setCalendarPopup(True) self.dateEdit.dateChanged.connect(self.onDateChanged) self.dateEdit.dateTimeChanged.connect(self.onDateTimeChanged) self.dateEdit.timeChanged.connect(self.onTimeChanged) self.btn = QPushButton('取得日期和時間') self.btn.clicked.connect(self.onButtonClick) layout.addWidget(self.dateEdit) layout.addWidget(self.btn) self.resize(300, 90) self.setWindowTitle('DateTimeEdit2') def onDateChanged(self, date): print(date) def onDateTimeChanged(self, dateTime): print(dateTime) def onTimeChanged(self, time): print(time) def onButtonClick(self): dateTime = self.dateEdit.dateTime() maxDate = self.dateEdit.maximumDate() maxDateTime = self.dateEdit.maximumDateTime() maxTime = self.dateEdit.maximumTime() minDate = self.dateEdit.minimumDate() minDateTime = self.dateEdit.minimumDateTime() minTime = self.dateEdit.minimumTime() print('\n選擇的日期時間') print('dateTime = %s') print('maxDate = %s' % str(maxDate)) print('maxDateTime = %s' % str(maxDateTime)) print('maxTime = %s' % str(maxTime)) print('minDate = %s' % str(minDate)) print('minDateTime = %s' % str(minDateTime)) print('minTime = %s' % str(minTime))
def add_input(self, k, v): lbl = QLabel(self) lbl.setText(k) self.vbox.addWidget(lbl) if isinstance(v, datetime.date): qle = QDateTimeEdit(self) qle.setDate(v) qle.setDisplayFormat("yyyy.MM.dd") qle.setCalendarPopup(True) else: qle = QLineEdit(self) qle.setText(str(v)) self.vbox.addWidget(qle) return qle
def createEditor(self, parent, styleOption, index): if index.column() == 1: editor = QDateTimeEdit(parent) editor.setDisplayFormat(self.parent().currentDateFormat) editor.setCalendarPopup(True) return editor editor = QLineEdit(parent) # create a completer with the strings in the column as model allStrings = [] for i in range(1, index.model().rowCount()): strItem = index.model().data(index.sibling(i, index.column()), Qt.EditRole) if strItem not in allStrings: allStrings.append(strItem) autoComplete = QCompleter(allStrings) editor.setCompleter(autoComplete) editor.editingFinished.connect(self.commitAndCloseEditor) return editor
class DatetimeEditField(DataEditField): """ Class for editing datetime fields. """ def __init__(self, parent, title, help_text): self.field = QDateTimeEdit(datetime.now()) self.field.setCalendarPopup(True) self.field.setDisplayFormat("dd-MM-yyyy hh:mm:ss") DataEditField.__init__(self, parent, title, help_text, self.field) def clearField(self): """ Set field to current datetime """ self.field.setDateTime(datetime.now()) def getValue(self): """ Get value of DateTimeEditField """ return qDateTime2Datetime(self.field.dateTime())
class DateDialog(QDialog): def __init__(self, parent=None): super(DateDialog, self).__init__(parent) layout = QVBoxLayout(self) # info text self.label = QLabel( text='The file appears to contain relative dates.\n' 'Please specify a reference date.') layout.addWidget(self.label) # nice widget for editing the date self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDisplayFormat('yyyy-MM-dd hh:mm:ss') self.datetime.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.datetime) # OK and Cancel buttons self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) layout.addWidget(self.buttons) self.setLayout(layout) # get current date and time from the dialog def date_time(self): return self.datetime.dateTime() # static method to create the dialog and return (date, time, accepted) @staticmethod def get_date_time(parent=None): dialog = DateDialog(parent) result = dialog.exec_() date = dialog.date_time() return date.toPyDateTime(), result == QDialog.Accepted
class DateDialog(QDialog): def __init__(self, parent=None): super(DateDialog, self).__init__(parent) layout = QVBoxLayout(self) # nice widget for editing the date self.datetime = QDateTimeEdit(self) self.datetime.setCalendarPopup(True) self.datetime.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.datetime) # OK and Cancel buttons self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) layout.addWidget(self.buttons) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) # get current date and time from the dialog def dateTime(self): return self.datetime.dateTime()
class DateDialog(QDialog): """对话窗口""" def __init__(self, parent=None): super().__init__(parent=parent) self.setWindowTitle("多窗口利用控件属性传递参数") self.resize(200, 100) self.datetimedit = QDateTimeEdit(parent=self) self.datetimedit.setCalendarPopup(True) self.datetimedit.setMinimumSize(100, 20) self.datetimedit.setDateTime(QDateTime.currentDateTime()) buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, parent=self) # 两个按钮, 分别连接dialog.accept()和dialog.reject() buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) v_layout = QVBoxLayout() v_layout.addWidget(self.datetimedit) v_layout.addWidget(buttons) self.setLayout(v_layout) def date_time(self): """从对话框中获取当前日期和时间""" return self.datetimedit.dateTime() @staticmethod def get_date_time(parent=None): """静态方法, 创建一个自己, 返回时间""" dialog = DateDialog(parent) result = dialog.exec() date = dialog.date_time() return date.date(), date.time(), result == QDialog.Accepted
class NewDateDialog(QDialog): Signal_OneParameter = pyqtSignal(str) def __init__(self, parent=None): super(NewDateDialog, self).__init__(parent) self.setWindowTitle('子窗口:用来发射信号') # 在布局中添加部件 layout = QVBoxLayout(self) self.label = QLabel(self) self.label.setText('前者发射内置信号\n后者发射自定义信号') self.datetime_inner = QDateTimeEdit(self) self.datetime_inner.setCalendarPopup(True) self.datetime_inner.setDateTime(QDateTime.currentDateTime()) self.datetime_emit = QDateTimeEdit(self) self.datetime_emit.setCalendarPopup(True) self.datetime_emit.setDateTime(QDateTime.currentDateTime()) layout.addWidget(self.label) layout.addWidget(self.datetime_inner) layout.addWidget(self.datetime_emit) # 使用两个button(ok和cancel)分别连接accept()和reject()槽函数 buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons) self.datetime_emit.dateTimeChanged.connect(self.emit_signal) def emit_signal(self): date_str = self.datetime_emit.dateTime().toString() self.Signal_OneParameter.emit(date_str)
class Window(QWidget): def __init__(self): super().__init__() # Make widgets ################# self.edit1 = QDateTimeEdit() self.edit2 = QDateTimeEdit() self.edit3 = QDateTimeEdit() self.edit1.setMinimumDate(datetime.datetime(year=2017, month=9, day=1, hour=8, minute=30, second=30)) self.edit2.setMinimumDate(datetime.datetime(year=2017, month=9, day=1, hour=8, minute=30, second=30)) self.edit3.setMinimumDate(datetime.datetime(year=2017, month=9, day=1, hour=8, minute=30, second=30)) self.edit1.setMaximumDate(datetime.datetime(year=2020, month=9, day=1, hour=18, minute=30, second=30)) self.edit2.setMaximumDate(datetime.datetime(year=2020, month=9, day=1, hour=18, minute=30, second=30)) self.edit3.setMaximumDate(datetime.datetime(year=2020, month=9, day=1, hour=18, minute=30, second=30)) self.edit1.setDateTime(datetime.datetime.now()) self.edit2.setDateTime(datetime.datetime.now()) self.edit3.setDateTime(datetime.datetime.now()) 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 HH:mm") self.edit2.setDisplayFormat("dd/MM/yyyy HH:mm:ss t") self.edit3.setDisplayFormat("dddd d MMMM yyyy h m AP") 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 Downtime(QDialog): """ Class who create Downtime QDialog for hosts/services """ def __init__(self, parent=None): super(Downtime, self).__init__(parent) self.setWindowTitle('Request a Downtime') self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(get_css()) self.setWindowIcon(QIcon(get_image_path('icon'))) self.setMinimumSize(360, 460) # Fields self.fixed = True self.duration = QTimeEdit() self.start_time = QDateTimeEdit() self.end_time = QDateTimeEdit() self.comment_edit = QTextEdit() def initialize(self, item_type, item_name, comment): """ Initialize Downtime QDialog :param item_type: type of item to acknowledge : host | service :type item_type: str :param item_name: name of the item to acknowledge :type item_name: str :param comment: the default comment of action :type comment: str """ # Main layout main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(get_logo_widget(self)) downtime_widget = QWidget() downtime_widget.setObjectName('login') downtime_layout = QGridLayout(downtime_widget) ack_title = QLabel('<h2>Request a downtime</h2>') downtime_layout.addWidget(ack_title, 0, 0, 1, 3) host_label = QLabel('<h2>%s: %s</h2>' % (item_type.capitalize(), item_name)) downtime_layout.addWidget(host_label, 1, 0, 1, 1) options_label = QLabel('Downtime options:') options_label.setObjectName('actions') downtime_layout.addWidget(options_label, 2, 0, 1, 1) fixed_checkbox = QCheckBox() fixed_checkbox.setObjectName('actions') fixed_checkbox.setChecked(self.fixed) fixed_checkbox.setFixedSize(18, 18) downtime_layout.addWidget(fixed_checkbox, 2, 1, 1, 1) fixed_label = QLabel('Fixed') fixed_label.setObjectName('actions') downtime_layout.addWidget(fixed_label, 2, 2, 1, 1) fixed_info = QLabel( '<i>If checked, downtime will start and end at the times specified' ' by the “start time” and “end time” fields.</i>') fixed_info.setWordWrap(True) downtime_layout.addWidget(fixed_info, 3, 0, 1, 3) duration_label = QLabel('Duration') duration_label.setObjectName('actions') downtime_layout.addWidget(duration_label, 4, 0, 1, 1) duration_clock = QLabel() duration_clock.setPixmap(QPixmap(get_image_path('clock'))) downtime_layout.addWidget(duration_clock, 4, 1, 1, 1) duration_clock.setFixedSize(16, 16) duration_clock.setScaledContents(True) self.duration.setTime(QTime(4, 00)) self.duration.setDisplayFormat("HH'h'mm") downtime_layout.addWidget(self.duration, 4, 2, 1, 1) duration_info = QLabel( '<i>Sets the duration if it is a non-fixed downtime.</i>') downtime_layout.addWidget(duration_info, 5, 0, 1, 3) date_range_label = QLabel('Downtime date range') date_range_label.setObjectName('actions') downtime_layout.addWidget(date_range_label, 6, 0, 1, 1) calendar_label = QLabel() calendar_label.setPixmap(QPixmap(get_image_path('calendar'))) calendar_label.setFixedSize(16, 16) calendar_label.setScaledContents(True) downtime_layout.addWidget(calendar_label, 6, 1, 1, 1) start_time_label = QLabel('Start time:') downtime_layout.addWidget(start_time_label, 7, 0, 1, 1) self.start_time.setCalendarPopup(True) self.start_time.setDateTime(datetime.datetime.now()) self.start_time.setDisplayFormat("dd/MM/yyyy HH'h'mm") downtime_layout.addWidget(self.start_time, 7, 1, 1, 2) end_time_label = QLabel('End time:') downtime_layout.addWidget(end_time_label, 8, 0, 1, 1) self.end_time.setCalendarPopup(True) self.end_time.setDateTime(datetime.datetime.now() + datetime.timedelta(hours=2)) self.end_time.setDisplayFormat("dd/MM/yyyy HH'h'mm") downtime_layout.addWidget(self.end_time, 8, 1, 1, 2) self.comment_edit.setText(comment) self.comment_edit.setMaximumHeight(60) downtime_layout.addWidget(self.comment_edit, 9, 0, 1, 3) request_btn = QPushButton('REQUEST DOWNTIME', self) request_btn.clicked.connect(self.handle_accept) request_btn.setObjectName('valid') request_btn.setMinimumHeight(30) request_btn.setDefault(True) downtime_layout.addWidget(request_btn, 10, 0, 1, 3) main_layout.addWidget(downtime_widget) def duration_to_seconds(self): """ Return "duration" QTimeEdit value in seconds :return: "duration" in seconds :rtype: int """ return QTime(0, 0).secsTo(self.duration.time()) def handle_accept(self): """ Check if end_time timestamp is not lower than start_time """ if self.start_time.dateTime().toTime_t() > self.end_time.dateTime( ).toTime_t(): logger.warning( 'Try to add Downtime with "End Time" lower than "Start Time"') else: self.accept() def mousePressEvent(self, event): """ QWidget.mousePressEvent(QMouseEvent) """ self.offset = event.pos() def mouseMoveEvent(self, event): """ QWidget.mousePressEvent(QMouseEvent) """ try: x = event.globalX() y = event.globalY() x_w = self.offset.x() y_w = self.offset.y() self.move(x - x_w, y - y_w) except AttributeError as e: logger.warning('Move Event %s: %s', self.objectName(), str(e))
class Ui_MainWindow(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.transprot_mass =[] self.netprot_mass =[] self.filtering_is_on = 0 grid = QGridLayout() self.setLayout(grid) self.IP_list = IP_list(self) self.TransProt_list = TransProt_list(self) self.NetProt_list = NetProt_list(self) self.setWindowTitle('Гамма') self.setWindowIcon(QIcon('допочки\Gamma_200x200.png')) self.resize(740, 830) self.to_center() self.centralwidget = QWidget(self) self.tabWidget = QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QRect(20, 20, 700, 750)) self.tab = QWidget() grid.addWidget(self.tab) self.cb_time = QCheckBox(self.tab) self.cb_time.setGeometry(QRect(360, 130, 120, 20)) self.cb_time.setText("Фильтр по времени") self.cb_prot = QCheckBox(self.tab) self.cb_prot.setGeometry(QRect(20, 130, 140, 20)) self.cb_prot.setText("Фильтр по протоколам") self.cb_addr = QCheckBox(self.tab) self.cb_addr.setGeometry(QRect(360, 290, 130, 20)) self.cb_addr.setText("Фильтр по IP-адресам") self.dt_beg = QDateTimeEdit(self.tab) self.dt_beg.setGeometry(QRect(360, 210, 150, 20)) self.dt_beg.setDateTime(QDateTime.currentDateTime()) self.dt_beg.setDisplayFormat("dd.MM.yyyy H:mm:ss.zzz") self.dt_beg.setCalendarPopup(True) self.dt_beg.setToolTip('Выбрать начальное время (>=)') self.dt_beg.setEnabled(False) self.dt_end = QDateTimeEdit(self.tab) self.dt_end.setGeometry(QRect(520, 210, 150, 20)) self.dt_end.setDateTime(QDateTime.currentDateTime()) self.dt_end.setDisplayFormat("dd.MM.yyyy H:mm:ss.zzz") self.dt_end.setCalendarPopup(True) self.dt_end.setToolTip('Выбрать конечное время (<)') self.dt_end.setEnabled(False) self.dt_beg.dateChanged.connect(lambda dc: self.date_changed(1)) self.dt_end.dateChanged.connect(lambda dc: self.date_changed(2)) #self.l_input_dir = QLabel(self.tab) #self.l_input_dir.setGeometry(QRect(102, 50, 180, 15)) #self.l_input_dir.setText("Выберите директорию с файлами") #self.l_or = QLabel(self.tab) #self.l_or.setGeometry(QRect(340, 50, 21, 16)) #self.l_or.setText("ИЛИ") self.l_input_file = QLabel(self.tab) self.l_input_file.setGeometry(QRect(300, 50, 90, 15)) self.l_input_file.setText("Выберите файлы") self.l_transpr = QLabel(self.tab) self.l_transpr.setGeometry(QRect(50, 190, 180, 16)) self.l_transpr.setEnabled(False) self.l_transpr.setText("Протоколы Транспортного уровня") self.l_netpr = QLabel(self.tab) self.l_netpr.setGeometry(QRect(50, 290, 180, 16)) self.l_netpr.setEnabled(False) self.l_netpr.setText("Протоколы Сетевого уровня") self.l_beg = QLabel(self.tab) self.l_beg.setGeometry(QRect(390, 190, 60, 16)) self.l_beg.setEnabled(False) self.l_beg.setText("Начиная с..") self.l_end = QLabel(self.tab) self.l_end.setGeometry(QRect(560, 190, 80, 16)) self.l_end.setEnabled(False) self.l_end.setText("Оканчивая до..") self.l_name = QLabel(self.tab) self.l_name.setGeometry(QRect(300, 450, 96, 16)) self.l_name.setText("Как назвать файл?") self.l_filt = QLabel(self.tab) self.l_filt.setGeometry(QRect(300, 10, 91, 16)) self.l_filt.setText("Выборка пакетов") self.line = QFrame(self.tab) self.line.setGeometry(QRect(0, 110, 690, 15)) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.line_2 = QFrame(self.tab) self.line_2.setGeometry(QRect(340, 120, 15, 300)) self.line_2.setFrameShape(QFrame.VLine) self.line_2.setFrameShadow(QFrame.Sunken) self.line_3 = QFrame(self.tab) self.line_3.setGeometry(QRect(0, 420, 690, 15)) self.line_3.setFrameShape(QFrame.HLine) self.line_3.setFrameShadow(QFrame.Sunken) #self.le_dir = QLineEdit(self.tab) #self.le_dir.setGeometry(QRect(110, 80, 211, 20)) #self.le_dir.setEnabled(False) #self.le_dir.setReadOnly(True) self.le_file = QLineEdit(self.tab) self.le_file.setGeometry(QRect(250, 80, 211, 20)) #self.le_file.setEnabled(False) self.le_file.setReadOnly(True) self.le_name = QLineEdit(self.tab) self.le_name.setGeometry(QRect(250, 480, 231, 20)) self.pt_transpr = QPlainTextEdit(self.tab) self.pt_transpr.setGeometry(QRect(50, 210, 271, 71)) self.pt_transpr.setEnabled(False) self.pt_transpr.setReadOnly(True) self.pt_netpr = QPlainTextEdit(self.tab) self.pt_netpr.setGeometry(QRect(50, 320, 271, 71)) self.pt_netpr.setEnabled(False) self.pt_netpr.setReadOnly(True) self.pt_addr = QPlainTextEdit(self.tab) self.pt_addr.setGeometry(QRect(390, 320, 271, 71)) self.pt_addr.setEnabled(False) self.pt_log = QPlainTextEdit(self.tab) self.pt_log.setGeometry(QRect(20, 610, 651, 101)) self.pt_log.setReadOnly(True) self.progressBar = QProgressBar(self.tab) self.progressBar.setGeometry(QRect(20, 580, 651, 20)) self.progressBar.setFormat("%v" + "%") self.progressBar.setMaximum(100) self.progressBar.setValue(0) #self.pb_dir = QPushButton(self.tab) #self.pb_dir.setGeometry(QRect(80, 80, 21, 20)) #self.pb_dir.setIcon(QIcon('допочки\_folder.png')) #self.pb_dir.clicked.connect(lambda gd: self.get_directory(1)) self.pb_file = QPushButton(self.tab) self.pb_file.setGeometry(QRect(220, 80, 21, 20)) self.pb_file.setIcon(QIcon('допочки\_folder.png')) self.pb_file.clicked.connect(lambda gf: self.get_files(1)) self.pb_time = QPushButton(self.tab) self.pb_time.setGeometry(QRect(480, 240, 71, 20)) self.pb_time.setToolTip('Добавить ещё временной отрезок') self.pb_time.setEnabled(False) self.pb_time.setText("Ещё!") self.pb_transpr = QPushButton(self.tab) self.pb_transpr.setGeometry(QRect(20, 210, 21, 20)) self.pb_transpr.setToolTip('Выбрать протоколы Транспортного уровня') self.pb_transpr.setIcon(QIcon('допочки\_blank.png')) self.pb_transpr.setEnabled(False) self.pb_transpr.clicked.connect(self.TransProt_list.exec) self.pb_netpr = QPushButton(self.tab) self.pb_netpr.setGeometry(QRect(20, 320, 21, 20)) self.pb_netpr.setToolTip('Выбрать протоколы Сетевого уровня') self.pb_netpr.setIcon(QIcon('допочки\_blank.png')) self.pb_netpr.setEnabled(False) self.pb_netpr.clicked.connect(self.NetProt_list.exec) self.pb_addr = QPushButton(self.tab) self.pb_addr.setGeometry(QRect(530, 290, 132, 20)) self.pb_addr.setText('Редактировать список') self.pb_addr.setEnabled(False) self.pb_addr.clicked.connect(self.IP_list.exec) self.pb_name = QPushButton(self.tab) self.pb_name.setGeometry(QRect(220, 480, 21, 20)) self.pb_name.setIcon(QIcon('допочки\_folder.png')) self.pb_name.clicked.connect(lambda ed: self.extract_to_directory(1)) self.pb_start = QPushButton(self.tab) self.pb_start.setGeometry(QRect(220, 510, 261, 41)) self.pb_start.setText("Начать выборку") self.pb_start.clicked.connect(self.do_it_motherFucker) #self.radiobutton = QRadioButton(self.tab) #self.radiobutton.setGeometry(QRect(84, 48, 20, 20)) #self.radiobutton_2 = QRadioButton(self.tab) #self.radiobutton_2.setGeometry(QRect(424, 48, 20, 20)) #self.radiobutton.raise_() #self.radiobutton_2.raise_() self.cb_time.raise_() self.cb_prot.raise_() self.cb_addr.raise_() self.dt_beg.raise_() self.dt_end.raise_() #self.l_input_dir.raise_() #self.l_or.raise_() self.l_input_file.raise_() self.l_transpr.raise_() self.l_netpr.raise_() self.l_beg.raise_() self.l_end.raise_() self.l_name.raise_() self.l_filt.raise_() self.line.raise_() self.line_2.raise_() self.line_3.raise_() #self.le_dir.raise_() self.le_file.raise_() self.le_name.raise_() self.pt_transpr.raise_() self.pt_netpr.raise_() self.pt_addr.raise_() self.pt_log.raise_() self.progressBar.raise_() #self.pb_dir.raise_() self.pb_file.raise_() self.pb_time.raise_() self.pb_transpr.raise_() self.pb_netpr.raise_() self.pb_addr.raise_() self.pb_name.raise_() self.pb_start.raise_() self.setCentralWidget(self.centralwidget) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.tabWidget.addTab(self.tab, "") self.cb_time.clicked['bool'].connect(self.dt_beg.setEnabled) self.cb_time.clicked['bool'].connect(self.dt_end.setEnabled) self.cb_time.clicked['bool'].connect(self.l_beg.setEnabled) self.cb_time.clicked['bool'].connect(self.l_end.setEnabled) self.cb_prot.clicked['bool'].connect(self.l_transpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.l_netpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pt_transpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pt_netpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pb_transpr.setEnabled) self.cb_prot.clicked['bool'].connect(self.pb_netpr.setEnabled) self.cb_addr.clicked['bool'].connect(self.pt_addr.setEnabled) self.cb_addr.clicked['bool'].connect(self.pb_addr.setEnabled) #####------------------------------2_TAB self.tab_2 = QWidget() self.tabWidget.addTab(self.tab_2, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), ("II работа с файлами")) self.l_merge = QLabel(self.tab_2) self.l_merge.setGeometry(QRect(300, 10, 180, 16)) self.l_merge.setText("Объединение файлов") self.l_arch = QLabel(self.tab_2) self.l_arch.setGeometry(QRect(300, 250, 180, 16)) self.l_arch.setText("Архивирование файлов") #self.radiobutton_3 = QRadioButton(self.tab_2) #self.radiobutton_3.setGeometry(QRect(84, 48, 20, 20)) #self.radiobutton_4 = QRadioButton(self.tab_2) #self.radiobutton_4.setGeometry(QRect(424, 48, 20, 20)) #self.l_input_dir2 = QLabel(self.tab_2) #self.l_input_dir2.setGeometry(QRect(102, 50, 180, 15)) #self.l_input_dir2.setText("Выберите директорию с файлами") #self.l_or2 = QLabel(self.tab_2) #self.l_or2.setGeometry(QRect(340, 50, 21, 16)) #self.l_or2.setText("ИЛИ") self.l_input_file2 = QLabel(self.tab_2) self.l_input_file2.setGeometry(QRect(102, 50, 180, 15))#442, 50, 90, 15)) self.l_input_file2.setText("Выберите файлы") self.l_name2 = QLabel(self.tab_2) self.l_name2.setGeometry(QRect(442, 50, 180, 15))#280, 140, 180, 16)) self.l_name2.setText("Куда сохранить результат?") self.l_ciph2 = QLabel(self.tab_2) self.l_ciph2.setGeometry(QRect(84, 298, 180, 15)) self.l_ciph2.setText("Убрать шифрованный трафик") self.l_arch2 = QLabel(self.tab_2) self.l_arch2.setGeometry(QRect(424, 298, 180, 15)) self.l_arch2.setText("Заархивировать файлы") #self.le_dir2 = QLineEdit(self.tab_2) #self.le_dir2.setGeometry(QRect(110, 80, 211, 20)) #self.le_dir2.setEnabled(False) self.le_file2 = QLineEdit(self.tab_2) self.le_file2.setGeometry(QRect(110, 80, 211, 20))#450, 80, 211, 20)) self.le_file2.setReadOnly(True) self.le_name2 = QLineEdit(self.tab_2) self.le_name2.setGeometry(QRect(450, 80, 211, 20))#260, 170, 180, 20)) #self.pb_dir2 = QPushButton(self.tab_2) #self.pb_dir2.setGeometry(QRect(80, 80, 21, 20)) #self.pb_dir2.setIcon(QIcon('допочки\_folder.png')) #self.pb_dir2.clicked.connect(lambda gd: self.get_directory(2)) self.pb_file2 = QPushButton(self.tab_2) self.pb_file2.setGeometry(QRect(80, 80, 21, 20))#420, 80, 21, 20)) self.pb_file2.setIcon(QIcon('допочки\_folder.png')) self.pb_file2.clicked.connect(lambda gf: self.get_files(2)) self.pb_name2 = QPushButton(self.tab_2) self.pb_name2.setGeometry(QRect(420, 80, 21, 20))#230, 170, 21, 20)) self.pb_name2.setIcon(QIcon('допочки\_folder.png')) self.pb_name2.clicked.connect(lambda ed: self.extract_to_directory(2)) self.pb_merge = QPushButton(self.tab_2) self.pb_merge.setGeometry(QRect(270, 170, 160, 20)) self.pb_merge.setText("Объединить") self.pb_merge.clicked.connect(self.merge_it_motherFucker) self.line_4 = QFrame(self.tab_2) self.line_4.setGeometry(QRect(0, 280, 690, 15)) self.line_4.setFrameShape(QFrame.HLine) self.line_4.setFrameShadow(QFrame.Sunken) self.line_5 = QFrame(self.tab_2) self.line_5.setGeometry(QRect(0, 580, 690, 15)) self.line_5.setFrameShape(QFrame.HLine) self.line_5.setFrameShadow(QFrame.Sunken) self.pt_log2 = QPlainTextEdit(self.tab_2) self.pt_log2.setGeometry(QRect(20, 610, 651, 101)) self.pt_log2.setReadOnly(True) self.graphicsView = QGraphicsView(self.tab_2) self.graphicsView.setGeometry(QRect(0, 330, 714, 277)) self.scene = QGraphicsScene() self.graphicsView.setScene(self.scene) self.scene.addPixmap(QPixmap('допочки\_in_working_3.png')) self.l_merge.raise_() self.l_arch.raise_() #self.l_input_dir2.raise_() #self.l_or2.raise_() self.l_input_file2.raise_() self.l_name2.raise_() #self.radiobutton_3.raise_() #self.radiobutton_4.raise_() #self.pb_dir2.raise_() self.pb_file2.raise_() self.pb_name2.raise_() #self.le_dir2.raise_() self.le_file2.raise_() self.le_name2.raise_() self.line_4.raise_() self.line_5.raise_() self.pt_log2.raise_() #####------------------------------2_TAB #####------------------------------3_TAB self.tab_3 = QWidget() self.tabWidget.addTab(self.tab_3, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), ("III Проверка на аномальную активность")) self.tab_3.setEnabled(False) self.l_filt3 = QLabel(self.tab_3) self.l_filt3.setGeometry(QRect(300, 10, 91, 16)) self.l_filt3.setText("Выборка пакетов") self.l_input_file3 = QLabel(self.tab_3) self.l_input_file3.setGeometry(QRect(300, 50, 90, 15)) self.l_input_file3.setText("Выберите файлы") self.pb_file3 = QPushButton(self.tab_3) self.pb_file3.setGeometry(QRect(220, 80, 21, 20)) self.pb_file3.setIcon(QIcon('допочки\_folder.png')) self.pb_file3.clicked.connect(lambda gf: self.get_files(3)) self.le_file3 = QLineEdit(self.tab_3) self.le_file3.setGeometry(QRect(250, 80, 211, 20)) self.le_file3.setReadOnly(True) self.pb_graphy = QPushButton(self.tab_3) self.pb_graphy.setGeometry(QRect(270, 170, 160, 20)) self.pb_graphy.setText("Построить граф") #self.pb_graphy.clicked.connect(self.graph_it) #self.label_6 = QLabel(self.tab_3) #self.pixmap = QPixmap('допочки\_in_working_1.png') #self.label_6.setPixmap(self.pixmap) self.l_filt3.raise_() self.l_input_file3.raise_() self.pb_file3.raise_() self.le_file3.raise_() #####------------------------------3_TAB #####----------------------------IN_WORK self.tab_4 = QWidget() self.tabWidget.addTab(self.tab_4, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), ("...IV visualization...")) self.tab_4.setEnabled(False) self.label_7 = QLabel(self.tab_4) self.pixmap_2 = QPixmap('допочки\_in_working_2.png') self.label_7.setPixmap(self.pixmap_2) #####----------------------------IN_WORK self.tabWidget.setCurrentIndex(0) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), ("I выборка пакетов")) QMetaObject.connectSlotsByName(self) self.show() def closeEvent(self, event): reply = QMessageBox.question(self, 'Ща закроется всё', "Ты чо, реально хочешь выйти?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def to_center(self): qr = self.frameGeometry() qr.moveCenter(QDesktopWidget().availableGeometry().center()) self.move(qr.topLeft()) def get_directory(self, gd): if gd == 1: result = QFileDialog.getExistingDirectory() #self.le_dir.setText(result) self.le_file.setDisabled(True) #self.le_dir.setEnabled(True) #self.radiobutton_2.setChecked(False) #self.radiobutton.setChecked(True) else: result = QFileDialog.getExistingDirectory() #self.le_dir2.setText(result) self.le_file2.setDisabled(True) #self.le_dir2.setEnabled(True) #self.radiobutton_4.setChecked(False) #self.radiobutton_3.setChecked(True) def get_files(self, gf): if gf == 1: result, bullshit = QFileDialog.getOpenFileNames(self, "Выберите pcap-файлы", getcwd(), "files (*.pcap *.pcapng)") #self.le_dir.setDisabled(True) self.le_file.setEnabled(True) #self.radiobutton.setChecked(False) #self.radiobutton_2.setChecked(True) if len(result): self.le_file.setText(", ".join(result)) elif gf == 3: result, bullshit = QFileDialog.getOpenFileNames(self, "Выберите pcap-файлы", getcwd(), "files (*.pcap *.pcapng)") #self.le_dir.setDisabled(True) self.le_file3.setEnabled(True) #self.radiobutton.setChecked(False) #self.radiobutton_2.setChecked(True) if len(result): self.le_file3.setText(", ".join(result)) else: result, bullshit = QFileDialog.getOpenFileNames(self, "Выберите pcap-файлы", getcwd(), "files (*.pcap *.pcapng)") #self.le_dir2.setDisabled(True) self.le_file2.setEnabled(True) #self.radiobutton_3.setChecked(False) #self.radiobutton_4.setChecked(True) if len(result): self.le_file2.setText(", ".join(result)) def date_changed(self, dc): if dc == 1: self.dt_end.setMinimumDateTime(QDateTime(self.dt_beg.dateTime())) else: self.dt_beg.setMaximumDateTime(QDateTime(self.dt_end.dateTime())) def extract_to_directory(self, ed): if ed == 1: result, bullshit =QFileDialog.getSaveFileName(self, "Сохранить файл", getcwd(), "files (*.pcap *.pcapng)") self.le_name.setText(result) else: result, bullshit =QFileDialog.getSaveFileName(self, "Сохранить файл", getcwd(), "files (*.pcap *.pcapng)") self.le_name2.setText(result) def do_it_motherFucker(self): if self.filtering_is_on == 0: #if ((not self.radiobutton.isChecked() and not self.radiobutton_2.isChecked())\ # or (self.radiobutton.isChecked() and self.le_dir.text() == '')\ # or (self.radiobutton_2.isChecked() and self.le_file.text() == ''))\ # and self.le_name.text() == '': if self.le_file.text() == '' and self.le_name.text() == '': self.pt_log.appendPlainText(" " + "Какие файлы обработать? Куда сохранить? Такая неопределённость..") #elif (not self.radiobutton.isChecked() and not self.radiobutton_2.isChecked()) or (self.radiobutton.isChecked() and self.le_dir.text() == '') or (self.radiobutton_2.isChecked() and self.le_file.text() == ''): elif self.le_file.text() == '': self.pt_log.appendPlainText(" " + "Какие файлы обработать?") elif self.le_name.text() == '': self.pt_log.appendPlainText(" " + "Куда сохранить?") else: self.filtering_is_on = 1 # эти пиздецы в идеале нужно заменить на что-нибудь адекватное self.count_for_pr_b = 0 # эти пиздецы в идеале нужно заменить на что-нибудь адекватное self.progressBar.setValue(0) self.pb_start.setText("Остановить выборку") #my_directory = self.le_dir.text() pcap_files_in = self.le_file.text() pcap_file_out = self.le_name.text() per_quest = 0 per_beg = '' per_end = '' prot_quest = 0 net_prot = 0 trans_prot = 0 appl_prot = 0 ## ip_quest = 0 netprot_mass = [] transprot_mass = [] addr_mass = [] if (pcap_file_out.endswith(".pcap") or pcap_file_out.endswith(".pcapng")) == False: pcap_file_out = pcap_file_out + ".pcap" self.pt_log.appendPlainText("Сохранить в:") self.pt_log.appendPlainText(" " + pcap_file_out) #if self.radiobutton.isChecked(): # onlyfiles = [my_directory + '/' + f for f in listdir(my_directory) if # f.endswith(".pcap") or f.endswith(".pcapng") and isfile(join(my_directory, f))] # self.for_pr_b = len(onlyfiles) # # self.pt_log.appendPlainText("Выбрана директория:") # self.pt_log.appendPlainText(" " + self.le_dir.text()) # self.pt_log.appendPlainText("С pcap-файлами:") # for file in onlyfiles: # bullshit, fname = file.rsplit('/', 1) # self.pt_log.appendPlainText(" " + fname) #elif self.radiobutton_2.isChecked(): onlyfiles = pcap_files_in.split(', ') self.for_pr_b = len(onlyfiles) self.pt_log.appendPlainText("Выбраны pcap-файлы:") for file in onlyfiles: self.pt_log.appendPlainText(" " + (file)) if self.cb_addr.isChecked() and self.pt_addr.toPlainText() != '': ip_quest = 1 addr_mass = self.pt_addr.toPlainText().splitlines() if self.cb_time.isChecked(): per_quest = 1 per_beg = self.dt_beg.dateTime() per_end = self.dt_end.dateTime() if self.cb_prot.isChecked(): prot_quest = 1 transprot_mass = self.transprot_mass netprot_mass = self.netprot_mass if self.pt_transpr.toPlainText() != '': trans_prot = 1 if self.pt_netpr.toPlainText() != '': net_prot = 1 #self.radiobutton.setDisabled(True) #self.radiobutton_2.setDisabled(True) #self.l_input_dir.setDisabled(True) #self.l_or.setDisabled(True) self.l_input_file.setDisabled(True) #self.pb_dir.setDisabled(True) self.pb_file.setDisabled(True) #self.le_dir.setDisabled(True) self.le_file.setDisabled(True) self.cb_time.setDisabled(True) self.cb_prot.setDisabled(True) self.cb_addr.setDisabled(True) self.l_transpr.setDisabled(True) self.l_netpr.setDisabled(True) self.l_beg.setDisabled(True) self.l_end.setDisabled(True) self.l_name.setDisabled(True) self.l_filt.setDisabled(True) self.le_name.setDisabled(True) self.dt_beg.setDisabled(True) self.dt_end.setDisabled(True) self.pt_transpr.setDisabled(True) self.pt_netpr.setDisabled(True) self.pt_addr.setDisabled(True) self.pb_time.setDisabled(True) self.pb_transpr.setDisabled(True) self.pb_netpr.setDisabled(True) self.pb_addr.setDisabled(True) self.pb_name.setDisabled(True) self.worker = WorkerThread(onlyfiles, pcap_file_out, per_quest, per_beg, per_end, prot_quest, net_prot, netprot_mass, trans_prot, transprot_mass, appl_prot, ip_quest, addr_mass) self.worker.callback_received.connect(self.append_to_log) self.worker.start() self.pt_log.appendPlainText("") self.pt_log.appendPlainText("В работе:") elif self.filtering_is_on == 1: self.worker.terminate() self.pt_log.appendPlainText("") self.pt_log.appendPlainText("Работа прервана") self.pt_log.appendPlainText("") self.pt_log.appendPlainText("") self.go_to_starting_set() def append_to_log(self, x): self.count_for_pr_b += 1 self.pt_log.appendPlainText("") self.pt_log.appendPlainText(x) self.progressBar.setValue(self.count_for_pr_b * 100 / (self.for_pr_b + 1)) if self.progressBar.value() == 100: self.pt_log.appendPlainText("") self.pt_log.appendPlainText("") self.go_to_starting_set() def go_to_starting_set(self): self.filtering_is_on = 0 self.pb_start.setText("Начать выборку") #self.radiobutton.setDisabled(False) #self.radiobutton_2.setDisabled(False) #self.l_input_dir.setDisabled(False) #self.l_or.setDisabled(False) self.l_input_file.setDisabled(False) #self.pb_dir.setDisabled(False) self.pb_file.setDisabled(False) #self.le_dir.setDisabled(False) self.le_file.setDisabled(False) self.cb_time.setDisabled(False) self.cb_prot.setDisabled(False) self.cb_addr.setDisabled(False) self.l_name.setDisabled(False) self.l_filt.setDisabled(False) self.le_name.setDisabled(False) self.pb_name.setDisabled(False) if self.cb_time.isChecked(): self.dt_beg.setEnabled(True) self.dt_end.setEnabled(True) self.l_beg.setEnabled(True) self.l_end.setEnabled(True) if self.cb_prot.isChecked(): self.l_transpr.setEnabled(True) self.l_netpr.setEnabled(True) self.pt_transpr.setEnabled(True) self.pt_netpr.setEnabled(True) self.pb_transpr.setEnabled(True) self.pb_netpr.setEnabled(True) if self.cb_addr.isChecked(): self.pt_addr.setEnabled(True) self.pb_addr.setEnabled(True) def merge_it_motherFucker(self): #if self.radiobutton_3.isChecked(): # self.pt_log2.appendPlainText("Выбрана директория с pcap-файлами:") # self.pt_log2.appendPlainText(" " + self.le_dir2.text()) # self.pt_log2.appendPlainText('Просматриваем "{}"...'.format(self.le_dir2.text())) # onlyfiles = [self.le_dir2.text() + '/' + f for f in listdir(self.le_dir2.text()) if # f.endswith(".pcap") or f.endswith(".pcapng") and isfile(join(self.le_dir2.text(), f))] # self.pt_log2.appendPlainText(str(onlyfiles)) #elif self.radiobutton_4.isChecked(): self.pt_log2.appendPlainText("Выбраны pcap-файлы:") self.pt_log2.appendPlainText(" " + self.le_file2.text()) onlyfiles = self.le_file2.text().split(', ') self.pt_log2.appendPlainText('Работаем с "{}"...'.format(onlyfiles)) merge_file_out = self.le_name2.text() if (merge_file_out.endswith(".pcap") or merge_file_out.endswith(".pcapng")) == False: merge_file_out = merge_file_out + ".pcap" self.pt_log2.appendPlainText("Сохранить в:") self.pt_log2.appendPlainText(" " + merge_file_out) self.pt_log2.appendPlainText("") merge.mergecap(onlyfiles, merge_file_out)
class CountdownWidget(QWidget): """Define custom widget as countdown control panel.""" def __init__(self, ctrl, parent=None): """Init completer.""" super().__init__(parent) self.controller = ctrl self.createLayout() self.loadSettings() self.connect() def createLayout(self): """Create widget to control the countdown browser source.""" layout = QGridLayout() self.rb_static = QRadioButton(_("Static Countdown to date:"), self) layout.addWidget(self.rb_static, 0, 0) self.rb_dynamic = QRadioButton(_("Dynamic Countdown duration:"), self) self.rb_dynamic.setChecked(True) self.rb_dynamic.toggled.connect(self.toggleRadio) layout.addWidget(self.rb_dynamic, 1, 0) self.te_datetime = QDateTimeEdit() self.te_datetime.setCalendarPopup(True) self.te_datetime.setContextMenuPolicy(Qt.CustomContextMenu) self.te_datetime.customContextMenuRequested.connect( self.openDateTimeMenu) layout.addWidget(self.te_datetime, 0, 1) self.te_duration = QTimeEdit() self.te_duration.setDisplayFormat("HH 'h' mm 'm' ss 's'") self.te_duration.setContextMenuPolicy(Qt.CustomContextMenu) self.te_duration.customContextMenuRequested.connect( self.openDurationMenu) layout.addWidget(self.te_duration, 1, 1) self.event_label = QLabel(' ' + _('Event description:')) layout.addWidget(self.event_label, 0, 2) self.le_desc = QLineEdit() self.le_desc.setAlignment(Qt.AlignCenter) layout.addWidget(self.le_desc, 0, 3, 1, 2) self.cb_restart = QCheckBox( _('Restart countdown when source becomes active')) layout.addWidget(self.cb_restart, 1, 2, 1, 2) self.pb_start = QPushButton(" " + _('Start Countdown') + " ") layout.addWidget(self.pb_start, 1, 4) layout.setColumnStretch(2, 1) layout.setColumnStretch(3, 2) self.setLayout(layout) def openDateTimeMenu(self, position): """Open menu to set date to today.""" menu = QMenu() act1 = QAction(_("Set Today")) act1.triggered.connect(self.setToday) menu.addAction(act1) menu.exec_(QCursor.pos()) def openDurationMenu(self, position): """Open menu to set the duration.""" menu = QMenu() for duration in [15, 10, 5, 3, 1]: act = QAction(_("Set {} min").format(duration), menu) act.triggered.connect( lambda x, duration=duration: self.setDuration(duration)) menu.addAction(act) menu.exec_(QCursor.pos()) def setToday(self): """Set date to today.""" today = QDateTime.currentDateTime() today.setTime(self.te_datetime.time()) self.te_datetime.setDateTime(today) def setFromTimestamp(self, timestamp): """Set time and date based on timestamp.""" self.te_datetime.setDateTime(QDateTime.fromTime_t(int(timestamp))) def setDuration(self, duration): """Set the duration.""" self.te_duration.setTime(QTime(0, duration, 0)) def toggleRadio(self): """Toggle radio buttion.""" static = self.rb_static.isChecked() self.te_datetime.setEnabled(static) self.te_duration.setEnabled(not static) self.cb_restart.setEnabled(not static) self.pb_start.setEnabled(not static) def loadSettings(self): """Load data from settings.""" static = scctool.settings.config.parser.getboolean( "Countdown", "static") if static: self.rb_static.setChecked(True) else: self.rb_dynamic.setChecked(True) description = scctool.settings.config.parser.get( 'Countdown', 'description') self.le_desc.setText(description.strip()) restart = scctool.settings.config.parser.getboolean( "Countdown", "restart") self.cb_restart.setChecked(restart) duration = QTime() string = scctool.settings.config.parser.get('Countdown', 'duration').strip() duration = QTime.fromString(string, 'HH:mm:ss') self.te_duration.setTime(duration) string = scctool.settings.config.parser.get('Countdown', 'datetime').strip() datetime = QDateTime.fromString(string, 'yyyy-MM-dd HH:mm') self.te_datetime.setDateTime(datetime) def connect(self): """Connect all form elements.""" self.le_desc.textChanged.connect(self.changed_description) self.cb_restart.toggled.connect(self.changed_restart) self.te_datetime.dateTimeChanged.connect(self.changed_datetime) self.te_duration.timeChanged.connect(self.changed_duration) self.rb_static.toggled.connect(self.changed_static) self.pb_start.pressed.connect(self.start_pressed) def changed_description(self): """Change the description.""" desc = self.le_desc.text().strip() scctool.settings.config.parser.set('Countdown', 'description', desc) self.controller.websocketThread.sendData2Path('countdown', "DESC", desc) def changed_restart(self): """Handle change of restart option.""" restart = self.cb_restart.isChecked() scctool.settings.config.parser.set('Countdown', 'restart', str(restart)) self.controller.websocketThread.sendData2Path('countdown', "RESTART", restart) def changed_datetime(self, time): """Handle change of datetime.""" datetime = time.toString('yyyy-MM-dd HH:mm') scctool.settings.config.parser.set('Countdown', 'datetime', datetime) self.sendData() def changed_duration(self, time): """Handle change of duration.""" duration = time.toString('HH:mm:ss') scctool.settings.config.parser.set('Countdown', 'duration', duration) self.sendData() def changed_static(self): """Handle change of static/dynamic.""" static = self.rb_static.isChecked() scctool.settings.config.parser.set('Countdown', 'static', str(static)) self.sendData() def start_pressed(self): """Handle press of the start button.""" self.controller.websocketThread.sendData2Path('countdown', 'START') def sendData(self): """Send the data to the websocket.""" self.controller.websocketThread.sendData2Path( 'countdown', "DATA", self.controller.websocketThread.getCountdownData())
class Setting(QWidget, Ui_widget_setting): signal_core_number = pyqtSignal(int) signal_suspend_status = pyqtSignal(bool) signal_waiting_min = pyqtSignal(int) signal_schedule_status = pyqtSignal(bool) signal_cancel_plan = pyqtSignal(str) signal_change_language = pyqtSignal(str) def __init__(self, suspend, cores, schedule_status, waiting_min, language): super().__init__() self.setupUi(self) # ----------init variable------------ self.suspend = suspend self.cores = cores self.schedule_status = schedule_status self.waiting_min = waiting_min self.language = language self.language_list = ['English', 'Chinese'] # ----------init widget-------------- self.label_suspend = QTreeWidgetItem() self.checkbox_suspend = QCheckBox() self.label_cores = QTreeWidgetItem() self.edit_cores = QSpinBox() self.label_plan = QTreeWidgetItem() self.edit_plan_datetime = QDateTimeEdit() self.label_about = QTreeWidgetItem() self.label_language = QTreeWidgetItem() self.combobox_lauguage = QComboBox() # -----------init function---------------- self.ui_set() self.btn() self.init_data_show() self.self_translate(language) self.show() def btn(self): self.tree_setting.itemClicked.connect(self.effect_expand) self.tree_setting.itemChanged.connect(self.enable_schedule) self.combobox_lauguage.activated.connect(self.choose_language) self.checkbox_suspend.stateChanged.connect(self.change_suspend_status) def ui_set(self): # style self.setStyleSheet( "QSpinBox{border:1.5px solid #778899;border-radius:4px; padding:2px 2px}" "QDateTimeEdit{border:1.5px solid #778899;border-radius:4px; padding:2px 2px}" ) self.tree_setting.setColumnWidth(0, 180) self.tree_setting.expandItem(self.tree_setting.topLevelItem(0)) self.tree_setting.topLevelItem(1).setCheckState(1, 0) self.edit_cores.setMaximumSize(50, 25) self.edit_cores.setContentsMargins(0, 4, 0, 0) self.edit_cores.setMinimum(1) self.edit_cores.setMaximum(132) self.label_plan.setDisabled(True) self.edit_plan_datetime.setMaximumSize(135, 28) self.edit_plan_datetime.setDisabled(True) self.combobox_lauguage.setMaximumSize(135, 28) self.combobox_lauguage.addItems(self.language_list) self.combobox_lauguage.setCurrentText(self.language) # function self.add_tree_item(0, self.label_suspend, "暂停队列", self.checkbox_suspend) self.add_tree_item(0, self.label_cores, "使用核数", self.edit_cores) self.add_tree_item(1, self.label_plan, "计划启动于", self.edit_plan_datetime) self.add_tree_item(2, self.label_language, "语言选择", self.combobox_lauguage) def add_tree_item(self, top_level_index, label, label_name, input_edit): label.setText(0, label_name) self.tree_setting.topLevelItem(top_level_index).addChild(label) self.tree_setting.setItemWidget(label, 1, input_edit) def effect_expand(self, item, column): index = self.tree_setting.indexOfTopLevelItem(item) if index >= 0: if item.isExpanded(): item.setExpanded(False) else: item.setExpanded(True) def enable_schedule(self, item, column): index = self.tree_setting.indexOfTopLevelItem(item) if index == 1: check_state = item.checkState(column) self.schedule_status = bool(check_state) self.label_plan.setDisabled(2 - check_state) self.edit_plan_datetime.setEnabled(check_state) item.setExpanded(2 - check_state) self.reset_date_edit() self.suspend = self.checkbox_suspend.checkState() self.checkbox_suspend.setCheckState(self.suspend + check_state) self.checkbox_suspend.setDisabled(check_state) def init_data_show(self): self.edit_cores.setValue(self.cores) self.checkbox_suspend.setCheckState(self.suspend * 2) if self.schedule_status: self.tree_setting.topLevelItem(1).setCheckState(1, 2) self.label_plan.setDisabled(False) self.edit_plan_datetime.setEnabled(True) self.tree_setting.topLevelItem(1).setExpanded(True) waiting_seconds = self.waiting_min * 60 self.edit_plan_datetime.setDisplayFormat("yyyy/MM/dd HH:mm") self.edit_plan_datetime.setDateTime( QDateTime.currentDateTime().addSecs(waiting_seconds)) else: self.reset_date_edit() def reset_date_edit(self): self.edit_plan_datetime.setDisplayFormat("yyyy/MM/dd HH:mm") self.edit_plan_datetime.setDateTime(QDateTime.currentDateTime()) self.edit_plan_datetime.setMinimumDateTime(QDateTime.currentDateTime()) self.edit_plan_datetime.setMaximumDateTime( QDateTime.currentDateTime().addDays(5)) self.edit_plan_datetime.setCalendarPopup(True) def change_suspend_status(self, status): self.suspend = bool(status) def plan_start(self): curr_time = QDateTime.currentSecsSinceEpoch() schedule_time = self.edit_plan_datetime.dateTime().toSecsSinceEpoch() self.waiting_min = int(round((schedule_time - curr_time) / 60, 0)) print('waiting min', self.waiting_min) self.signal_waiting_min.emit(self.waiting_min) def choose_language(self): language = self.combobox_lauguage.currentText() self.signal_change_language.emit(language) self.self_translate(language) def self_translate(self, language): if language == 'English': self.label_suspend.setText(0, 'Suspend next') self.label_cores.setText(0, 'Threads number') self.label_plan.setText(0, 'Scheduled in') self.label_language.setText(0, 'Language') else: self.label_suspend.setText(0, "暂停队列") self.label_cores.setText(0, "使用核数") self.label_plan.setText(0, "计划启动于") self.label_language.setText(0, "语言选择") self.retranslateUi(self) def closeEvent(self, event): self.cores = self.edit_cores.value() suspend_status = self.checkbox_suspend.checkState() self.signal_core_number.emit(self.cores) self.signal_schedule_status.emit(self.schedule_status) if self.schedule_status: self.plan_start() else: self.signal_cancel_plan.emit(' ') self.signal_suspend_status.emit(bool(suspend_status)) self.close()
class MyWindow(QMainWindow): def __init__(self, commodity): super().__init__() self.commodityData = commodity self.kucundandata = KuCunDan(commodity) self.yingye = YingYeEData.YingYeE(commodity) self.initUI() self.show() def Show(self): if self.commodityData.model.tableName() != "yingyee": self.commodityData.model.setTable("yingyee") self.commodityData.model.select() self.yingye.show() def ShowNotPayCustomer(self): """ 点击listwidget的item时被调用 显示未付款用户 :return: """ select = self.listwidget.currentItem().text().split() kehu = self.kucundandata.Find("name", select[0], "==") if kehu: alldata = self.kucundandata.getData("date", select[1] + " " + select[2], "==") self.FillTable(alldata[0]) def FillTable(self, data): """ 此函数用于将数据库中的未付款客户数据展示在界面上,被ShowNotPayCustomer调用 :param data: :return: """ a = data[0].split() self.dateedit.setText(a[0]) self.customer.setText(data[1]) self.danjubianhao.setText(data[2]) self.chuhuocangku.setText(data[3]) self.customertel.setText(data[4]) self.address.setText(data[5]) for i in range(6, 11): self.beizhulineedits[i - 6].setText(data[i]) index = 11 for i in range(10): if data[(index - 11) % 8 == 0] != "": for j in range(8): self.lineedits[i][j].setText(data[index]) index += 1 else: break def LineEditsEditAble(self, Bool): """ 设置表格是否可以编辑,在查看未付款用户下不可编辑,打开或关闭都会清空单据 :param Bool: :return: """ self.dateedit.setReadOnly(Bool) self.customer.setReadOnly(Bool) self.danjubianhao.setReadOnly(Bool) self.chuhuocangku.setReadOnly(Bool) self.customertel.setReadOnly(Bool) self.address.setReadOnly(Bool) for i in range(6, 11): self.beizhulineedits[i - 6].setReadOnly(Bool) for i in range(10): for j in range(8): self.lineedits[i][j].setReadOnly(Bool) self.dateedit.setText("") self.customer.setText("") self.danjubianhao.setText("") self.chuhuocangku.setText("") self.customertel.setText("") self.address.setText("") for i in range(6, 11): self.beizhulineedits[i - 6].setText("") for i in range(10): for j in range(8): self.lineedits[i][j].setText("") def getcheckrange(self): """ 获得查找未付款客户的范围 :return: """ self.datetimemax = QDateTimeEdit(QDateTime.currentDateTime(), self) # 3 self.datetimemax.dateTimeChanged.connect( lambda: print(self.datetimemax.text())) self.datetimemax.setCalendarPopup(True) self.datetimemin = QDateTimeEdit(QDateTime.currentDateTime(), self) # 3 self.datetimemin.dateTimeChanged.connect( lambda: print(self.datetimemin.text())) self.datetimemin.setCalendarPopup(True) #self.datetimemin.setReadOnly(True) #self.datetimemax.setReadOnly(True) groupbox = QGroupBox("查看模式选择", self.listframe) min = QLabel("起始日期:") max = QLabel("终止日期:") kehulabel = QLabel("客户名称:") hlayout1 = QHBoxLayout() hlayout2 = QHBoxLayout() hlayout1.addStretch(1) hlayout2.addStretch(1) hlayout1.addWidget(min) hlayout1.addWidget(self.datetimemin) hlayout2.addWidget(max) hlayout2.addWidget(self.datetimemax) hlayout3 = QHBoxLayout() hlayout3.addStretch(1) hlayout3.addWidget(kehulabel) self.kehucheckbox = QCheckBox("按客户查找") self.datecheckbox = QCheckBox("按日期查找") self.findcustomer = QLineEdit("") hlayout3.addWidget(self.findcustomer) #self.findcustomer.setReadOnly(True) #self.finddate = QLineEdit() vlayout = QVBoxLayout() vlayout.addStretch(1) vlayout.addWidget(self.kehucheckbox) vlayout.addLayout(hlayout3) vlayout.addWidget(self.datecheckbox) vlayout.addLayout(hlayout1) vlayout.addLayout(hlayout2) groupbox.setLayout(vlayout) self.findbutton = QPushButton(groupbox) self.findbutton.setGeometry(200, 15, 35, 35) self.findbutton.setIcon(QIcon("find.jpg")) #self.findbutton.setStyleSheet("border-width:30px") #self.findbutton.autoFillBackground() self.findbutton.setToolTip("查找") self.findbutton.clicked.connect(self.ChooseFindWay) def ChooseFindWay(self): if self.kehucheckbox.isChecked() and not self.datecheckbox.isChecked(): if self.findcustomer.text() != "": self.listwidget.clear() print("1") self.AddListItem( self.kucundandata.getData("name", self.findcustomer.text(), "==")) print("哈哈哈哈哈哈哈哈") elif self.kehucheckbox.isChecked() and self.datecheckbox.isChecked(): dataname = self.kucundandata.getData("name", self.findcustomer.text(), "==") adddata = [] if dataname == None: QMessageBox.information(self, "注意", "未发现该客户") return min = (self.datetimemin.text().split())[0] max = (self.datetimemax.text().split())[0] if min > max: QMessageBox.warning(self, "错误提示", "请输入正确的时间范围") return else: min += " 00:00:00" max += " 23:59:59" data1 = self.kucundandata.getData("date", min, ">=") data2 = self.kucundandata.getData("date", max, "<=") if data1 != None and data2 != None: for data in data1: if data in data2: if data in dataname: adddata.append(data) self.listwidget.clear() self.AddListItem(adddata) elif self.datecheckbox.isChecked( ) and not self.kehucheckbox.isChecked(): min = (self.datetimemin.text().split())[0] max = (self.datetimemax.text().split())[0] if min > max: QMessageBox.warning(self, "错误提示", "请输入正确的时间范围") return else: min += " 00:00:00" max += " 23:59:59" data1 = self.kucundandata.getData("date", min, ">=") data2 = self.kucundandata.getData("date", max, "<=") self.listwidget.clear() if data1 != None and data2 != None: data3 = [] for data in data1: if data in data2: data3.append(data) print("-----", data3) if len(data3) != 0: self.AddListItem(data3) else: year = datetime.date.today().year + 1 self.AddListItem(self.kucundandata.getData('date', str(year), "<=")) QMessageBox.information(self, "提示", "请勾选查询方式") def deletecustomer(self): """ 删除未付款客户,此处还需要将此客户从数据库中删除,并将未付款状态修改成已付款状态 :return: """ result = QMessageBox.information(self, "提示", "确定删除此未付客户?", QMessageBox.Yes | QMessageBox.No) if result == QMessageBox.Yes: date = self.listwidget.currentItem().text().split() target = date[1] + " " + date[2] self.kucundandata.RemoveData("date", target, "==") self.yingye.ReviseStatus(target, "已付款") self.listwidget.takeItem(self.listwidget.currentIndex().row()) def AddListItem(self, data): """ :param data: data 是数据库中getData获得的数据,是一个二位列表 :return: """ if data == None: QMessageBox.information(self, "查找结果", "未发现该客户") return print(data) print("AddListItem") self.listwidget.clear() listdata = [ data[i][1] + " " + data[i][0] for i in range(0, len(data)) ] self.listwidget.addItems(listdata) def initUI(self): self.setGeometry(200, 200, 1000, 800) self.setStyleSheet("background-color:rgb(255,255,255,255)") self.setWindowIcon(QIcon("n.jpg")) self.setWindowTitle("库存单") self.listframe = QFrame(self) self.listwidget = QListWidget(self.listframe) self.listwidget.setGeometry(0, 175, 300, 455) #self.listwidget.addItems(["黄小泽 2018/11/25 16:32:04","小黄 2018-10-30","小泽 2018-9-31"]) self.listframe.setVisible(False) self.listframe.setGeometry(950, 0, 300, 800) #self.listframe.setStyleSheet("background-color:blue") self.listwidget.itemClicked.connect(self.ShowNotPayCustomer) self.listwidget.itemDoubleClicked.connect(self.deletecustomer) self.closelistbutton = QPushButton("关闭", self.listframe) self.closelistbutton.setGeometry(100, 650, 50, 25) self.closelistbutton.clicked.connect(lambda: self.ShowNotPay(False)) self.getcheckrange() self.TableXY() label = QLabel(self) label.setFont(QFont("微软雅黑", 9, QFont.Bold)) label.setGeometry(self.Cell[0][8].x + 155, self.Cell[0][8].y - 115, 29, 625) label.setText( "白\n联\n存\n根\n\n红\n联\n收\n款\n签\n名\n作\n欠\n款\n依\n据\n \n蓝\n联\n仓\n库\n \n黄\n联\n客\n户" ) self.Write() self.ChoosePrintColor() self.LineEdit() def ShowNotPay(self, a): """ 显示未付款客户,以及打开数据库的'sh'或'Kucun'table :param a: bool :return: """ if a == False: #填写模式 print("close") self.commodityData.model.setTable("sh") self.setGeometry(200, 200, 1000, 800) self.listframe.setVisible(False) self.LineEditsEditAble(False) self.groupbox2.setVisible(True) self.AddinDatabase = True #定义这个变量的目的是为了传递此时是否是处于查看模式,以便阻止将数据存入数据库 self.listwidget.clear() else: #查看模式 self.commodityData.model.setTable("Kucun") self.setGeometry(200, 200, 1400, 800) self.listframe.setVisible(True) self.LineEditsEditAble(True) self.groupbox2.setVisible(False) year = datetime.date.today().year + 1 self.AddinDatabase = False self.AddListItem(self.kucundandata.getData('date', str(year), "<=")) def ChoosePrintColor(self): self.printer = QPrinter(QPrinter.HighResolution) self.printerbutton = QPushButton("打印", self) self.printerbutton.setStyleSheet( "background-color:rgb(240,128,128,250)") self.printerbutton.setGeometry(200, 650, 50, 50) self.printerbutton.clicked.connect(self.Print) self.checkpay = QPushButton("查看未付款", self) self.checkpay.setStyleSheet("background-color:rgb(240,128,128,250)") self.checkpay.clicked.connect(lambda: self.ShowNotPay(True)) self.checkpay.setGeometry(300, 650, 100, 50) self.colorlabel = QLabel(self) self.colorlabel.setGeometry(0, 0, 940, 630) self.colorlabel.setFrameShape(QFrame.Box) self.colorlabel.setStyleSheet("background-color:rgb(255,0,0,0)") self.redcheckbutton = QRadioButton("红色(客户)") self.whitecheckbutton = QRadioButton("白色(存根)") self.yellowcheckbutton = QRadioButton("黄色(会计)") self.bluecheckbutton = QRadioButton("蓝色(回单)") self.whitecheckbutton.setChecked(True) frame = QFrame(self) frame.setGeometry(700, 630, 120, 140) vlayout = QVBoxLayout() vlayout.addWidget(self.whitecheckbutton) vlayout.addWidget(self.yellowcheckbutton) vlayout.addWidget(self.bluecheckbutton) vlayout.addWidget(self.redcheckbutton) vlayout.addStretch(1) groupbox1 = QGroupBox("颜色", frame) groupbox1.setLayout(vlayout) self.yifu = QRadioButton("已付款") self.weifu = QRadioButton("未付款") vlayout1 = QVBoxLayout() vlayout1.addStretch(1) vlayout1.addWidget(self.yifu) vlayout1.addWidget(self.weifu) self.groupbox2 = QGroupBox("付款情况", self) self.groupbox2.setLayout(vlayout1) self.groupbox2.setGeometry(570, 630, 120, 90) self.yifu.toggled.connect(self.addcustomer) self.weifu.toggled.connect(self.addcustomer) def getYingYeEData(self, status): data = [] if self.weifu.isChecked(): data.append(self.yingyeedate) #确保该客户与未付款库存单的日期一致 else: data.append(self.dateedit.text() + datetime.datetime.now().strftime(' %H:%M:%S')) data.append(self.customer.text()) data.append(self.sumlabel.text()) data.append(status) print(data) return data def CheckTable(self): if self.customer.text()=="" or self.danjubianhao.text()=="" \ or self.chuhuocangku.text()=="" or self.customertel.text()=="" or self.address.text()=="" or self.dateedit.text()=="": QMessageBox.warning(self, "注意", "请将库存单信息填完整") return False for i in range(4): if self.beizhulineedits[i].text() == "": QMessageBox.warning(self, "注意", "请将库存单信息填完整") return False return True def getnotpaydata(self): """ 次函数用于获得未付款的数据,便于存于数据库 :return: """ data = [] data.append( self.dateedit.text() + datetime.datetime.now().strftime(' %H:%M:%S')) # 需要加上本地时间保证订单唯一性 self.yingyeedate = data[0] data.append(self.customer.text()) data.append(self.danjubianhao.text()) data.append(self.chuhuocangku.text()) data.append(self.customertel.text()) data.append(self.address.text()) for i in range(5): data.append(self.beizhulineedits[i].text()) for i in range(10): for j in range(8): data.append(self.lineedits[i][j].text()) return data def addcustomer(self): if self.yifu.isChecked(): print("已付款") else: print("未付款") def filltable(self): """ 填写表格的数量和单价时自动补全 :return: None """ heji = 0 amount = 0 print("func:filltable") for i in range(10): if self.lineedits[i][4].text() != "" and self.lineedits[i][5].text( ) != "": total = float(self.lineedits[i][4].text()) * float( self.lineedits[i][5].text()) heji += total amount += float(self.lineedits[i][4].text()) self.lineedits[i][6].setText(str(total)) else: self.lineedits[i][6].setText("") if heji != 0: h = str(int(heji * 100)) change = "" print(h) for i in range(1, len(h) + 1): t = lower_to_upper[h[-i]] + title2[-i] change = t + change self.hejilabel.setText(change) self.amountlabel.setText(str(amount)) self.sumlabel.setText(str(heji)) else: self.hejilabel.setText("") self.amountlabel.setText("") self.sumlabel.setText("") def CheckData(self): """ 填写表格的编号时自动补全 :return: """ print("func:CheckData") for i in range(10): if self.commodityData.Find(self.lineedits[i][0].text()): k = self.commodityData.getData(self.lineedits[i][0].text()) for j in range(1, 3): self.lineedits[i][j].setText(k[j]) def LineEdit(self): """ 定义表格的lineedit对象 :return: """ self.lineedits = [[QLineEdit(self) for col in range(8)] for row in range(10)] for i in range(10): for j in range(8): self.lineedits[i][j].setGeometry( self.Cell[i + 1][j + 1].x, self.Cell[i + 1][j + 1].y, self.Cell[i + 1][j + 1].width, self.Cell[i + 1][j + 1].height) self.lineedits[i][j].setStyleSheet( "background-color:rgb(0,0,0,0)") self.lineedits[i][j].setFrame(False) if j == 4 or j == 5: self.lineedits[i][j].textChanged.connect(self.filltable) elif j == 0: self.lineedits[i][j].textChanged.connect(self.CheckData) self.beizhulineedits = [QLineEdit(self) for i in range(5)] for i in range(5): self.beizhulineedits[i].setStyleSheet("background:rgb(0,0,0,0)") self.beizhulineedits[i].setFrame(QFrame.NoFrame) self.beizhulineedits[i].setFont(QFont("微软雅黑", 9, QFont.Bold)) if i == 0: self.beizhulineedits[i].setGeometry(self.beizhuxy[i].x + 50, self.beizhuxy[i].y - 20, 100, 30) elif i < 4 and i > 0: self.beizhulineedits[i].setGeometry(self.beizhuxy[i].x + 70, self.beizhuxy[i].y - 20, 100, 30) else: self.beizhulineedits[i].setGeometry(self.beizhuxy[i].x + 170, self.beizhuxy[i].y - 20, 60, 30) self.dateedit = QLineEdit(self) self.dateedit.setFrame(QFrame.NoFrame) self.dateedit.setStyleSheet("background-color:rgb(0,0,0,0)") self.dateedit.setGeometry(self.Cell[0][8].x - 20, self.Cell[0][2].y - 2 * self.height - 28, 190, 25) self.danjubianhao = QLineEdit(self) self.danjubianhao.setFrame(QFrame.NoFrame) self.danjubianhao.setStyleSheet("background-color:rgb(0,0,0,0)") self.danjubianhao.setGeometry(self.Cell[0][8].x - 20, self.Cell[0][2].y - 2 * self.height, 190, 25) self.chuhuocangku = QLineEdit(self) self.chuhuocangku.setFrame(QFrame.NoFrame) self.chuhuocangku.setStyleSheet("background-color:rgb(0,0,0,0)") self.chuhuocangku.setGeometry(self.Cell[0][0].x + 80, self.Cell[0][0].y - 50, 220, 25) self.customertel = QLineEdit(self) self.customertel.setFrame(QFrame.NoFrame) self.customertel.setStyleSheet("background-color:rgb(0,0,0,0)") self.customertel.setGeometry(self.Cell[0][0].x + 80, self.Cell[0][0].y - 25, 220, 25) self.customer = QLineEdit(self) self.customer.setFrame(QFrame.NoFrame) self.customer.setStyleSheet("background-color:rgb(0,0,0,0)") self.customer.setGeometry(self.Cell[0][3].x + 45, self.Cell[0][3].y - 50, 200, 25) self.address = QLineEdit(self) self.address.setFrame(QFrame.NoFrame) self.address.setStyleSheet("background-color:rgb(0,0,0,0)") self.address.setGeometry(self.Cell[0][3].x + 45, self.Cell[0][3].y - 25, 300, 25) def TableXY(self): """ 定义表格的单元格的长宽 :return: """ self.x = 10 self.y = 125 self.height = 32 self.Cell = [] self.colwidth = { 1: 32, 2: 80, 3: 200, 4: 50, 5: 150, 6: 80, 7: 80, 8: 80, 9: 150 } for i in range(11): l = [] for j in range(9): x = 0 for z in range(j): x += self.colwidth[z + 1] l.append( Cell_Set(x + self.x, self.height * i + self.y, self.colwidth[j + 1], self.height)) self.Cell.append(l) self.zhidan = Cell_Set(self.Cell[10][0].x + 10, self.Cell[10][0].y + 175, 0, 0) self.jingshouren = Cell_Set(self.Cell[10][0].x + 170, self.Cell[10][0].y + 175, 0, 0) self.shoukuangren = Cell_Set(self.Cell[10][0].x + 340, self.Cell[10][0].y + 175, 0, 0) self.fahuoren = Cell_Set(self.Cell[10][0].x + 510, self.Cell[10][0].y + 175, 0, 0) self.kehu = Cell_Set(self.Cell[10][0].x + 700, self.Cell[10][0].y + 175, 0, 0) self.beizhuxy = [ self.zhidan, self.jingshouren, self.shoukuangren, self.fahuoren, self.kehu ] def Write(self): """ 在屏幕上画上库存单合计及以下的内容 :return: """ self.jiaoyi = QLabel(self) self.jiaoyi.setFont(QFont("微软雅黑", 10, QFont.Bold)) self.jiaoyi.setGeometry(self.Cell[10][0].x, self.Cell[10][0].y + 62, 890, 97) self.jiaoyi.setText( "交易协议:1.客户收货时请当面核对数量、质量,如有质量问题请于签收后三天内提出异议,超期通知我司将不予处理。\n" "2.*****价差损失负责,对所造成的期待利益、下家损失、商誉损失均不承担责任。" "3.此单作为买卖双方****合同,\n*****************买方必须在当天内付清贷款,逾期每天按总金额1%加收违约金。\n" ) self.jiaoyi.setStyleSheet("background-color:rgb(0,0,0,0)") beizu = QLabel("备注:", self) beizu.setFont(QFont("微软雅黑", 12, QFont.Bold)) beizu.setGeometry(self.Cell[10][0].x, self.Cell[10][0].y + 129, 50, 25) beizu.setStyleSheet("background-color:rgb(0,0,0,0)") width1 = 0 width2 = 0 for i in range(7): if i < 5: width1 += self.Cell[0][i].width else: width2 += self.Cell[0][i].width label2 = QLabel("合计:", self) label2.setFont(QFont("微软雅黑", 10, QFont.Bold)) label2.setGeometry(self.Cell[10][0].x, self.Cell[10][0].y + self.height, width1 + 1, self.height) label2.setFrameShape(QFrame.Box) self.amountlabel = QLabel(self) self.amountlabel.setGeometry(self.Cell[10][5].x, self.Cell[10][0].y + self.height, width2 + 1, self.height) self.amountlabel.setFrameShape(QFrame.Box) self.sumlabel = QLabel(self) self.sumlabel.setGeometry(self.Cell[10][7].x, self.Cell[10][0].y + self.height, self.Cell[10][7].width + 1, self.height) self.sumlabel.setFrameShape(QFrame.Box) label5 = QLabel(self) label5.setGeometry(self.Cell[10][8].x, self.Cell[10][0].y + self.height, self.Cell[10][8].width + 1, self.height) label5.setFrameShape(QFrame.Box) label2.setStyleSheet("background-color:rgb(255,0,0,0)") label5.setStyleSheet("background-color:rgb(255,0,0,0)") self.hejilabel = QLabel(self) self.hejilabel.setGeometry(self.Cell[10][0].x + 60, self.Cell[10][0].y + self.height, width1 + 1, self.height) self.hejilabel.setStyleSheet("background-color:rgb(255,0,0,0)") self.amountlabel.setStyleSheet("background-color:rgb(255,0,0,0)") self.sumlabel.setStyleSheet("background-color:rgb(255,0,0,0)") def paintEvent(self, event): painter = QPainter(self) self.DrawReceipt(painter) def DrawReceipt(self, painter): title = "东莞市天航五金制品有限公司 销售出库单" address = "地址:东莞市东城区温塘红槟榔东日仓库3号" tel = "电话:0769-23831842 81805899 传真:0769-27205560" title1 = [ "No.", "商品编号", " 商 品 名 称 ", "单位", " 规 格 ", " 数 量 ", " 单 价 ", " 金 额 ", " 备 注 " ] for i in range(11): for j in range(9): painter.drawRect(self.Cell[i][j].x, self.Cell[i][j].y, self.Cell[i][j].width, self.Cell[i][j].height) #填入文字 painter.setFont(QFont("微软雅黑", 16, QFont.Bold)) painter.drawText( QRect(self.Cell[0][2].x - 6, self.Cell[0][2].y - 3 * self.height - 25, 550, 40), Qt.AlignCenter, title) painter.setFont(QFont("微软雅黑", 10, QFont.Bold)) painter.drawText( QRect(self.Cell[0][2].x + 50, self.Cell[0][2].y - 2 * self.height - 33, 350, 40), Qt.AlignCenter, address) painter.drawText( QRect(self.Cell[0][8].x - 100, self.Cell[0][2].y - 2 * self.height - 35, 100, 40), Qt.AlignCenter, "销售日期:") painter.drawText( QRect(self.Cell[0][2].x - 3, self.Cell[0][2].y - 2 * self.height - 14, 500, 40), Qt.AlignCenter, tel) painter.drawText( QRect(self.Cell[0][8].x - 100, self.Cell[0][2].y - 2 * self.height - 10, 100, 40), Qt.AlignCenter, "单据编号:") painter.drawText( QRect(self.Cell[0][0].x - 6, self.Cell[0][0].y - self.height - 25, 100, 40), Qt.AlignCenter, "出货仓库:") painter.drawText( QRect(self.Cell[0][0].x - 6, self.Cell[0][0].y - self.height, 100, 40), Qt.AlignCenter, "客户电话:") painter.drawText( QRect(self.Cell[0][3].x - 22, self.Cell[0][3].y - self.height - 25, 100, 40), Qt.AlignCenter, "客户:") painter.drawText( QRect(self.Cell[0][3].x - 22, self.Cell[0][3].y - self.height, 100, 40), Qt.AlignCenter, "地址:") for i in range(1, 11): painter.drawText( QRect(self.Cell[0][0].x, self.Cell[i][0].y, self.Cell[i][0].width, self.Cell[i][0].height), Qt.AlignCenter, str(i)) for j in range(9): painter.drawText( QRect(self.Cell[0][j].x, self.Cell[0][j].y, self.Cell[0][j].width, self.Cell[0][j].height), Qt.AlignCenter, title1[j]) painter.setFont(QFont("微软雅黑", 12, QFont.Bold)) painter.drawText(self.zhidan.x, self.zhidan.y, "制单:") painter.drawText(self.jingshouren.x, self.jingshouren.y, "经手人:") painter.drawText(self.shoukuangren.x, self.shoukuangren.y, "收款人:") painter.drawText(self.fahuoren.x, self.fahuoren.y, "发货人:") painter.drawText(self.kehu.x, self.kehu.y, "客户签字(盖章):") pixmap = QPixmap("607.jpg") painter.setOpacity(0.65) painter.drawPixmap(QRect(0, 632, 1500, 200), pixmap) """ 打印 """ def Print(self): if self.CheckTable() == False: #如果库存单信息不完整,将不能打印 return if not (self.yifu.isChecked() or self.weifu.isChecked()) and self.AddinDatabase == True: QMessageBox.warning(self, "警告", "请选择“付款情况") return if self.AddinDatabase: #在非查看模式下打印才会将数据存入数据库 #if True: print("yes") if not self.yifu.isChecked(): #将未付款客户订单存入数据库 print(self.getnotpaydata()) self.kucundandata.InsertData(self.getnotpaydata()) self.yingye.InsertData(self.getYingYeEData("未付款")) #print(self.getYingYeEData("未付款")) else: self.yingye.InsertData(self.getYingYeEData("已付款")) #print(self.getYingYeEData("已付款")) for i in range(10): #将从没出现过的商品存入数据库 if self.commodityData.Find( self.lineedits[i][0].text()) == False: self.commodityData.InsertData(self.lineedits[i][0].text(), self.lineedits[i][1].text(), self.lineedits[i][2].text()) for i in range(4): if i == 0: self.redcheckbutton.setChecked(True) self.colorlabel.setStyleSheet( "background-color:rgba(255,0,0,25)") elif i == 1: self.whitecheckbutton.setChecked(True) self.colorlabel.setStyleSheet( "background-color:rgba(255,255,255,25)") elif i == 2: self.yellowcheckbutton.setChecked(True) self.colorlabel.setStyleSheet( "background-color:rgba(255,255,0,25)") else: self.bluecheckbutton.setChecked(True) self.colorlabel.setStyleSheet( "background-color:rgba(0,255,255,25)") preview = QPrintPreviewDialog(self.printer, self) preview.setGeometry(100, 100, 1200, 900) """ 以下两句实现控制打印纸张的大小 QSizeF 中的第二个参数是height ,第一个是width """ self.printer.setPageSize(QPrinter.Custom) self.printer.setPaperSize(QSizeF(1880, 1260), QPrinter.Point) #QSizeF 中的参数按比例改变可以填充满纸张 preview.paintRequested.connect(self.PlotPic) preview.exec() # 显示预览窗口 self.colorlabel.setStyleSheet("background-color:rgba(255,255,255,25)") self.bluecheckbutton.setChecked(False) def PlotPic(self): painter = QPainter(self.printer) # QRect(0,0) 中(0,0)是窗口坐标 image = self.grab(QRect(QPoint(0, 0), QSize(940, 630))) # /* 绘制窗口至画布 */ rect = painter.viewport() size = image.size() size.scale(rect.size(), Qt.KeepAspectRatio) # //此处保证图片显示完整 painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(image.rect()) painter.drawPixmap(0, 0, image)
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 TableSheet(QWidget): def __init__(self): super().__init__() self.initUi() def initUi(self): #self.setWindowFlags(Qt.WindowCloseButtonHint && Qt.WindowMinimizeButtonHint) #self.setWindowFlags(Qt.WindowMinimizeButtonHint) self.setWindowTitle('火车票查询系统') #self.setGeometry(40,80,1500,720) #第一部分,输入出发地、目的地和日期 controlsLayout = QGridLayout() #栅格布局 self.label1 = QLabel("出发地:") self.Editlabel1 = QLineEdit() self.label2 = QLabel("目的地:") self.Editlabel2 = QLineEdit() self.label3 = QLabel("乘车日期:") self.Editlabel3 = QDateTimeEdit() now = QDateTime.currentDateTime() #print(now) self.Editlabel3.setDateTime(now) self.Editlabel3.setDisplayFormat("yyyy-MM-dd") #小写m为分钟 self.Editlabel3.setCalendarPopup(True) self.buttonOK = QPushButton("确定") controlsLayout.addWidget(QLabel(""), 0, 0, 1, 6) self.message = QLabel("暂未查询车次信息!") controlsLayout.addWidget(self.message, 0, 7, 1, 4) controlsLayout.addWidget(self.label1, 0, 11, 1, 1) controlsLayout.addWidget(self.Editlabel1, 0, 12, 1, 2) controlsLayout.addWidget(QLabel(" "), 0, 14, 1, 1) controlsLayout.addWidget(self.label2, 0, 15, 1, 1) controlsLayout.addWidget(self.Editlabel2, 0, 16, 1, 2) controlsLayout.addWidget(QLabel(" "), 0, 18, 1, 1) controlsLayout.addWidget(self.label3, 0, 19, 1, 1) controlsLayout.addWidget(self.Editlabel3, 0, 20, 1, 2) controlsLayout.addWidget(QLabel(" "), 0, 22, 1, 1) controlsLayout.addWidget(self.buttonOK, 0, 23, 1, 1) controlsLayout.addWidget(QLabel(" "), 0, 25, 1, 8) #第二部分,显示查询到的车次信息 horizontalHeader = [ "车次", "车站", "时间", "历时", "商务座", "一等座", "二等座", "高级软卧", "软卧", "动卧", "硬卧", "软座", "硬座", "无座", "其他" ] self.table = QTableWidget() self.table.setColumnCount(15) self.table.setRowCount(0) #初始化为0行 self.table.setHorizontalHeaderLabels(horizontalHeader) self.table.setEditTriggers(QTableWidget.NoEditTriggers) #不能编辑 self.table.setSelectionBehavior(QTableWidget.SelectRows) #选中整行 self.table.setSelectionMode(QTableWidget.SingleSelection) for index in range(self.table.columnCount()): headItem = self.table.horizontalHeaderItem(index) headItem.setFont(QFont("song", 12, QFont.Bold)) headItem.setForeground(QBrush(Qt.gray)) headItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) #self.table.setFrameShape(QFrame.HLine)#设定样式 #self.table.setShowGrid(False) #取消网格线 #self.table.verticalHeader().setVisible(False) #隐藏垂直表头 #row_count = self.table.rowCount() #self.table.setColumnWidth(0,200) mainLayout = QHBoxLayout() mainLayout.addWidget(self.table) layout = QVBoxLayout() layout.addLayout(controlsLayout) layout.addLayout(mainLayout) self.setLayout(layout) self.buttonOK.clicked.connect(self.showMessage) self.showMaximized() def closeEvent(self, event): #关闭时弹窗提示 reply = QMessageBox.question(self, '警告', '查询记录不会被保存,\n确认退出?', QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def showMessage(self): #显示查询信息 stations_fz = dict(map(lambda t: (t[1], t[0]), stations.items())) #反转字典 from_s = self.Editlabel1.text() #获取文本框内容 to_s = self.Editlabel2.text() if (from_s in stations.keys()) and (to_s in stations.keys()): f = stations[from_s] # 通过字典转化为车站对应的缩写字母 t = stations[to_s] # 通过字典转化为车站对应的缩写字母 date = self.Editlabel3.text() d = str(date) # print(d) # print('正在查询' + from_s + '至' + to_s + '的列车...') url = 'https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=' + d + '&leftTicketDTO.from_station=' + f + '&leftTicketDTO.to_station=' + t + '&purpose_codes=ADULT' # print(url) warnings.filterwarnings("ignore") # 这个网站是有安全警告的,这段代码可以忽略警告 r = requests.get(url, verify=False) raw_trains = r.json()['data']['result'] # 获取车次信息 # print(raw_trains) num = len(raw_trains) # 获取车次数目 # print('共查询到%d个车次信息'%num) self.message.setText("共查询到%d个车次信息" % num) if raw_trains == []: QMessageBox.warning(self, "提示", "暂无所查询的车次信息!") i = 0 self.table.setRowCount(num) self.table.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff) #关闭水平滚动条 for raw_train in raw_trains: # split分割之后得到的是一个列表 data_list = raw_train.split("|") # print(data_list) tra_no = data_list[2] #train_no from_s_no = data_list[16] #from_station_no to_s_no = data_list[17] #to_station_no seat_type = data_list[35] #seat_types tra_date = d #train_date checi = data_list[3] # 车次 cfd = stations_fz[data_list[6]] #出发地,通过字典转换 mdd = stations_fz[data_list[7]] #目的地 fctime = data_list[8] # 发车时间 ddtime = data_list[9] # 到达时间 lishi = data_list[10] # 历时 shangwuzuo = data_list[32] or "--" # 商务座/特等座 yidengzuo = data_list[31] or "--" # 一等座 erdengzuo = data_list[30] or "--" # 二等座 gjruanwo = data_list[21] or "--" # 高级软卧 ruanwo = data_list[23] or "--" # 软卧 dongwo = data_list[33] or "--" # 动卧 yingwo = data_list[28] or "--" # 硬卧 ruanzuo = data_list[24] or "--" # 软座 yingzuo = data_list[29] or "--" # 硬座 wuzuo = data_list[26] or "--" # 无座 others = data_list[22] or "--" # 其他 price_url = "https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=" + tra_no + "&from_station_no=" + from_s_no + "&to_station_no=" + to_s_no + "&seat_types=" + seat_type + "&train_date=" + tra_date r1 = requests.get(price_url, verify=False) # print(price_url) raw_prices = r1.json()['data'] # 获取车次信息 if 'A1' in raw_prices.keys(): #A1:硬座 pr_yz = raw_prices['A1'] else: pr_yz = '' if 'A2' in raw_prices.keys(): # A2:软座 pr_rz = raw_prices['A2'] else: pr_rz = '' if 'A3' in raw_prices.keys(): # A3:硬卧 pr_yw = raw_prices['A3'] else: pr_yw = '' if 'A4' in raw_prices.keys(): # A4:软卧 pr_rw = raw_prices['A4'] else: pr_rw = '' if 'A6' in raw_prices.keys(): # A6:高级软卧 pr_gjrw = raw_prices['A6'] else: pr_gjrw = '' if 'A9' in raw_prices.keys(): # A9:商务座,特等座 pr_swz = raw_prices['A9'] else: pr_swz = '' if 'WZ' in raw_prices.keys(): # WZ:无座 pr_wz = raw_prices['WZ'] else: pr_wz = '' if 'M' in raw_prices.keys(): # M:一等座 pr_ydz = raw_prices['M'] else: pr_ydz = '' if 'O' in raw_prices.keys(): # O:二等座 pr_edz = raw_prices['O'] else: pr_edz = '' if 'F' in raw_prices.keys(): # F:动卧 pr_dw = raw_prices['F'] else: pr_dw = '' # print(pr_yz,pr_rz,pr_yw,pr_rw,pr_gjrw,pr_swz,pr_wz,pr_ydz,pr_edz,pr_dw) NewItem = QTableWidgetItem(checi) NewItem.setForeground(QColor(Qt.red)) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) #垂直居中 self.table.setItem(i, 0, NewItem) NewItem = QTableWidgetItem(cfd + '\n-\n' + mdd) NewItem.setFont(QFont("song", 9, QFont.Bold)) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 1, NewItem) NewItem = QTableWidgetItem(fctime + '\n-\n' + ddtime) NewItem.setFont(QFont("song", 9, QFont.Bold)) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 2, NewItem) NewItem = QTableWidgetItem(lishi) NewItem.setFont(QFont("song", 9, QFont.Bold)) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 3, NewItem) NewItem = QTableWidgetItem(shangwuzuo + '\n' + pr_swz) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 4, NewItem) NewItem = QTableWidgetItem(yidengzuo + '\n' + pr_ydz) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 5, NewItem) NewItem = QTableWidgetItem(erdengzuo + '\n' + pr_edz) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 6, NewItem) NewItem = QTableWidgetItem(gjruanwo + '\n' + pr_gjrw) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 7, NewItem) NewItem = QTableWidgetItem(ruanwo + '\n' + pr_rw) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 8, NewItem) NewItem = QTableWidgetItem(dongwo + '\n' + pr_dw) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 9, NewItem) NewItem = QTableWidgetItem(yingwo + '\n' + pr_yw) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 10, NewItem) NewItem = QTableWidgetItem(ruanzuo + '\n' + pr_rz) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 11, NewItem) NewItem = QTableWidgetItem(yingzuo + '\n' + pr_yz) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 12, NewItem) NewItem = QTableWidgetItem(wuzuo + '\n' + pr_wz) NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 13, NewItem) NewItem = QTableWidgetItem(others + '\n' + '') NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.table.setItem(i, 14, NewItem) self.table.setRowHeight(i, 60) #设置行高 i = i + 1 #self.table.setSpan(0, 8, 2, 1) #合并单元格 else: if from_s not in stations.keys(): # print('请输入正确的出发地') QMessageBox.warning(self, "提示", "请输入正确的出发地!") if to_s not in stations.keys(): # print('请输入正确的目的地') QMessageBox.warning(self, "提示", "请输入正确的目的地!")
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 MainWidget(QWidget): ''' The MainWidget class is the home screen of the app and allows the user to input parameters for analysis. Attributes: output_path (str): the output path selected by the user file (str): the file path selected by the user ad_number (int): the integer selected by the user for the averaging duration ad_unit (int): the unit of time selected by the user for the averaging duration time_selected (bool): whether or not the user has selected a specific time range VALID_FILES (list of str): the list of valid file types accepted AD_UNITS (list of str): the list of time units selectable by the user time_selectors (QWidget): a widget containing the time range inputs layout (QVBoxLayout): a vertical layout for the screen ''' def __init__(self): super().__init__() # initialize variables self.output_path = None self.file = None self.ad_number = None self.ad_unit = None self.time_selected = False # single definition point for hardcoded values (valid file types and averaging duration units) self.VALID_FILES = ["xlsx", "xls", "csv"] self.AD_UNITS = ["Minutes", "Hours", "Days", "Weeks", "Months", "Years"] # create static UI elements title_label = QLabel("CDC Air Quality Analysis") title_label.setObjectName("title") file_select_layout = self.file_select_layout() output_path_layout = self.output_path_layout() averaging_duration_layout = self.averaging_duration_layout() time_range_layout = self.time_range_layout() self.time_selectors = self.create_time_selectors() # create process button and connect to function process_file = QPushButton("Process File") process_file.clicked.connect(self.begin_process) # define the layout of the screen self.layout = QVBoxLayout() self.layout.addWidget(title_label) self.layout.addLayout(file_select_layout) self.layout.addLayout(output_path_layout) self.layout.addLayout(averaging_duration_layout) self.layout.addLayout(time_range_layout) self.layout.addWidget(self.time_selectors) self.layout.addWidget(process_file) self.setLayout(self.layout) # define UI elements and layout for the file select input def file_select_layout(self): instruction_label = QLabel("Select Data File:") instruction_label.setObjectName("instruction") self.file_name = QLabel("No File Selected") self.file_name.setObjectName("fileName") self.file_name.setFixedWidth(200) button = QPushButton("Browse") button.setFixedWidth(100) button.clicked.connect(partial(self.get_file, self.file_name)) layout = QHBoxLayout() layout.addWidget(instruction_label) layout.addWidget(self.file_name) layout.addWidget(button) layout.setContentsMargins(6, 10, 6, 8) return layout # define UI elements and layout for the output path select input def output_path_layout(self): instruction_label = QLabel("Select Output Path:") instruction_label.setObjectName("instruction") self.output_select = QLabel("No Path Selected") self.output_select.setObjectName("fileName") self.output_select.setFixedWidth(200) button = QPushButton("Browse") button.setFixedWidth(100) button.clicked.connect(partial(self.get_output, self.output_select)) layout = QHBoxLayout() layout.addWidget(instruction_label) layout.addWidget(self.output_select) layout.addWidget(button) layout.setContentsMargins(6, 10, 6, 8) return layout # define UI elements and layout for averaging duration input def averaging_duration_layout(self): instruction_label = QLabel("Select Averaging Duration:") instruction_label.setObjectName("instruction") self.ad_number_input = QLineEdit(self) self.ad_number_input.setPlaceholderText("Input an Integer") self.ad_number_input.setFixedWidth(125) self.ad_number_input.setFixedHeight(25) # define dropdown menu (known as a ComboBox) self.ad_unit = self.AD_UNITS[0] # default comboBox = QComboBox(self) comboBox.setFixedWidth(100) for item in self.AD_UNITS: comboBox.addItem(item) comboBox.currentIndexChanged.connect(partial(self.selection_change, comboBox)) layout = QHBoxLayout() layout.addWidget(instruction_label) layout.addWidget(self.ad_number_input) layout.addWidget(comboBox) layout.setContentsMargins(6, 8, 6, 8) return layout # called whenever the user makes a new selection from the averaging duration dropdown def selection_change(self, cb): self.ad_unit = cb.currentText() # define UI elements and layout for the time range input def time_range_layout(self): instruction_label = QLabel("Use Time Range?") instruction_label.setObjectName("instruction") # time range is optional, so these radio buttons formalize that choice yes_rb = QRadioButton("Yes") no_rb = QRadioButton("No") no_rb.setChecked(True) yes_rb.toggled.connect(partial(self.rb_state, yes_rb)) no_rb.toggled.connect(partial(self.rb_state, no_rb)) layout = QHBoxLayout() layout.addWidget(instruction_label) layout.addWidget(yes_rb) layout.addWidget(no_rb) layout.setContentsMargins(6,8,6,8) layout.insertSpacing(1, 85) layout.insertSpacing(3, 80) return layout # define UI elements and layout for the time range selectors def create_time_selectors(self): instruction_label = QLabel("Start Time:") instruction_label.setObjectName("instruction") self.start = QDateTimeEdit(self) self.start.setCalendarPopup(True) self.start.setDateTime(QDateTime.currentDateTime()) instruction2_label = QLabel("End Time:") instruction2_label.setObjectName("instruction") self.end = QDateTimeEdit(self) self.end.setCalendarPopup(True) self.end.setDateTime(QDateTime.currentDateTime()) layout = QHBoxLayout() layout.setContentsMargins(6, 8, 6, 10) layout.addWidget(instruction_label) layout.addWidget(self.start) layout.addWidget(instruction2_label) layout.addWidget(self.end) # define a new widget so we can enable and disable it based on the radio button input widget = QWidget() widget.setLayout(layout) widget.setFixedHeight(50) widget.setEnabled(False) return widget # called when the user clicks the select file button def get_file(self, label): # get valid file types from array valid_files = "" for ext in self.VALID_FILES: valid_files += "*." + ext + " " # open file explorer dialog prefilled with valid file types file_name, _ = QFileDialog.getOpenFileName(self, "Select Data Files", "", "Data Files (" + valid_files.strip() +");;All Files (*)") # if user closes dialog without selecting a file path, it will return None if file_name: self.file = file_name.split("/")[-1] self.file_path = file_name label.setText(self.file) # called when the user clicks the select output path button def get_output(self, label): path = QFileDialog.getExistingDirectory(self, "Choose an Output Directory", options=QFileDialog.ShowDirsOnly) if path: self.output_path = path split_path = path.split("/") if len(split_path) >= 2: label.setText(split_path[-2] + "/" + split_path[-1]) else: label.setText(self.output_path) # change the state of the radio buttons and toggle the time range widget def rb_state(self, clicked): if clicked.text() == "Yes" and clicked.isChecked() == True: self.time_selectors.setEnabled(True) self.time_selected = True elif clicked.text() == "No" and clicked.isChecked() == True: self.time_selectors.setEnabled(False) self.time_selected = False # perform input validation and begin processing def begin_process(self): main_window = self.parentWidget().parentWidget() # check that a file has been selected if not self.file: main_window.raise_error("Input Error", "No File Selected", "Please select a file for analysis.") return extension = self.file.split(".")[-1] # check that the file selected is a valid file type if not extension in self.VALID_FILES: main_window.raise_error("Input Error", "Invalid File Type Selected", "Valid file types include " + ", ".join(self.VALID_FILES) + ".") return # check that the user has inputted a number and unit for averaging duration self.ad_number = self.ad_number_input.text() if not self.ad_number or not self.ad_unit: main_window.raise_error("Input Error", "Invalid Averaging Duration Selected", "Please input an integer and unit for the averaging duration.") return # check that the ad_num input is actually a number try: self.ad_number = int(self.ad_number) except ValueError: main_window.raise_error("Input Error", "Invalid Averaging Duration Selected", "Averaging duration must be a whole number.") return # check that the ad_num input is actually an integer # we want the user to be made aware that it must be an integer if not round(self.ad_number) == self.ad_number: main_window.raise_error("Input Error", "Invalid Averaging Duration Selected", "Averaging duration must be a whole number.") return # if the user has chosen a time range, make sure that end time is not before start time if self.time_selected: start_time = self.start.dateTime() end_time = self.end.dateTime() if start_time > end_time: main_window.raise_error("Input Error", "Invalid Time Entered", "End Time cannot be greater than Start Time.") return else: start_time = None end_time = None # callback to main window to initiate process and change the screen main_window.start_analysis( self.file, self.file_path, self.output_path, self.ad_number, self.ad_unit, start_time, end_time ) # reset and clear all inputs def reset(self): self.file = None self.file_name.setText("No File Selected") self.output_path = None self.output_select.setText("No Path Selected") self.ad_number = None self.ad_number_input.clear() self.start.setDateTime(QDateTime.currentDateTime()) self.end.setDateTime(QDateTime.currentDateTime())
class StockMemoEditor(QDialog): def __init__(self, history: History): super(StockMemoEditor, self).__init__() self.__history = history self.__source = '' self.__current_record = None self.__label_uuid = QLabel() self.__label_source = QLabel() self.__text_record = QTextEdit() self.__datetime_time = QDateTimeEdit(QDateTime.currentDateTime()) self.__button_apply = QPushButton('保存') self.__button_cancel = QPushButton('取消') self.init_ui() self.config_ui() def init_ui(self): root_layout = QVBoxLayout() self.setLayout(root_layout) group_box, group_layout = create_v_group_box('') group_layout.addWidget(self.__label_uuid) group_layout.addWidget(self.__label_source) group_layout.addWidget(self.__datetime_time) # group_layout.addLayout(horizon_layout([QLabel('笔记ID'), self.__label_uuid])) # group_layout.addLayout(horizon_layout([QLabel('笔记文件'), self.__label_source])) # group_layout.addLayout(horizon_layout([QLabel('记录时间'), self.__datetime_time])) root_layout.addWidget(group_box, 0) root_layout.addWidget(self.__text_record, 10) root_layout.addLayout(horizon_layout([self.__button_apply, self.__button_cancel])) self.setMinimumSize(500, 600) def config_ui(self): self.__label_uuid.setEnabled(False) self.__label_source.setEnabled(False) self.setWindowTitle('笔记') self.__datetime_time.setCalendarPopup(True) self.__button_apply.clicked.connect(self.on_button_apply) self.__button_cancel.clicked.connect(self.on_button_cancel) def on_button_apply(self): if self.__current_record is None: self.__current_record = HistoricalRecord() else: self.__current_record.reset() if not self.ui_to_record(self.__current_record): QMessageBox.information(self, QtCore.QCoreApplication.translate('History', '错误'), QtCore.QCoreApplication.translate('History', '采集界面数据错误'), QMessageBox.Ok, QMessageBox.Ok) return if self.__source is None or self.__source == '': QMessageBox.information(self, QtCore.QCoreApplication.translate('History', '错误'), QtCore.QCoreApplication.translate('History', '没有指定数据源,无法保存'), QMessageBox.Ok, QMessageBox.Ok) return self.__current_record.set_source(self.__source) self.__history.update_records([self.__current_record]) records = self.__history.get_record_by_source(self.__source) result = HistoricalRecordLoader.to_local_source(records, self.__source) if not result: QMessageBox.information(self, QtCore.QCoreApplication.translate('History', '错误'), QtCore.QCoreApplication.translate('History', '保存到数据源 [%s] 失败' % self.__source), QMessageBox.Ok, QMessageBox.Ok) return self.close() def on_button_cancel(self): self.close() # --------------------------------------------------------------------------- def set_memo(self, memo: HistoricalRecord): self.__current_record = memo self.__source = memo.source() self.record_to_ui(memo) def set_source(self, source: str): self.__source = source def set_memo_datetime(self, date_time: datetime.datetime): self.__datetime_time.setDateTime(date_time) # -------------------------------- Operation -------------------------------- def clear_ui(self): self.__label_uuid.setText('') self.__label_source.setText('') self.__text_record.clear() def ui_to_record(self, record: HistoricalRecord) -> bool: input_time = self.__datetime_time.dateTime() input_memo = self.__text_record.toPlainText() date_time = input_time.toPyDateTime() record.set_label_tags('time', date_time.strftime('%Y-%m-%d %H:%M:%S')) record.set_label_tags('event', input_memo) record.set_focus_label('time') return True def record_to_ui(self, record: HistoricalRecord or str): self.clear_ui() self.__label_uuid.setText(LabelTagParser.tags_to_text(record.uuid())) self.__label_source.setText(self.__source) self.__text_record.setText(LabelTagParser.tags_to_text(record.event())) since = record.since() pytime = HistoryTime.tick_to_pytime(since) self.__datetime_time.setDateTime(pytime)
class StockMemoEditor(QDialog): def __init__(self, sas: StockAnalysisSystem, memo_record: RecordSet, parent: QWidget = None): super(StockMemoEditor, self).__init__(parent) self.__sas = sas self.__memo_recordset = memo_record self.__current_stock = None self.__current_index = None self.__current_record: Record = None data_utility = self.__sas.get_data_hub_entry().get_data_utility( ) if self.__sas is not None else None self.__combo_stock = SecuritiesSelector(data_utility) self.__table_memo_index = EasyQTableWidget() self.__datetime_time = QDateTimeEdit(QDateTime().currentDateTime()) self.__line_brief = QLineEdit() self.__text_record = QTextEdit() self.__button_new = QPushButton('新建') self.__button_apply = QPushButton('保存') self.init_ui() self.config_ui() def init_ui(self): root_layout = QHBoxLayout() self.setLayout(root_layout) group_box, group_layout = create_v_group_box('') group_layout.addWidget(self.__combo_stock, 1) group_layout.addWidget(self.__table_memo_index, 99) root_layout.addWidget(group_box, 4) group_box, group_layout = create_v_group_box('') group_layout.addLayout( horizon_layout( [QLabel('时间:'), self.__datetime_time, self.__button_new], [1, 99, 1])) group_layout.addLayout( horizon_layout([QLabel('摘要:'), self.__line_brief], [1, 99])) group_layout.addWidget(self.__text_record) group_layout.addLayout( horizon_layout([QLabel(''), self.__button_apply], [99, 1])) root_layout.addWidget(group_box, 6) self.setMinimumSize(500, 600) def config_ui(self): self.setWindowTitle('笔记编辑器') self.__datetime_time.setCalendarPopup(True) self.__combo_stock.setEditable(False) self.__combo_stock.currentIndexChanged.connect( self.on_combo_select_changed) self.__table_memo_index.insertColumn(0) self.__table_memo_index.insertColumn(0) self.__table_memo_index.setHorizontalHeaderLabels(['时间', '摘要']) self.__table_memo_index.setSelectionMode( QAbstractItemView.SingleSelection) self.__table_memo_index.setSelectionBehavior( QAbstractItemView.SelectRows) self.__table_memo_index.itemSelectionChanged.connect( self.on_table_selection_changed) self.__table_memo_index.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.__button_new.clicked.connect(self.on_button_new) self.__button_apply.clicked.connect(self.on_button_apply) # self.setWindowFlags( # QtCore.Qt.Window | # QtCore.Qt.CustomizeWindowHint | # QtCore.Qt.WindowTitleHint | # QtCore.Qt.WindowCloseButtonHint | # QtCore.Qt.WindowStaysOnTopHint # ) def on_button_new(self): if self.__current_stock is None: QMessageBox.information(self, '错误', '请选择需要做笔记的股票', QMessageBox.Ok, QMessageBox.Ok) self.create_new_memo(None) def on_button_apply(self): _time = self.__datetime_time.dateTime().toPyDateTime() brief = self.__line_brief.text() content = self.__text_record.toPlainText() if not str_available(brief): QMessageBox.information(self, '错误', '请至少填写笔记摘要', QMessageBox.Ok, QMessageBox.Ok) return if self.__current_index is not None: ret = self.__current_record.update_record(self.__current_index, _time, brief, content, True) else: ret, index = self.__current_record.add_record( _time, brief, content, 'memo', True) self.__current_index = index if ret: self.__reload_stock_memo() def on_combo_select_changed(self): input_securities = self.__combo_stock.get_input_securities() self.__load_stock_memo(input_securities) def on_table_selection_changed(self): if self.__current_record is None: return sel_index = self.__table_memo_index.GetCurrentIndex() if sel_index < 0: return sel_item = self.__table_memo_index.item(sel_index, 0) if item is None: return df_index = sel_item.data(Qt.UserRole) self.__load_memo_by_index(df_index) def select_stock(self, stock_identity: str): index = self.__combo_stock.findData(stock_identity) if index != -1: print('Select combox index: %s' % index) self.__combo_stock.setCurrentIndex(index) else: print('No index in combox for %s' % stock_identity) self.__combo_stock.setCurrentIndex(-1) self.__load_stock_memo(stock_identity) def select_memo_by_time(self, _time: datetime.datetime): if self.__current_record is None or self.__current_record.is_empty(): self.create_new_memo(_time) return df = self.__current_record.get_records('memo') time_serial = df['time'].dt.normalize() select_df = df[time_serial == _time.replace( hour=0, minute=0, second=0, microsecond=0)] select_index = None for index, row in select_df.iterrows(): select_index = index break if select_index is not None: self.select_memo_by_index(select_index) else: self.create_new_memo(_time) def select_memo_by_index(self, index: int): for row in range(0, self.__table_memo_index.rowCount()): table_item = self.__table_memo_index.item(row, 0) row_index = table_item.data(Qt.UserRole) if row_index == index: self.__table_memo_index.selectRow(row) break def create_new_memo(self, _time: datetime.datetime): self.__table_memo_index.clearSelection() if _time is not None: self.__datetime_time.setDateTime(_time) self.__line_brief.setText('') self.__text_record.setText('') self.__current_index = None # ------------------------------------------------------------------- def __load_stock_memo(self, stock_identity: str): print('Load stock memo for %s' % stock_identity) self.__table_memo_index.clear() self.__table_memo_index.setRowCount(0) self.__table_memo_index.setHorizontalHeaderLabels(['时间', '摘要']) self.__current_stock = stock_identity self.__current_record = None self.__current_index = None if self.__memo_recordset is None or \ self.__current_stock is None or self.__current_stock == '': return self.__current_record = self.__memo_recordset.get_record( stock_identity) df = self.__current_record.get_records('memo') select_index = None for index, row in df.iterrows(): if select_index is None: select_index = index self.__table_memo_index.AppendRow( [datetime2text(row['time']), row['brief']], index) self.select_memo_by_index(select_index) def __reload_stock_memo(self): self.__line_brief.setText('') self.__text_record.setText('') self.__table_memo_index.clear() self.__table_memo_index.setRowCount(0) self.__table_memo_index.setHorizontalHeaderLabels(['时间', '摘要']) if self.__current_record is None: print('Warning: Current record is None, cannot reload.') return df = self.__current_record.get_records('memo') select_index = self.__current_index for index, row in df.iterrows(): if select_index is None: select_index = index self.__table_memo_index.AppendRow( [datetime2text(row['time']), row['brief']], index) self.select_memo_by_index(select_index) def __load_memo_by_index(self, index: int): self.__table_memo_index.clearSelection() if self.__current_record is None or index is None: return df = self.__current_record.get_records('memo') s = df.loc[index] if len(s) == 0: return self.__current_index = index _time = s['time'] brief = s['brief'] content = s['content'] self.__datetime_time.setDateTime(to_py_datetime(_time)) self.__line_brief.setText(brief) self.__text_record.setText(content)
class MailserverUi(QMainWindow): def __init__(self): super().__init__() setConfigOption('background', '#19232D') setConfigOption('foreground', 'd') setConfigOptions(antialias = True) # self.resize(720,500) self.init_ui() self.data_smtp = [] self.data_db = [] self.data_logs = [] self.data_temp_logs = [] # self.sub_win = SubWindow() # 默認狀態欄 self.status = self.statusBar() self.status.showMessage("開發者: 鄭鈺城, 聯絡資訊: [email protected]") # 標題欄 self.setWindowTitle("社交郵件工程") self.setWindowOpacity(1) # 窗口透明度 self.main_layout.setSpacing(0) self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) self.main_widget.setStyleSheet( """ QComboBox::item:checked { height: 12px; border: 1px solid #32414B; margin-top: 0px; margin-bottom: 0px; padding: 4px; padding-left: 0px; } """ ) def init_ui(self): # 創建視窗主部件 self.main_widget = QWidget() # 創建主部件的網格佈局 self.main_layout = QGridLayout() # 設置窗口主部件佈局為網格佈局 self.main_widget.setLayout(self.main_layout) # 創建左側部件 self.left_widget = QWidget() self.left_widget.setObjectName('left_widget') self.left_layout = QGridLayout() self.left_widget.setLayout(self.left_layout) # 創建右側部件 self.right_widget = QWidget() self.right_widget.setObjectName('right_widget') self.right_layout = QGridLayout() self.right_widget.setLayout(self.right_layout) # 左側部件在第0行第0列,佔12行3列 self.main_layout.addWidget(self.left_widget, 0, 0, 12, 3) # 右側部件在第0行第3列,佔12行8列 self.main_layout.addWidget(self.right_widget, 0, 3, 12, 8) # 設置視窗主部件 self.setCentralWidget(self.main_widget) # 主要功能按鈕 self.btn_sendmail = QPushButton("發送信件") self.btn_sendmail.clicked.connect(self.display_send_mail) self.btn_smtp = QPushButton("系統設定") self.btn_smtp.clicked.connect(self.display_smtp_setting) self.btn_db = QPushButton("資料庫設定") self.btn_db.clicked.connect(self.display_db_setting) self.btn_update_eml = QPushButton("修改樣板") self.btn_update_eml.clicked.connect(self.display_update_eml) self.btn_get_logs = QPushButton("觸發明細") self.btn_get_logs.clicked.connect(self.display_logs) self.btn_download_logs = QPushButton("下載觸發明細") self.btn_download_logs.clicked.connect(self.logs_download) self.quit_btn = QPushButton("退出") self.quit_btn.clicked.connect(self.quit_act) self.left_layout.addWidget(self.btn_sendmail, 2, 0, 1, 3) self.left_layout.addWidget(self.btn_smtp, 3, 0, 1, 3) self.left_layout.addWidget(self.btn_db, 4, 0, 1, 3) self.left_layout.addWidget(self.btn_update_eml, 5, 0, 1, 3) self.left_layout.addWidget(self.btn_get_logs, 6, 0, 1, 3) self.left_layout.addWidget(self.btn_download_logs, 7, 0, 1, 3) self.left_layout.addWidget(self.quit_btn, 8, 0, 1, 3) # 主要功能查詢 self.in_data = QLineEdit() self.in_data.setPlaceholderText("暫無") self.left_layout.addWidget(self.in_data, 1, 0, 1, 3) # 主要功能 log self.query_result = QTableWidget() self.left_layout.addWidget(self.query_result, 9, 0, 2, 3) self.query_result.verticalHeader().setVisible(False) self.right_display = GraphicsLayoutWidget() self.right_layout.addWidget(self.right_display, 0, 3, 12, 8) # 右側物件: sendmail self.in_eml_type = QLineEdit() self.in_eml_template = QLineEdit() self.btn_eml_browse = QPushButton('瀏覽') self.btn_eml_browse.clicked.connect(lambda: self.open_eml(self.in_eml_template)) self.in_recipient_group = QLineEdit() self.in_recipient_excel = QLineEdit() self.btn_recipient_browse = QPushButton('瀏覽') self.btn_recipient_browse.clicked.connect(lambda: self.open_excel(self.in_recipient_excel)) self.in_annex_file = QLineEdit() self.btn_annex_file = QPushButton('瀏覽') self.btn_annex_file.clicked.connect(lambda: self.open_word(self.in_annex_file)) self.in_scheduler = QDateTimeEdit(QDateTime.currentDateTime()) self.in_scheduler.setCalendarPopup(True) self.in_scheduler.setDisplayFormat('yyyy-MM-dd hh:mm') self.cb_scheduler = QCheckBox('使用') self.btn_sendmail_start = QPushButton('執行') self.btn_sendmail_start.clicked.connect(self.send_mail) # 右側物件: smtp self.in_smtp_host = QLineEdit() self.in_smtp_port = QLineEdit() self.in_smtp_user = QLineEdit() self.in_smtp_password = QLineEdit() self.cb_smtp_ssl = QCheckBox('使用') self.in_smtp_test = QLineEdit() self.btn_smtp_save = QPushButton('儲存') self.btn_smtp_save.clicked.connect(lambda: self.save_data(self.data_smtp)) self.btn_smtp_test = QPushButton('測試') self.btn_smtp_test.clicked.connect(self.show_sub_win) # 右側物件: db self.in_db_host = QLineEdit() self.in_db_port = QLineEdit() self.in_db_user = QLineEdit() self.in_db_password = QLineEdit() self.in_db_database = QLineEdit() self.in_db_domain = QLineEdit() self.in_db_domain.setPlaceholderText('回收風險資訊動作的網址') self.btn_db_save = QPushButton('儲存') self.btn_db_save.clicked.connect(lambda: self.save_data(self.data_db)) # 右側物件: update eml self.in_edit_sender = QLineEdit() self.in_edit_sender_name = QLineEdit() self.cb_edit_annex = QCheckBox('是') self.in_edit_annex = QLineEdit() self.btn_edit_annex = QPushButton('瀏覽') self.btn_edit_annex.clicked.connect(lambda: self.open_annex(self.in_edit_annex)) self.in_edit_subject = QLineEdit() self.mail_tab = QTabWidget() self.mail_tab.setDocumentMode(True) self.mail_tab.currentChanged.connect(self.print_html) self.mail_tab_1 = QWidget() self.mail_tab_2 = QWidget() self.mail_tab.addTab(self.mail_tab_1, 'Html') self.mail_tab.addTab(self.mail_tab_2, 'Web') self.tab_1 = QGridLayout() self.tab_2 = QGridLayout() self.tab_1.setContentsMargins(0,0,0,0) self.tab_2.setContentsMargins(0,0,0,0) self.mail_tab_1.setLayout(self.tab_1) self.mail_tab_2.setLayout(self.tab_2) self.in_edit_html = QTextEdit() self.in_edit_web = QWebEngineView() self.tab_1.addWidget(self.in_edit_html, 1, 1, 1, 1) self.tab_2.addWidget(self.in_edit_web, 1, 1, 1, 1) self.btn_edit_eml_reset = QPushButton('清除') self.btn_edit_eml_reset.clicked.connect(self.eml_reset) self.btn_edit_eml_read = QPushButton('讀取') self.btn_edit_eml_read.clicked.connect(self.eml_open) self.btn_edit_eml_save = QPushButton('儲存') self.btn_edit_eml_save.clicked.connect(self.eml_save) # 右側物件: logs self.tbw_logs = QTableWidget() self.tbw_logs.verticalHeader().setVisible(False) self.cmb_logs_choice = QComboBox() self.in_logs_data = QLineEdit() self.in_logs_data.setPlaceholderText("輸入資料") self.btn_logs_search = QPushButton('執行') self.btn_logs_search.clicked.connect(self.logs_change) def display_send_mail(self): self.clear_layout(self.right_layout) labels = [ "信件類型 :", "信件模板 :", " 收件人群組 :", "收件人資料 :", '附件資料 :',"設定排程 :"] for i, label in enumerate(labels): self.right_layout.addWidget(QLabel(label), i, 3, 1, 1, Qt.AlignRight) self.right_layout.addWidget(self.in_eml_type, 0, 4, 1, 7) self.right_layout.addWidget(self.in_eml_template, 1, 4, 1, 6) self.right_layout.addWidget(self.btn_eml_browse, 1, 10, 1, 1) self.right_layout.addWidget(self.in_recipient_group, 2, 4, 1, 7) self.right_layout.addWidget(self.in_recipient_excel, 3, 4, 1, 6) self.right_layout.addWidget(self.btn_recipient_browse, 3, 10, 1, 1) self.right_layout.addWidget(self.in_annex_file , 4, 4, 1, 6) self.right_layout.addWidget(self.btn_annex_file, 4, 10, 1, 1) self.right_layout.addWidget(self.in_scheduler, 5, 4, 1, 6) self.right_layout.addWidget(self.cb_scheduler, 5, 10, 1, 1) self.right_layout.addWidget(self.btn_sendmail_start, 6, 9, 1, 2) def display_smtp_setting(self): self.clear_layout(self.right_layout) # 在右邊新增物件 labels = ["SMTP HOST :", "SMTP PORT :", "SMTP 帳號 :", "SMTP 密碼 :", "SMTP SSL :", " 測試信件內容 :"] for i, label in enumerate(labels): self.right_layout.addWidget(QLabel(label), i, 3, 1, 1, Qt.AlignRight) self.right_layout.addWidget(self.in_smtp_host, 0, 4, 1, 7) self.right_layout.addWidget(self.in_smtp_port, 1, 4, 1, 7) self.right_layout.addWidget(self.in_smtp_user, 2, 4, 1, 7) self.right_layout.addWidget(self.in_smtp_password, 3, 4, 1, 7) self.right_layout.addWidget(self.cb_smtp_ssl, 4, 4, 1, 7) self.right_layout.addWidget(self.in_smtp_test, 5, 4, 1, 7) self.right_layout.addWidget(self.btn_smtp_save, 6, 9, 1, 2) self.right_layout.addWidget(self.btn_smtp_test, 6, 7, 1, 2) def display_db_setting(self): self.clear_layout(self.right_layout) # 在右邊新增物件 labels = ["資料庫 HOST :", "資料庫 PORT :", "資料庫 帳號 :", "資料庫 密碼 :", "使用資料庫名稱 :", "回收網址 :"] for i, label in enumerate(labels): self.right_layout.addWidget(QLabel(label), i, 3, 1, 1, Qt.AlignRight) self.right_layout.addWidget(self.in_db_host, 0, 4, 1, 7) self.right_layout.addWidget(self.in_db_port, 1, 4, 1, 7) self.right_layout.addWidget(self.in_db_user, 2, 4, 1, 7) self.right_layout.addWidget(self.in_db_password, 3, 4, 1, 7) self.right_layout.addWidget(self.in_db_database, 4, 4, 1, 7) self.right_layout.addWidget(self.in_db_domain, 5, 4, 1, 7) self.right_layout.addWidget(self.btn_db_save, 6, 9, 1, 2) def display_update_eml(self): self.clear_layout(self.right_layout) labels = ["寄件人 :", "寄件人名稱 :", " 是否加入附件 :", "附件名稱 :", "主旨 :", "內容 :"] for i, label in enumerate(labels): self.label = QLabel(label) self.right_layout.addWidget(self.label, i, 3, 1, 1, Qt.AlignRight) self.right_layout.addWidget(self.in_edit_sender, 0, 4, 1, 7) self.right_layout.addWidget(self.in_edit_sender_name, 1, 4, 1, 7) self.right_layout.addWidget(self.cb_edit_annex, 2, 4, 1, 7) self.right_layout.addWidget(self.in_edit_annex, 3, 4, 1, 6) self.right_layout.addWidget(self.btn_edit_annex, 3, 10, 1, 1) self.right_layout.addWidget(self.in_edit_subject, 4, 4, 1, 7) self.right_layout.addWidget(self.mail_tab, 5, 4, 6, 7) self.right_layout.addWidget(self.btn_edit_eml_reset, 11, 5, 1, 2) self.right_layout.addWidget(self.btn_edit_eml_read, 11, 7, 1, 2) self.right_layout.addWidget(self.btn_edit_eml_save, 11, 9, 1, 2) def display_logs(self): self.data_temp_logs = [] self.tbw_logs.setRowCount(0) self.clear_layout(self.right_layout) self.right_layout.addWidget(self.tbw_logs, 1, 3, 11, 8) self.right_layout.addWidget(QLabel('查詢 :'), 0, 3, 1, 1) self.right_layout.addWidget(self.cmb_logs_choice, 0, 4, 1, 2) self.right_layout.addWidget(self.in_logs_data, 0, 6, 1, 3) self.right_layout.addWidget(self.btn_logs_search, 0, 9, 1, 2) try: db = Database(self.data_db[0], int(self.data_db[1]), self.data_db[2], self.data_db[3], self.data_db[4]) if self.data_db[:5] else Database() self.data_logs = db.get_logs() self.data_temp_logs = deepcopy(self.data_logs) if self.data_logs: row_num = len(self.data_logs) col_num = len(self.data_logs[0]) col_lst = list(self.data_logs[0].keys()) self.cmb_logs_choice.clear() self.cmb_logs_choice.addItems(col_lst) self.tbw_logs.setRowCount(row_num) self.tbw_logs.setColumnCount(col_num) self.tbw_logs.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.tbw_logs.setHorizontalHeaderLabels(col_lst) for i in range(row_num): row_data = list(self.data_logs[i].values()) for j in range(col_num): temp_data = row_data[j] item = QTableWidgetItem(str(temp_data)) item.setForeground(QBrush(QColor(144, 182, 240))) self.tbw_logs.setItem(i, j, item) except: QMessageBox.warning(self, 'Failed!', '資料庫連結失敗!', QMessageBox.Ok) else: db.__disconnect__() def get_items_from_layout(self, layout): return [layout.itemAt(i).widget() for i in range(layout.count())] def save_data(self, data): items = self.get_items_from_layout(self.right_layout) data.clear() try: for item in items: if type(item) == type(QLineEdit()): data.append(item.text()) elif type(item) == type(QCheckBox()): data.append(item.isChecked()) QMessageBox.information(self, 'Success!', '儲存成功!', QMessageBox.Ok) except: QMessageBox.warning(self, 'Failed!', '儲存失敗!', QMessageBox.Ok) print(data) def clear_layout(self, layout): for i in reversed(range(layout.count())): layout.itemAt(i).widget().setParent(None) def open_eml(self, obj): file_name, _ = QFileDialog.getOpenFileName(self, "選取檔案", "./", "Eml Files (*.eml)") obj.setText(file_name) def open_excel(self, obj): file_name, _ = QFileDialog.getOpenFileName(self, "選取檔案", "./", "Excel Files (*.xlsx)") obj.setText(file_name) def open_word(self, obj): file_name, _ = QFileDialog.getOpenFileName(self, "選取檔案", "./", "Word Files (*.doc *.docx)") obj.setText(file_name) def open_annex(self, obj): file_name, _ = QFileDialog.getOpenFileName(self, "選取檔案", "./", "Annex Files (*.jpg *.png *.zip)") org_files = obj.text() all_files = org_files + ',' + file_name if org_files else file_name obj.setText(all_files) def print_html(self, index): if index: self.in_edit_web.setHtml(self.in_edit_html.toPlainText()) def send_mail(self): eml_type = self.in_eml_type.text() eml_file = self.in_eml_template.text() user_group = self.in_recipient_group.text() mail_excel = self.in_recipient_excel.text() annex_file = self.in_annex_file.text() url = self.data_db[5] if self.data_db else 'http://yumail.myvnc.com' try: if self.cb_scheduler.isChecked(): my_time = self.in_scheduler.text()+':00' client = Client() client.send(self.data_smtp[:4], self.data_db[:5], eml_type, eml_file, user_group, mail_excel, annex_file, url, my_time) QMessageBox.information(self, 'Success!', '排程設定成功!', QMessageBox.Ok) else: sm = Smtp(self.data_smtp[0], int(self.data_smtp[1]), self.data_smtp[2], self.data_smtp[3]) if self.data_smtp else Smtp() db = Database(self.data_db[0], int(self.data_db[1]), self.data_db[2], self.data_db[3], self.data_db[4]) if self.data_db else Database() insert_send_mail(eml_type, eml_file, user_group, mail_excel, sm, db, annex=annex_file, url=url) sm.close() db.__disconnect__() QMessageBox.information(self, 'Success!', '信件寄出成功!', QMessageBox.Ok) except: QMessageBox.warning(self, 'Failed!', '信件寄出失敗!', QMessageBox.Ok) def show_sub_win(self): if self.data_smtp: self.sub_win = SubWindow() self.sub_win.btn_send.clicked.connect(self.send_test) self.sub_win.show() else: QMessageBox.warning(self, 'Failed!', '請確認有無 SMTP 資料!', QMessageBox.Ok) def send_test(self): try: if self.data_smtp: mailserver = Smtp(self.data_smtp[0], int(self.data_smtp[1]), self.data_smtp[2], self.data_smtp[3]) mail_msg = gm.gen_test_eml(['Test Email', '測試寄件人', self.data_smtp[2], self.sub_win.in_recipient.text()], self.data_smtp[5]) error = mailserver.send(mail_msg.as_string(), self.data_smtp[2], self.sub_win.in_recipient.text()) mailserver.close() if error: QMessageBox.warning(self, 'Warning!', '信件寄出成功!\nWaning: '+error, QMessageBox.Ok) else: QMessageBox.information(self, 'Success!', '信件寄出成功!', QMessageBox.Ok) self.sub_win.in_recipient.clear() except: QMessageBox.warning(self, 'Failed!', '信件寄出失敗!', QMessageBox.Ok) def eml_open(self): self.in_edit_html.clear() file_name, _ = QFileDialog.getOpenFileName(self, "選取檔案", "./", "Eml Files (*.eml)") if not file_name: return header, html = gm.get_msg(file_name) self.in_edit_sender.setText(header[2]) self.in_edit_sender_name.setText(header[1]) self.in_edit_subject.setText(header[0]) self.in_edit_html.insertPlainText(html) def eml_save(self): header, msg = [], '' header.append(self.in_edit_subject.text()) header.append(self.in_edit_sender_name.text()) header.append(self.in_edit_sender.text()) header.append('*****@*****.**') annex_file = self.in_edit_annex.text().split(',') html = self.in_edit_html.toPlainText() if not any(header[:3]) or not html: return try: msg = gm.gen_eml(header, html, annex_file) if self.cb_edit_annex.isChecked() else gm.gen_eml(header, html) file_path, _ = QFileDialog.getSaveFileName(self, '另存為...', './', 'Excel Files (*.eml)') with open(file_path, 'w') as outfile: gen = generator.Generator(outfile) gen.flatten(msg) QMessageBox.information(self, 'Success!', '儲存成功!', QMessageBox.Ok) except: QMessageBox.warning(self, 'Failed!', '儲存失敗!', QMessageBox.Ok) def eml_reset(self): items = self.get_items_from_layout(self.right_layout) for item in items: if type(item) == type(QLineEdit()): item.clear() self.cb_edit_annex.setChecked(False) self.in_edit_html.clear() def logs_change(self): if not self.data_logs or not self.in_logs_data.text(): return self.data_temp_logs = [] self.tbw_logs.setRowCount(0) # header = {'郵件類型':'type', '郵件主旨':'subject', '使用者群組':'user_group', '使用者信箱':'user_email'} condition = self.cmb_logs_choice.currentText() content = self.in_logs_data.text() row_num = len(self.data_logs) col_num = len(self.data_logs[0]) # self.tbw_logs.setRowCount(row_num) self.tbw_logs.setColumnCount(col_num) for i in range(row_num): switch = False if condition == 'date' and content in str(self.data_logs[i][condition]): switch = True elif self.data_logs[i][condition] == content: switch = True if switch: self.tbw_logs.insertRow(self.tbw_logs.rowCount()) row_data = list(self.data_logs[i].values()) self.data_temp_logs.append(self.data_logs[i]) for j in range(col_num): temp_data = row_data[j] item = QTableWidgetItem(str(temp_data)) item.setForeground(QBrush(QColor(144, 182, 240))) self.tbw_logs.setItem(self.tbw_logs.rowCount()-1, j, item) def logs_download(self): if self.data_temp_logs: try: file_path, _ = QFileDialog.getSaveFileName(self, '另存為...', './', 'Excel Files (*.xlsx)') if not file_path: return df = DataFrame(self.data_temp_logs) df.to_excel(file_path, index=False) QMessageBox.information(self, 'Success!', '儲存成功!', QMessageBox.Ok) except: QMessageBox.warning(self, 'Failed!', '儲存失敗!', QMessageBox.Ok) else: QMessageBox.warning(self, "缺少資料", "請確認是否有資料可以下載", QMessageBox.Ok) def quit_act(self): # sender 是发送信号的对象 sender = self.sender() print(sender.text() + '键被按下') qApp = QApplication.instance() qApp.quit()
class AnalyzerUi(QWidget): task_finish_signal = pyqtSignal() TABLE_HEADER_SELECTOR = ['', 'Selector', 'Comments', 'UUID', 'Status'] TABLE_HEADER_ANALYZER = ['', 'Strategy', 'Comments', 'UUID', 'Status'] def __init__(self, data_hub_entry: DataHubEntry, strategy_entry: StrategyEntry): super(AnalyzerUi, self).__init__() self.__data_hub_entry = data_hub_entry self.__strategy_entry = strategy_entry self.__analyzer_info = self.__strategy_entry.analyzer_info() # Thread and task related self.__selector_list = [] self.__analyzer_list = [] self.__result_output = StockAnalysisSystem().get_project_path() self.__timing_clock = Clock() self.__progress_rate = ProgressRate() self.task_finish_signal.connect(self.__on_task_done) # Timer for update status self.__timer = QTimer() self.__timer.setInterval(1000) self.__timer.timeout.connect(self.on_timer) self.__timer.start() # UI related group, layout = create_v_group_box('Selector') self.__group_selector = group self.__layout_selector = layout group, layout = create_v_group_box('Analyzer') self.__group_analyzer = group self.__layout_analyzer = layout group, layout = create_v_group_box('Option') self.__group_option = group self.__layout_option = layout group, layout = create_h_group_box('Result') self.__group_result = group self.__layout_result = layout self.__table_selector = TableViewEx() self.__table_analyzer = TableViewEx() # self.__radio_group_selector = QButtonGroup(self) # self.__radio_all = QRadioButton('All') # self.__radio_tags = QRadioButton('Tags') # self.__radio_manual = QRadioButton('Manual') # self.__table_preview = QTableWidget() self.__check_force_calc = QCheckBox('Force Calc') self.__check_auto_cache = QCheckBox('Cache Result') self.__check_load_json = QCheckBox('Load Json') self.__check_dump_json = QCheckBox('Dump Json') self.__check_load_dump_all = QCheckBox('Load/Dump All') self.__datetime_time_since = QDateTimeEdit(years_ago(5)) self.__datetime_time_until = QDateTimeEdit(now()) self.__edit_path = QLineEdit('analysis_report.xlsx') self.__button_browse = QPushButton('Browse') self.__button_selector = QPushButton('Selector') self.__button_analyzer = QPushButton('Analyzer') self.__button_result = QPushButton('Result') self.__button_run_strategy = QPushButton('Run Strategy') self.__check_attach_basic_index = QCheckBox('Attach Basic Index') self.init_ui() self.update_selector() self.update_analyzer() # ---------------------------------------------------- UI Init ----------------------------------------------------- def init_ui(self): self.__layout_control() self.__config_control() def __layout_control(self): main_layout = QVBoxLayout() self.setLayout(main_layout) self.setMinimumSize(600, 400) self.__layout_selector.addWidget(self.__table_selector) main_layout.addWidget(self.__group_selector) self.__layout_analyzer.addWidget(self.__table_analyzer) main_layout.addWidget(self.__group_analyzer) self.__layout_result.addWidget(self.__edit_path) self.__layout_result.addWidget(self.__button_browse) main_layout.addWidget(self.__group_result) grid_layout = QGridLayout() grid_layout.addWidget(self.__check_force_calc, 0, 0) grid_layout.addWidget(self.__check_auto_cache, 1, 0) grid_layout.addWidget(self.__check_load_json, 0, 1) grid_layout.addWidget(self.__check_dump_json, 1, 1) grid_layout.addWidget(QLabel(' '), 0, 2) grid_layout.addWidget(QLabel(' '), 0, 2) grid_layout.addWidget(QLabel('Since'), 0, 3) grid_layout.addWidget(QLabel('Until'), 1, 3) grid_layout.addWidget(self.__datetime_time_since, 0, 4) grid_layout.addWidget(self.__datetime_time_until, 1, 4) grid_layout.addWidget(self.__check_attach_basic_index, 2, 0, 3, 1) grid_layout.addWidget(self.__check_load_dump_all, 2, 1, 3, 1) self.__layout_option.addLayout(grid_layout) main_layout.addWidget(self.__group_option) bottom_control_area = QHBoxLayout() main_layout.addLayout(bottom_control_area) bottom_control_area.addWidget(QLabel('Strategy Flow: '), 99) bottom_control_area.addWidget(self.__button_selector) bottom_control_area.addWidget(QLabel('==>')) bottom_control_area.addWidget(self.__button_analyzer) bottom_control_area.addWidget(QLabel('==>')) bottom_control_area.addWidget(self.__button_result) bottom_control_area.addWidget(QLabel(' | ')) bottom_control_area.addWidget(self.__button_run_strategy) def __config_control(self): self.__table_selector.SetCheckableColumn(0) self.__table_selector.SetColumn(AnalyzerUi.TABLE_HEADER_SELECTOR) self.__table_selector.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.__table_analyzer.SetCheckableColumn(0) self.__table_analyzer.SetColumn(AnalyzerUi.TABLE_HEADER_ANALYZER) self.__table_analyzer.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.__check_auto_cache.setChecked(True) self.__datetime_time_since.setCalendarPopup(True) self.__datetime_time_until.setCalendarPopup(True) self.__check_force_calc.setToolTip('勾选此项后,程序将不会从缓存中读取分析结果,并强制进行实时计算。') self.__check_auto_cache.setToolTip('勾选此项后,程序会自动缓存分析结果到SasCache数据库') self.__check_load_json.setToolTip('仅供Debug:从JSON文件中载入分析结果') self.__check_dump_json.setToolTip('仅供Debug:将分析结果写入JSON文件中') self.__check_load_dump_all.setToolTip( '仅供Debug:载入/保存所有结果而不是按Analyzer分别载入/保存') self.__layout_selector.setSpacing(0) self.__layout_analyzer.setSpacing(0) self.__layout_option.setSpacing(0) self.__layout_result.setSpacing(0) self.__layout_selector.setContentsMargins(0, 0, 0, 0) self.__layout_analyzer.setContentsMargins(0, 0, 0, 0) # self.__layout_result.setContentsMargins(0, 0, 0, 0) self.__button_result.clicked.connect(self.on_button_browse) self.__button_browse.clicked.connect(self.on_button_browse) self.__button_selector.clicked.connect(self.on_button_selector) self.__button_analyzer.clicked.connect(self.on_button_analyzer) self.__button_run_strategy.clicked.connect(self.on_button_run_strategy) def on_button_browse(self): file_path, ok = QFileDialog.getSaveFileName( self, 'Select Result Excel Path', '', 'XLSX Files (*.xlsx);;All Files (*)') if ok: self.__edit_path.setText(file_path) def on_button_selector(self): self.__group_selector.setVisible(True) self.__group_analyzer.setVisible(not self.__group_analyzer.isVisible()) def on_button_analyzer(self): self.__group_analyzer.setVisible(True) self.__group_selector.setVisible(not self.__group_selector.isVisible()) def on_button_run_strategy(self): selector_list = [] analyzer_list = [] output_path = self.__edit_path.text() if len(output_path.strip()) == 0: QMessageBox.information( self, QtCore.QCoreApplication.translate('', '配置缺失'), QtCore.QCoreApplication.translate('', '请指定结果输出文件'), QMessageBox.Close, QMessageBox.Close) for i in range(self.__table_analyzer.RowCount()): if self.__table_analyzer.GetItemCheckState(i, 0) == QtCore.Qt.Checked: uuid = self.__table_analyzer.GetItemText(i, 3) analyzer_list.append(uuid) if len(analyzer_list) == 0: QMessageBox.information(None, '提示', '请至少选择一个分析方法') return self.__selector_list = selector_list self.__analyzer_list = analyzer_list self.__result_output = output_path self.execute_update_task() def on_timer(self): for i in range(self.__table_analyzer.RowCount()): uuid = self.__table_analyzer.GetItemText(i, 3) if self.__progress_rate.has_progress(uuid): rate = self.__progress_rate.get_progress_rate(uuid) self.__table_analyzer.SetItemText(i, 4, '%.2f%%' % (rate * 100)) else: self.__table_analyzer.SetItemText(i, 4, '') def closeEvent(self, event): if self.__task_thread is not None: QMessageBox.information( self, QtCore.QCoreApplication.translate('', '无法关闭窗口'), QtCore.QCoreApplication.translate('', '策略运行过程中无法关闭此窗口'), QMessageBox.Close, QMessageBox.Close) event.ignore() else: event.accept() # -------------------------------------------------------------------------------------- def update_selector(self): self.__table_selector.Clear() self.__table_selector.SetRowCount(0) self.__table_selector.SetColumn(AnalyzerUi.TABLE_HEADER_SELECTOR) self.__table_selector.AppendRow( ['', '所有股票', '当前只支持所有股票,不选默认也是所有股票', '-']) # Add check box # check_item = QTableWidgetItem() # check_item.setCheckState(QtCore.Qt.Unchecked) # self.__table_selector.setItem(0, 0, check_item) def update_analyzer(self): self.__table_analyzer.Clear() self.__table_analyzer.SetRowCount(0) self.__table_analyzer.SetColumn(AnalyzerUi.TABLE_HEADER_ANALYZER) for method_uuid, method_name, method_detail, _ in self.__analyzer_info: line = [ '', # Place holder for check box method_name, method_detail, method_uuid, '', # Place holder for status ] self.__table_analyzer.AppendRow(line) # index = self.__table_analyzer.RowCount() - 1 # Add check box # check_item = QTableWidgetItem() # check_item.setCheckState(QtCore.Qt.Unchecked) # self.__table_analyzer.setItem(index, 0, check_item) # -------------------------------------------------------------------------- # def load_analyzer_info(self) -> [(str, str, str)]: # info = [] # probs = self.__strategy_entry.strategy_prob() # for prob in probs: # methods = prob.get('methods', []) # for method in methods: # method_uuid = method[0] # method_name = method[1] # method_detail = method[2] # method_entry = method[3] # if method_entry is not None and '测试' not in method_name: # # Notice the item order # info.append([method_uuid, method_name, method_detail]) # return info # --------------------------------- Thread --------------------------------- def execute_update_task(self): options = AnalysisTask.OPTION_CALC if not self.__check_force_calc.isChecked(): options |= AnalysisTask.OPTION_FROM_CACHE if self.__check_auto_cache.isChecked(): options |= AnalysisTask.OPTION_UPDATE_CACHE if self.__check_load_json.isChecked(): options |= AnalysisTask.OPTION_LOAD_JSON if self.__check_dump_json.isChecked(): options |= AnalysisTask.OPTION_DUMP_JSON if self.__check_load_dump_all.isChecked(): options |= AnalysisTask.OPTION_LOAD_DUMP_ALL if self.__check_attach_basic_index.isChecked(): options |= AnalysisTask.OPTION_ATTACH_BASIC_INDEX time_serial = (to_py_datetime(self.__datetime_time_since.dateTime()), to_py_datetime(self.__datetime_time_until.dateTime())) self.__timing_clock.reset() task = AnalysisTask(self, self.__strategy_entry, self.__data_hub_entry, self.__selector_list, self.__analyzer_list, time_serial, options, self.__result_output, self.__progress_rate) StockAnalysisSystem().get_task_queue().append_task(task) # if self.__task_thread is None: # self.__task_thread = threading.Thread(target=self.ui_task) # StockAnalysisSystem().lock_sys_quit() # self.__timing_clock.reset() # self.__task_thread.start() # else: # print('Task already running...') # QMessageBox.information(self, # QtCore.QCoreApplication.translate('', '无法执行'), # QtCore.QCoreApplication.translate('', '已经有策略在运行中,无法同时运行多个策略'), # QMessageBox.Close, QMessageBox.Close) # def ui_task(self): # print('Strategy task start.') # # self.__lock.acquire() # selector_list = self.__selector_list # analyzer_list = self.__analyzer_list # output_path = self.__result_output # self.__lock.release() # # data_utility = self.__data_hub_entry.get_data_utility() # stock_list = data_utility.get_stock_identities() # # self.__progress_rate.reset() # # # ------------- Run analyzer ------------- # clock = Clock() # # # result = self.__strategy_entry.run_strategy(stock_list, analyzer_list, progress=self.__progress_rate) # # total_result = [] # uncached_analyzer = [] # # for analyzer in analyzer_list: # result = self.__strategy_entry.result_from_cache('Result.Analyzer', analyzer=analyzer) # if result is None or len(result) == 0: # uncached_analyzer.append(analyzer) # result = self.__strategy_entry.run_strategy(stock_list, [analyzer], progress=self.__progress_rate) # else: # self.__progress_rate.finish_progress(analyzer) # if result is not None and len(result) > 0: # total_result.extend(result) # # # DEBUG: Load result from json file # # result = None # # with open('analysis_result.json', 'rt') as f: # # result = analysis_results_from_json(f) # # if result is None: # # return # # print('Analysis time spending: ' + str(clock.elapsed_s()) + ' s') # # # # DEBUG: Dump result to json file # # with open('analysis_result.json', 'wt') as f: # # analysis_results_to_json(result, f) # # # self.__strategy_entry.cache_analysis_result('Result.Analyzer', result) # result2 = self.__strategy_entry.result_from_cache('Result.Analyzer') # print(result2) # # result = analysis_result_dataframe_to_list(result2) # print(result) # # # ------------ Parse to Table ------------ # # result_table = analysis_result_list_to_analyzer_security_table(result) # # # ----------- Generate report ------------ # clock.reset() # stock_list = self.__data_hub_entry.get_data_utility().get_stock_list() # stock_dict = {_id: _name for _id, _name in stock_list} # name_dict = self.__strategy_entry.strategy_name_dict() # generate_analysis_report(result_table, output_path, name_dict, stock_dict) # print('Generate report time spending: ' + str(clock.elapsed_s()) + ' s') # # # ----------------- End ------------------ # self.task_finish_signal.emit() # print('Update task finished.') # --------------------------------------------------------------------------------- def notify_task_done(self): self.task_finish_signal.emit() def __on_task_done(self): StockAnalysisSystem().release_sys_quit() QMessageBox.information( self, QtCore.QCoreApplication.translate('main', '远行完成'), QtCore.QCoreApplication.translate( 'main', '策略运行完成,耗时' + str(self.__timing_clock.elapsed_s()) + '秒\n' + '报告生成路径:' + self.__result_output), QMessageBox.Ok, QMessageBox.Ok)
def setupTab2(self, tab2): """Special widgets for preview panel""" scrollContainer = QVBoxLayout() scrollArea = QScrollArea() scrollArea.setWidgetResizable(True) mainWidget = QWidget() layout = QVBoxLayout() mainWidget.setLayout(layout) mainWidget.setMinimumSize(QSize(420, 800)) scrollArea.setWidget(mainWidget) scrollContainer.addWidget(scrollArea) tab2.setLayout(scrollContainer) # Dialog group0 = QGroupBox("Dialog") group1Layout = QVBoxLayout() layoutRow1 = QHBoxLayout() layoutRow2 = QHBoxLayout() group1Layout.addLayout(layoutRow1) group1Layout.addLayout(layoutRow2) group0.setLayout(group1Layout) layout.addWidget(group0) b1 = QPushButton(self.tr("Info")) b1.clicked.connect(lambda: QMessageBox.information( self, "Info", self.tr("This is a message."), QMessageBox.Ok, QMessageBox.Ok)) b2 = QPushButton(self.tr("Question")) b2.clicked.connect(lambda: QMessageBox.question( self, "question", self.tr("Are you sure?"), QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes)) b3 = QPushButton(self.tr("Warning")) b3.clicked.connect(lambda: QMessageBox.warning( self, "warning", self.tr("This is a warning."), QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes)) b4 = QPushButton(self.tr("Error")) b4.clicked.connect(lambda: QMessageBox.critical( self, "error", self.tr("It's a error."), QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes)) b5 = QPushButton(self.tr("About")) b5.clicked.connect(lambda: QMessageBox.about( self, "about", self.tr("About this software"))) b6 = QPushButton(self.tr("Input")) # ,"输入对话框")) b6.clicked.connect(lambda: QInputDialog.getInt( self, self.tr("input"), self.tr("please input int"))) b6.clicked.connect(lambda: QInputDialog.getDouble( self, self.tr("input"), self.tr("please input float"))) b6.clicked.connect(lambda: QInputDialog.getItem( self, self.tr("input"), self.tr("please select"), ["aaa", "bbb"])) b7 = QPushButton(self.tr("Color")) # ,"颜色对话框")) b7.clicked.connect(lambda: QColorDialog.getColor()) b8 = QPushButton(self.tr("Font")) # ,"字体对话框")) b8.clicked.connect(lambda: QFontDialog.getFont()) b9 = QPushButton(self.tr("OpenFile")) # ,"打开对话框")) b9.clicked.connect(lambda: QFileDialog.getOpenFileName( self, "open", "", "Text(*.txt *.text)")) b10 = QPushButton(self.tr("SaveFile")) # ,"保存对话框")) b10.clicked.connect(lambda: QFileDialog.getSaveFileName()) layoutRow1.addWidget(b1) layoutRow1.addWidget(b2) layoutRow1.addWidget(b3) layoutRow1.addWidget(b4) layoutRow1.addWidget(b5) layoutRow2.addWidget(b6) layoutRow2.addWidget(b7) layoutRow2.addWidget(b8) layoutRow2.addWidget(b9) layoutRow2.addWidget(b10) # DateTime group1 = QGroupBox("DateTime") group1.setCheckable(True) group1Layout = QHBoxLayout() layoutRow1 = QVBoxLayout() layoutRow2 = QVBoxLayout() group1Layout.addLayout(layoutRow1) group1Layout.addLayout(layoutRow2) group1.setLayout(group1Layout) layout.addWidget(group1) group1.setMaximumHeight(240) dt1 = QDateEdit() dt1.setDate(QDate.currentDate()) dt2 = QTimeEdit() dt2.setTime(QTime.currentTime()) dt3 = QDateTimeEdit() dt3.setDateTime(QDateTime.currentDateTime()) dt4 = QDateTimeEdit() dt4.setCalendarPopup(True) dt5 = QCalendarWidget() dt5.setMaximumSize(QSize(250, 240)) layoutRow1.addWidget(dt1) layoutRow1.addWidget(dt2) layoutRow1.addWidget(dt3) layoutRow1.addWidget(dt4) layoutRow2.addWidget(dt5) # Slider group2 = QGroupBox("Sliders") group2.setCheckable(True) group2Layout = QVBoxLayout() layoutRow1 = QHBoxLayout() layoutRow2 = QHBoxLayout() group2Layout.addLayout(layoutRow1) group2Layout.addLayout(layoutRow2) group2.setLayout(group2Layout) layout.addWidget(group2) slider = QSlider() slider.setOrientation(Qt.Horizontal) slider.setMaximum(100) progress = QProgressBar() slider.valueChanged.connect(progress.setValue) slider.setValue(50) scroll1 = QScrollBar() scroll2 = QScrollBar() scroll3 = QScrollBar() scroll1.setMaximum(255) scroll2.setMaximum(255) scroll3.setMaximum(255) scroll1.setOrientation(Qt.Horizontal) scroll2.setOrientation(Qt.Horizontal) scroll3.setOrientation(Qt.Horizontal) c = QLabel(self.tr("Slide to change color")) # , "拖动滑块改变颜色")) c.setAutoFillBackground(True) c.setAlignment(Qt.AlignCenter) # c.setStyleSheet("border:1px solid gray;") c.setStyleSheet("background:rgba(0,0,0,100);") def clr(): # clr=QColor(scroll1.getValue(),scroll2.getValue(),scroll3.getValue(),100) # p=QPalette() # p.setColor(QPalette.Background,clr) # c.setPalette(p) c.setStyleSheet("background: rgba({},{},{},100);".format( scroll1.value(), scroll2.value(), scroll3.value())) scroll1.valueChanged.connect(clr) scroll2.valueChanged.connect(clr) scroll3.valueChanged.connect(clr) scroll1.setValue(128) layoutRow1.addWidget(slider) layoutRow1.addWidget(progress) layCol1 = QVBoxLayout() layCol1.addWidget(scroll1) layCol1.addWidget(scroll2) layCol1.addWidget(scroll3) layoutRow2.addLayout(layCol1) layoutRow2.addWidget(c) # Meter group3 = QGroupBox("Meters") group3.setCheckable(True) layRow = QHBoxLayout() group3.setLayout(layRow) layout.addWidget(group3) dial1 = QDial() dial2 = QDial() dial2.setNotchesVisible(True) dial1.valueChanged.connect(dial2.setValue) layRow.addWidget(dial1) layRow.addWidget(dial2) layout.addStretch(1)