Prueba PyQt5: aplicación basada en QTableWidget

Prueba PyQt5: aplicación basada en QTableWidget

Prefacio:

El contenido de este artículo se basa en el control QtableWidget, combinado con el pensamiento de cuatro cuadrantes de la administración del tiempo, para hacer una simple calculadora de prioridad de tareas. Necesita tener una cierta comprensión del lenguaje Python y la biblioteca PyQt5. Para una introducción rápida a PyQt5, puede leer la serie de artículos "Registro de prueba para principiantes PyQt5" (← clic).

Hoy en día, es una era de explosión de todas las categorías. Cada día tenemos que enfrentarnos a innumerables cosas nuevas, o todo tipo de conocimientos por aprender, o diversas tareas que se han planificado. Lo que es particularmente problemático es que, ¿Qué debo hacer primero? Hay todo tipo de aplicaciones de gestión del tiempo o planificación del trabajo en el mercado, que proporcionan una forma de aclarar ideas para las personas que sufren de dificultades de selección y dilación.

En mi trabajo de estudio diario, el autor también se siente angustiado por lo que se debe hacer primero en el lote de asuntos que se deben manejar. Después de comprender el pensamiento de los cuatro cuadrantes de la administración del tiempo, solo tenía ideas. A continuación, el autor presentará un método para programar tareas.
Inserte la descripción de la imagen aquí
( En resumen, tomé algo y probé la función de QTableWidget ) Los cuatro cuadrantes de administración del tiempo, como se muestra en la figura anterior. Con las dos etiquetas de importante y urgente, los asuntos se dividen en cuatro categorías, lo que puede hacer que los usuarios se den cuenta claramente de que las cosas urgentes e importantes deben hacerse primero. Y cuando hay muchos elementos de transacción, es útil controlar la situación general y planificar la secuencia de ejecución de cada transacción.

De acuerdo con este concepto, el autor estableció un modelo pequeño en EXCEL, de acuerdo con diferentes urgencia e importancia, estableció el intervalo del coeficiente de referencia y agregó un coeficiente de tiempo. De acuerdo con el criterio del usuario sobre la tarea, complete 3 coeficientes para calcular el valor de prioridad. El algoritmo de valor de prioridad utilizado por el autor aquí es: urgente X0.6 + importante X0.4 + tiempo X0.1 . Es decir, los asuntos más urgentes tienen mayor peso y el tiempo se utiliza como valor de ajuste para la distinción auxiliar.
Inserte la descripción de la imagen aquí

Después de calcular el valor de prioridad y ordenar, puede conocer el orden de prioridad de las tareas. ( Bueno, finalmente le di la máxima prioridad a la redacción del artículo ).
Inserte la descripción de la imagen aquí

Ok, usemos pyqt5 para hacer esto. ( Obviamente la operación en EXCEL es más rápida )

Para usar la magia para lidiar con la magia, es necesario usar una tabla para implementar una tabla, esta vez usando el control QTableWidget. Primero, arrastre y suelte en Qt Designer para crear la interfaz. La fila superior de botones es la función básica y el marco inferior es el control central.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

QTableWidget hereda de QTableView. La diferencia es que el hijo no es lo suficientemente independiente y solo conoce el modelo de datos estándar enseñado por el padre, mientras que el padre tiene conocimiento y puede usar datos extraños. Así que elijo educar al hijo inmaduro aquí ( es decir, QTableView está en problemas ).

Primer __init__método de modificación , a sumar colsy rowsel número de columnas de la tabla que representan un número variable de filas, en una operación CRUD posterior se utilizará en. Luego, configure el ancho de columna de cada columna para adaptarse al tamaño del QTableWidget. Debido a que el contenido del elemento de la tarea es un carácter indeterminado, las otras columnas son todos valores numéricos, es decir, el ancho básicamente no se puede cambiar, por lo que puede ajustar manualmente el ancho de la columna configurando solo la primera columna.

def __init__(self):
    super(ReLearnForm, self).__init__()
    self.setupUi(self)
    self.cols = self.tableWidget.columnCount()
    self.rows = 0 # 任务数
    self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 自适应列宽
    self.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive) # 仅首列可手动调整

