简单界面(PYQT5)

目录

前言

结构说明

①创建元素 分类管理元素,新增的界面元素都按照各自的类别分别管理。

②排版 在widget_content列表里,按照预想的位置去排列元素.

③修改样式

代码

优点


前言

python开发的脚本总是要配合界面才会好用.平时,添加一些功能就要调整一下界面.

现在,改出一个通用版本,方便快速的调整界面.

结构说明

①创建元素 分类管理元素,新增的界面元素都按照各自的类别分别管理。

# 创建按钮
self._setting_btn()
# 创建标签信息
self._setting_label()
# 创建文本输入框
self._setting_text_edit()
# 创建 选择框
self._setting_combo()

②排版 在widget_content列表里,按照预想的位置去排列元素.

__核心方法__ self.__setting_layout()

        widget_content = [
            # 第一行第一个
            [self.lb_file2],
            # 第二行 并排多个
            [self.bt_file2, self.edit_file2],
            [self.bt_file, self.edit_file],
            [self.bt_clear_file2, self.bt_combine_file],
            [self.lb_setting],
            # 数组嵌套  前者在上面(标签说明),后者在下面(输入框)
            [[self.bt_setting], [self.lb_input_num, self.input_num],
             [self.lb_unit, self.cb_units], [self.lb_time, self.cb_time]],
            [self.lb_file],
            [self.bt_file, self.edit_file],
            [self.bt_clear_file, self.bt_split],
            [self.lb_process]
        ]

③修改样式

调整edit_style的内容

样式表
属性作用
:checked按钮控件被选中
:unchecked按钮控件未被选中
:indeterminate对于checkBox或者redioButton部分选中
:hover鼠标放上去
:pressed按下
:focus获取焦点
:disabled控件禁用
:enabled控件启用
:on可用
:off关闭
background-color背景颜色
color字体颜色
border边框宽度
border-radius边框圆角
font-size字体大小
font-family字体类型(Times New Roman)

代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :my_interface.py
# @Time      :2022/7/19 11:10
# @Author    :Marst


"""
task:
 step1
 step2
 ...
"""
import datetime
import os
import shutil
import sys
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QFont, QIntValidator
from PyQt5.QtWidgets import QMainWindow, QStatusBar, QProgressBar, QApplication, QPushButton, QComboBox, QLineEdit, \
    QWidget, QVBoxLayout, QHBoxLayout
from PyQt5.QtWidgets import QTextEdit, QFileDialog, QLabel, QMessageBox

sys.path.append('..')

today_date = datetime.datetime.now().strftime("%F")
DEFAULT_TIP = "请选择或拖拽file(CSV)文件到框中"
DEFAULT_TIP2 = "请选择或拖拽file2(CSV)文件到框中"
DEFAULT_TIP3 = "请选择或拖拽file(CSV)文件到框中"
DEFAULT_TIP_Items = "(可选)请拖拽存放位置到框中"

DEFAULT_LABEL_TEXT_file2 = "①file2文件路径"
DEFAULT_LABEL_TEXT_PARA = "②参数设定"
DEFAULT_LABEL_TEXT_file = "③file文件路径"

DEFAULT_LABEL_TEXT_Items = "时间误差"
DEFAULT_LABEL_TEXT2 = "file Unit"
DEFAULT_LABEL_Time = "file Start Time"

INTRODUTION_REPORT = "①选file2文件,点击下方对应 Clear按钮;\n" \
                     "②设定参数;\n" \
                     "③选file文件,点击下方对应 Clear按钮;\n" \
                     "④最后点击Run按钮,开始合并数据."

REPORT_FOLDER = ""
TODAY_FOLDER = ""
REPORT_SETTING = {}
version = "0.0.1"


class ComboxTime(QWidget):

    def __init__(self, time_list=None, parent=None):
        super(ComboxTime, self).__init__(parent)
        self.setWindowTitle("选择初始时间")
        self.resize(420, 90)

        layout = QVBoxLayout()
        self.lb = QLabel()

        if time_list:
            self.cb_time.addItems(time_list)

        layout.addWidget(self.cb_time)
        layout.addWidget(self.lb)
        self.setLayout(layout)


