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)
Example #2
0
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)
Example #4
0
    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)
Example #5
0
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()
Example #6
0
    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
Example #7
0
    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')
Example #8
0
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
Example #9
0
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)
Example #10
0
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))
Example #11
0
 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
Example #12
0
    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
Example #13
0
    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
Example #14
0
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
Example #16
0
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
Example #18
0
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())
Example #20
0
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))
Example #21
0
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())
Example #23
0
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()
Example #24
0
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)
Example #25
0
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
Example #26
0
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, "提示", "请输入正确的目的地!")
Example #27
0
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
Example #28
0
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()
Example #32
0
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)