Inserte la descripción de la imagen aquí

Aquí implemente la funcionalidad de cada botón:.
1, la
ventana de especificación de clic Léame abre una personalizada, donde ReadForm()una clase de diálogo.

def read(self):
    self.d = ReadForm()
    self.d.show()
    self.d.setWindowTitle("参数说明")

2 + (aumento de tareas)
por rowsel registro del número de tareas actualmente en la línea.

def add_row(self):
    print('添加一行任务记录')
    self.rows += 1
    self.tableWidget.setRowCount(self.rows)

3.- (Eliminar tarea)
Antes de eliminar una fila, es necesario obtener la fila actualmente seleccionada;

En el __init__método de agregar la row_flagvariable se usa para indexar filas (primera fila 0) de los registros seleccionados (cuando no están seleccionados) el valor inicial de -1. Al itemSelectionChangedvincular la señal de selección de celda y la función personalizada de ranura;

self.row_flag = -1 # 当前被选中的行索引
self.result = []
self.tableWidget.itemSelectionChanged.connect(self.chioce) # 单元格选择改变

Función de ranuras personalizadas choice()para lograr row_flagla modificación;

def chioce(self): # 修改被选中的行索引
    self.row_flag = self.tableWidget.currentRow()
    print(f'选中第{self.row_flag + 1}行')

Escriba un método para eliminar filas, modificarlas al mismo tiempo después de eliminarlas rowsy restablecerlas row_flag.

def del_row(self):
    print('删除一行任务记录')
    if self.row_flag == -1:
        QMessageBox.about(self,'提醒','未选择要删除的行!')
    else:
        self.tableWidget.removeRow(self.row_flag) # 删除指定行
        self.rows -= 1
        self.row_flag = -1

4. X (Borrar tarea)
Establezca el número de filas en el control en 0 para lograr la limpieza.

def clean_rows(self):
    print('清空任务记录')
    reply = QMessageBox.question(self, '提示', '请确认是否要清空!', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
    if reply == QMessageBox.Yes:
        self.rows = 0
        self.tableWidget.setRowCount(self.rows)

5. RUN (cálculo)
Antes de explicar la operación de deshacer, primero explique la función realizada por el botón RUN;

En el __init__método de agregar la resultvariable para almacenar temporalmente los resultados del cálculo;

self.result = []

El método para realizar el cálculo de la prioridad: ① recorrer por fila, obtener los valores de entrada del nombre de la tarea, urgencia, importancia y factor de tiempo en las 4 columnas, y calcular la prioridad p de acuerdo con las reglas descritas anteriormente (redondeado para retener 2 lugares decimales), ② Agregue el valor p a la celda y hágalo seleccionable y no editable, coloque la celda en la quinta columna de la misma fila (índice 4), es decir, la columna de prioridad, ③ finalmente guarde el resultado de cada fila en la lista, La prioridad descendente, y luego a través de resultuna variable guardada.

def prior_value(self):
    print('计算优先度')
    # print(f"共{self.row_nums}行{self.cols}列数据")
    list_para = []
    try:
        for r in range(self.rows):
            my_item = self.tableWidget.item(r, 0).text() # 任务名称
            urgent = int(self.tableWidget.item(r, 1).text()) # 紧急程度
            important = int(self.tableWidget.item(r, 2).text()) # 重要程度
            t = int(self.tableWidget.item(r, 3).text()) # 时间系数
            p = round(urgent*0.6 + important*0.4 + t*0.1,2) # 优先度
            item_p = QTableWidgetItem(str(p)) # 将优先度值添加为单元格
            item_p.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) # 设置为可选择、不可编辑
            self.tableWidget.setItem(r, 4, item_p)
            list_para.append([my_item, urgent, important, t, p])
        self.result = sorted(list_para, key=lambda x: x[4], reverse=True) # 根据优先度将行元素列表降序
        self.sort_move(self.result)
    except:
        pass