class ReportTool(QMainWindow):
    window_title = f'ReportTool v{version} Marst'

    tool_x, tool_y = 770, 700
    # 设置按钮控件大小
    w, h = 90, 25
    pos_x, pos_y = 15, 25
    delta_y = 150
    tx_pos_x, tx_w = 210, 900

    select_cbox_items = ["数据合并", "批量处理"]

    select_ct = ["left", "right"]

    edit_style = """
    QTextEdit{background:#F5F5DC;border:1px solid white;border-radius:5px;font-weight:bold;font-size:9px}
    QComboBox{border:1px solid white;font-size:12px;}
    QLineEdit{border:1px solid white;font-size:12px;}
    QPushButton{font-weight:bold;font-size:18px;background-color:#ff4c41;font-family:'Arial';color:#ffffff;
    border:1px solid white;border-radius:6px}
    QPushButton:hover{background-color:rgb(44,169,225);border:1px solid rgb(44,169,225)}
            QPushButton:disabled{background-color:#a9b6bb}
    QLabel{font-weight:bold;font-size:11px;}
    #Anc{font-size:12px;font-family:'Arial';color:#0968F7}
    #mode{font-size:26px;font-family:'Arial';color:black}
    #RunBt:hover{background-color:#22DD92}
    #RunBt:disabled{background-color:#a9b6bb}
    #RunBt{font-weight:bold;font-size:29px;background-color:rgb(44,169,225);border:1px solid white;border-radius:6px;};
    background-color:#FFEBCD;color:#2B2B2B;
    """

    def __init__(self):
        super().__init__()
        self.csv_path = None
        self.target_path = None
        self.value = 0
        self.worker = None

        self.start_time_file2 = REPORT_SETTING.get('start_time_file2')
        self.start_time_file = None
        self.file_data = None
        self.file2_data = None
        self.unit_pos = None
        self.show_msg_list = []

        # 输入框
        self.input_num = self.create_validator()
        self.input_num.setText(f"{REPORT_SETTING.get('time', 5)}")
        self.input_num.setToolTip(f"file2与file的时间差范围值")
        self.input_num.setFixedWidth(38)
        self.input_num.setFixedHeight(self.h)
        # 创建按钮
        self._setting_btn()
        # 创建标签信息
        self._setting_label()
        # 创建文本输入框
        self._setting_text_edit()
        # 创建 选择框
        self._setting_combo()
        # 状态栏
        self.statusBar = QStatusBar(self)
        # 进度条
        self.progressBar = QProgressBar()

        self.__setting_layout()

        self.init_ui()
        self.setStyleSheet(self.edit_style)

    def __setting_layout(self):
        # 主要布局
        self.mainLayout = QVBoxLayout(self)

        # 顶层的设定
        header_layout = QHBoxLayout()
        header_widget = QWidget()
        header_layout.addStretch(1)
        header_layout.addWidget(self.label_mode)
        header_layout.addWidget(self.cb_mode)
        header_layout.addStretch(9)
        header_layout.addWidget(self.label_introdution)
        header_widget.setLayout(header_layout)
        self.mainLayout.addWidget(header_widget)
        widget_content = [
            [self.lb_file2],
            [self.bt_file2, self.edit_file2],
            [self.bt_file, self.edit_file],
            [self.bt_clear_file2, self.bt_combine_file],
            [self.lb_setting],
            [[self.bt_setting], [self.lb_input_num, self.input_num],
             [self.lb_unit, self.cb_units], [self.lb_time, self.cb_time]],
            [self.lb_file],
            [self.bt_file, self.edit_file],
            [self.bt_clear_file, self.bt_split],
            [self.lb_process]
        ]

        for y, row_line in enumerate(widget_content):
            temp_layout = QHBoxLayout()
            temp_widget = QWidget()
            for x, wid in enumerate(row_line):
                if x == 0:
                    temp_layout.addSpacing(5)

                if isinstance(wid, list):
                    vtemp_layout = QVBoxLayout()
                    vtemp_widget = QWidget()
                    for _ in wid:
                        vtemp_layout.addWidget(_)
                    vtemp_layout.addSpacing(1)
                    vtemp_widget.setLayout(vtemp_layout)
                    temp_layout.addWidget(vtemp_widget)
                    temp_layout.addStretch(2)
                else:
                    temp_layout.addWidget(wid)

            temp_widget.setLayout(temp_layout)
            self.mainLayout.addWidget(temp_widget)
            self.mainLayout.addStretch(2)

        # 布局生效
        widget = QWidget()
        widget.setLayout(self.mainLayout)
        self.setCentralWidget(widget)
        self.setLayout(self.mainLayout)

    def _setting_btn(self):
        self.bt_file = QPushButton('&file', self)
        self.bt_file.setToolTip("选取CT文件")
        self.bt_file.setFixedWidth(self.w)

        self.bt_clear_file = QPushButton('Clear', self)
        self.bt_clear_file.setToolTip("对CT文件进行预处理")
        self.bt_clear_file.setFixedWidth(self.w)

        self.bt_file2 = QPushButton('&file2', self)
        self.bt_file2.setToolTip("选取file2文件")
        self.bt_file2.setFixedWidth(self.w)

        self.bt_file = QPushButton('file', self)
        self.bt_file.setToolTip("选取file文件")
        self.bt_file.setFixedWidth(self.w)

        self.bt_clear_file2 = QPushButton('Clear', self)
        self.bt_clear_file2.setToolTip("对file2文件进行预处理")
        self.bt_clear_file2.setFixedWidth(self.w)

        self.bt_combine_file = QPushButton('Combine', self)
        self.bt_combine_file.setToolTip("合并file文件")
        self.bt_combine_file.setFixedWidth(self.w)

        self.bt_setting = QPushButton('Setting', self)
        self.bt_setting.setToolTip("保存设定参数,包括文件的路径等")
        self.bt_setting.setFixedWidth(self.w)

        self.bt_run = QPushButton('&RUN', self)
        self.bt_run.setObjectName("RunBt")

        self.bt_split = QPushButton('Split', self)
        self.bt_split.setObjectName("SplitBt")
        self.bt_split.setFixedWidth(self.w)
        self.bt_split.setToolTip("将文件拆分成两半.")

        # 实行按钮功能
        self.bt_file.clicked.connect(self.open_csv_file)
        self.bt_clear_file.clicked.connect(self.func_one)
        self.bt_file2.clicked.connect(self.open_target_file)
        self.bt_file.clicked.connect(self.open_target_file_file)
        self.bt_clear_file2.clicked.connect(self.func_two)
        self.bt_combine_file.clicked.connect(self.func_combine_file)

        self.bt_setting.clicked.connect(self.update_setting)
        self.bt_split.clicked.connect(self.func_four)
        # 设置开始按钮
        self.bt_run.clicked.connect(self.start_process)

    def _setting_label(self):
        self.label_mode = QLabel(self)
        self.label_mode.setText("模式")
        self.label_mode.setObjectName("mode")

        self.label_introdution = QLabel(self)
        self.label_introdution.setText(INTRODUTION_REPORT)
        self.label_introdution.setObjectName("Anc")

        self.lb_file = QLabel(self)
        self.lb_file.setText(DEFAULT_LABEL_TEXT_file)

        self.lb_file2 = QLabel(self)
        self.lb_file2.setText(DEFAULT_LABEL_TEXT_file2)

        self.lb_setting = QLabel(self)
        self.lb_setting.setText(DEFAULT_LABEL_TEXT_PARA)

        self.lb_input_num = QLabel(self)
        self.lb_input_num.setText(DEFAULT_LABEL_TEXT_Items)

        self.lb_unit = QLabel(self)
        self.lb_unit.setText(DEFAULT_LABEL_TEXT2)

        self.lb_time_title = QLabel(self)
        self.lb_time_title.setText("时间误差")
        self.lb_time_title.setHidden(True)

        self.lb_time = QLabel(self)
        self.lb_time.setText(DEFAULT_LABEL_Time)

        self.lb_process = QLabel(self)
        # 设置状态标签
        self.show_msg('程序初始化成功!')

    def _setting_text_edit(self):
        self.edit_file = MyTextEdit(self)
        self.edit_file.setText(REPORT_SETTING.get("file_path", ""))
        self.edit_file.setFixedHeight(self.h)
        self.edit_file2 = MyTextEdit(self)
        self.edit_file2.setText(REPORT_SETTING.get("file2_path", ""))
        self.edit_file2.setFixedHeight(self.h)

        self.edit_file = MyTextEdit(self)
        self.edit_file.setText(REPORT_SETTING.get("file_path", ""))
        self.edit_file.setFixedHeight(self.h)

        self.tx3 = MyTextEdit(self)
        self.tx3.setHidden(True)
        self.edit_file.setPlaceholderText(DEFAULT_TIP)
        self.edit_file2.setPlaceholderText(DEFAULT_TIP2)
        self.edit_file.setPlaceholderText(DEFAULT_TIP3)

    def _setting_combo(self):
        self.cb_mode = QComboBox(self)
        self.cb_mode.addItems(self.select_cbox_items)
        self.cb_mode.currentIndexChanged.connect(self.model_selection_change)
        self.cb_mode.setFixedWidth(120)

        self.cb_units = QComboBox(self)
        self.cb_units.addItems(self.select_ct)
        self.cb_units.setToolTip(f"left 1,3,5,7\nright 2,4,6,8")
        self.cb_units.setFixedWidth(80)
        self.cb_units.setFixedHeight(self.h)

        self.cb_time = QComboBox(self)
        self.cb_time.setToolTip("设定file数据的开始时间")
        self.cb_time.setFixedWidth(200)
        self.cb_time.setFixedHeight(self.h)
        # file2_time_list
        _file2_time_list = REPORT_SETTING.get("file2_time_list")
        if _file2_time_list:
            self.cb_time.addItems(_file2_time_list)

    def init_ui(self):
        # 设置字体大小
        font = QFont()
        font.setFamily('STSong')
        font.setPointSize(9)
        self.setFont(font)
        self.setWindowTitle(self.window_title)

        # 定义状态栏
        self.setStatusBar(self.statusBar)
        self.statusBar.addPermanentWidget(self.bt_run, stretch=0)
        self.statusBar.addPermanentWidget(self.progressBar, stretch=2)
        self.progressBar.setRange(0, 100)  # 设置进度条的范围
        self.progressBar.setValue(0)
        self.setFixedSize(self.tool_y, self.tool_x)

    def hide_all(self, hide_val=False):
        hidden_list = [
            self.bt_file,
            self.bt_file2,
            self.edit_file,
            self.edit_file2,
            self.tx3,
            self.lb_time_title,
            self.lb_input_num,
            self.lb_unit,
            self.input_num,
            self.lb_file,
            self.lb_file2,
        ]
        for h in hidden_list:
            h.setHidden(hide_val)

    def model_selection_change(self):
        # 测试项筛选
        self.hide_all(False)

    def show_msg(self, val):
        if val:
            self.show_msg_list.append(f"{val}")

        str_val = '\n'.join(self.show_msg_list[-3:])
        self.lb_process.setText(str_val)

    def open_csv_file(self):
        self.edit_file.clear()
        # 文件夹
        # csv_path = QFileDialog.getExistingDirectory(self, '', './')
        # 单文件
        csv_path = QFileDialog.getOpenFileName(self, '选取csv文件', './')
        self.edit_file.setText(csv_path[0])
        self.bt_run.setEnabled(True)

    def func_one(self):
        """
        开始处理 file 文件
        :return:
        """

        csv_path = self.edit_file.toPlainText()
        if not os.path.exists(csv_path):
            self.show_msg(f"文件不存在,请检查 {csv_path}")
            QMessageBox.critical(self, "警告", f"文件不存在,请检查 {csv_path}")
            return

    def func_two(self):
        csv_path = self.edit_file2.toPlainText()
        if not os.path.exists(csv_path):
            self.show_msg(f"文件不存在,请检查 {csv_path}")
            QMessageBox.critical(self, "警告", f"文件不存在,请检查 {csv_path}")
            return

    def func_three(self):

        file_path = self.edit_file.toPlainText()
        self.show_msg(f"获取file文件 {file_path}")

    def open_target_file(self):
        """
        打开文件夹 只见xlsx文件
        :return:
        """
        self.edit_file2.clear()
        # files = QFileDialog.getOpenFileName(self, 'Open file', './', 'xlsx files (*.xlsx)')
        csv_path = QFileDialog.getOpenFileName(self, '选取csv文件', './')
        self.edit_file2.setText(csv_path[0])

    def open_target_file_file(self):
        """
        打开文件夹 只见xlsx文件
        :return:
        """
        self.edit_file.clear()
        # files = QFileDialog.getOpenFileName(self, 'Open file', './', 'xlsx files (*.xlsx)')
        csv_path = QFileDialog.getOpenFileName(self, '选取csv文件', './')
        self.edit_file.setText(csv_path[0])

    def update_setting(self):
        p = self.edit_file.toPlainText()
        if p:
            REPORT_SETTING["file_path"] = p

        p2 = self.edit_file2.toPlainText()
        if p2:
            REPORT_SETTING["file2_path"] = p2

        p3 = self.edit_file.toPlainText()
        if p3:
            REPORT_SETTING["file_path"] = p3

        time_range = int(self.input_num.text())
        REPORT_SETTING["time"] = time_range
        REPORT_SETTING["start_time_file2"] = self.start_time_file2
        self.show_msg(f"设定参数保存成功")

    def func_four(self):
        csv_path = self.edit_file.toPlainText()
        if not os.path.exists(csv_path):
            self.show_msg(f"文件不存在,请检查 {csv_path}")
            QMessageBox.critical(self, "警告", f"文件不存在,请检查 {csv_path}")
            return

    def func_combine_file(self):
        self.show_msg("combine")

    def create_validator(self):
        int_line_edit = QLineEdit(self)
        int_validator = QIntValidator(self)
        int_validator.setRange(1, 9999)
        int_line_edit.setValidator(int_validator)
        input_config_num = int_line_edit
        input_config_num.setPlaceholderText('输入数字')
        input_config_num.setFixedSize(130, 40)
        return input_config_num

    def start_process(self):
        model_text = self.cb_mode.currentText()
        if model_text == self.select_cbox_items[0]:
            if self.file2_data is None:
                self.show_msg(f"请先预处理file2文件, 对file2进行Clear")
                return

            if self.file_data is None:
                self.show_msg(f"请先预处理file文件, 对file进行Clear")
                return

            value = 0
            self.progressBar.setValue(value)
            self.show_msg("开始合并数据")
            self.bt_run.setEnabled(False)
            if self.file_data and self.file2_data:
                # 这句就很关键了
                self.lb_process.repaint()
                self.worker = ReportWorker(self.file_data, self.file2_data, self.end_process, self)
                self.worker.start()

        elif model_text == self.select_cbox_items[1]:
            ...

        else:
            self.show_msg('请选择要处理的文件!')

    def end_process(self, value):
        self.progressBar.setValue(value)
        if value == 100:
            del self.worker
            if os.path.exists('res_img'):
                shutil.rmtree('res_img')
        self.bt_run.setEnabled(True)