Inserte la descripción de la imagen aquí
Los resultados se calculan en este momento, pero aún no se ajustan a una celda, de modo que el resultado de la lista ordenada de procesamiento adicional resultentrante sort_move(): a partir del resultvalor adquirido de cada columna en la celda de reescritura, donde se nowordenó el índice de fila actual. QTableWidget no tiene la función de ajustar uniformemente el centro, y necesita atravesar todas las celdas nuevamente para establecer el centro.

def sort_move(self, list_para_sorted): # 根据排序结果重写单元格
    print('执行了sort')
    for now in range(len(list_para_sorted)):
        item_it = QTableWidgetItem(str(list_para_sorted[now][0]))
        item_u = QTableWidgetItem(str(list_para_sorted[now][1]))
        item_im = QTableWidgetItem(str(list_para_sorted[now][2]))
        item_t = QTableWidgetItem(str(list_para_sorted[now][3]))
        item_p = QTableWidgetItem(str(list_para_sorted[now][4]))
        item_p.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 设置为可选择、不可编辑
        print('得到了items')
        self.tableWidget.setItem(now, 0, item_it)
        self.tableWidget.setItem(now, 1, item_u)
        self.tableWidget.setItem(now, 2, item_im)
        self.tableWidget.setItem(now, 3, item_t)
        self.tableWidget.setItem(now, 4, item_p)
        print('设置了items')
    for i in range(int(self.rows)):  # 设置所有单元格文本居中
        for j in range(int(self.cols)):
            self.tableWidget.item(i, j).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

El resultado final es el siguiente, hasta ahora se ha realizado la función principal. Pero para hacer que esta herramienta ( las cosas rotas se vean más impresionantes ) sea más perfecta, continúe implementando las funciones de deshacer la eliminación y guardar los resultados en EXCEL.
Inserte la descripción de la imagen aquí

6, ← (flecha izquierda - retirar)
de la resultlectura de la última variable de registro, la primera línea de recuperación, forma de reutilización sort_move()para restaurar el contenido, que es el sort_move()único escrito como método en lugar de integrado en las prior_valuerazones del método.

def return_result(self):
    print('撤销操作')
    print(self.result)
    if self.result:
        self.rows = len(self.result) # 恢复任务数
        self.tableWidget.setRowCount(self.rows) # 恢复行
        self.sort_move(self.result) # 恢复内容

Nota: Eliminar línea sin contenido no responde, tomará el resultcontenido de las variables actuales se puede restaurar.

Inserte la descripción de la imagen aquí

7. ↓ (flecha abajo-guardar)
( realmente una función de mal gusto ) ¡Ahora es el momento de los pandas! Si resultdespués no está vacío, se escribe fila por fila DataFrame guardar en archivo EXCEL, y luego llamar os.startfile('.xlsx')para abrir el archivo.

def save(self):
    print('保存结果')
    if self.result:
        # [my_item, urgent, important, t, p]
        df = pd.DataFrame(columns=['任务项', '紧急程度', '重要程度', '时间系数', '优先度'])
        for i in range(len(self.result)):
            df.loc[i] = self.result[i]
        df.to_excel('优先度结果表.xlsx', index = False)
        os.startfile('优先度结果表.xlsx')
    else:
        QMessageBox.about(self,'提醒','未产生计算结果!')

Finalmente, empaquetado en un programa ejecutable, el ícono es una paloma pensante dibujada por el autor ( cuco, incluso si la tarea está programada, no la haré a tiempo ). Para conocer los procedimientos de empaquetado, consulte " Registro de prueba para principiantes de PyQt5 (3): Resumen de empaquetado de Pyinstaller ".
Inserte la descripción de la imagen aquí

Después de completar este gadget, creo que todo el mundo tiene una cierta comprensión de las características del control QTableWidget, ¡apliquémoslo a sus propios gadgets!

¡gracias por leer! (El código fuente se ha subido a gitub: https://github.com/SeonPan/ReLearn )

Supongo que te gusta

Origin blog.csdn.net/zohan134/article/details/107238759
Recomendado
Clasificación