class ReportWorker(QThread):
    _signal = pyqtSignal(int)

    def __init__(self, file_data, file2_data, func, parent=None):
        super(ReportWorker, self).__init__()

        self.file_data = file_data
        self.file2_data = file2_data
        self.parent = parent
        self._signal.connect(func)

    def update_process_bar(self, val, count):
        value = int(val * 100 / count)
        if value <= 99:
            self._signal.emit(value)

    def run(self):
        try:
            self.parent.show_msg("start run")

        except Exception as e:
            self.parent.show_msg(e)
        self._signal.emit(100)


class MyTextEdit(QTextEdit):
    """实现文件拖放功能"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)  # 设置接受拖放动作

    def dragEnterEvent(self, e):
        if e.mimeData().text().endswith(''):  # 如果是.srt结尾的路径接受
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):  # 放下文件后的动作
        if os.name == 'nt':
            path = e.mimeData().text().replace('file:///', '')  # 删除多余开头
        else:
            path = e.mimeData().text().replace('file://', '')  # 删除多余开头
        self.setText(path)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ReportTool()
    ex.show()
    sys.exit(app.exec_())

优点

这个脚本的好处是快速便捷,使用时,只要创建新的元素,并通过修改widget_content列表的内容就可以马上产生自己想要的效果.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Marst·Zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值