Я пишу инструмент, который позволяет мне отслеживать некоторые задачи по пути предопределенных этапов, от чего-то из невыполненной работы до ToDo, через WIP, Review и, наконец, до выполнения.
Я создал пользовательскийвиджет, который в конечном итоге станет желтым, мало чем отличающимся от заметки postit и, возможно, с небольшим форматированием, чтобы придать ей красивый кадр и т. д. ... но остановился, прежде чем получить достаточно далеко, чтобы она выглядела правильно из-за этой проблемы.
Идея состоит в том, что у каждого из этих желтых виджетов задач будет стадия, на которой они находятся, и что я могу выбрать их в виджете таблицы и переместить их на следующую или предыдущую стадию, которая обновит стадию объектов taht,затем обновите TableWidget, прочитайте все виджеты и где они должны быть и установите их на новом месте.
Так что у меня есть вид работы до некоторой степени (ниже), где я могу перемещать задачи вперед иони обновляют местоположение, но я заметил, что когда я щелкаю по ячейкам, в которых ранее был виджет, оператор print по-прежнему говорит, что ячейкаУ ill там есть виджет (который имеет смысл, так как приведенный ниже код не удаляет предыдущий, но я ожидаю увидеть его все еще визуально). И я могу перемещать их вперед и назад, и информация о задачах обновляется правильно, но таблица не будет обновляться, если задача не перемещается в ячейку, в которой никогда не было cellWidget. Проверьте это, сдвинув его назад. Это работает, движение вперед визуально ничего не делает, но движение снова появляется.
Я попытался очистить TableWidget и восстановить с нуля, и это вылетело. Основная проблема, с которой я сталкиваюсь, заключается в том, что со всеми этими сбоями, которая сама по себе является проблемой, поскольку делает отладку очень сложной ... Когда я пытаюсь очистить TableWidget (с помощью .clear ()) перед повторным заполнением, я получаю это.
Process finished with exit code -1073741819 (0xC0000005)
Тот же код ошибки, если я пытаюсь удалить старые ячейки, установив виджет таблицы в 0 строк перед добавлением правильного количества строк.
Известная проблема, которая менее важна, - это когда я выбираю ячейку без виджета и пытаюсь переместить ее, мне это кажется, но я не слишком беспокоюсь об этом исправлении, поскольку это известная проблема.
Process finished with exit code -1073740791 (0xC0000409)
Также попытался выполнить очистку путем итерации каждой ячейки, и, если у нее есть виджет ячейки, удалите виджет ячейки перед тем, как переустановить их в правильное место, и он все еще падает. У меня нет идей.
Виджет задач
import sys
from PyQt5.QtWidgets import (QApplication, QTableWidget, QWidget, QFrame, QHBoxLayout, QLabel,
QPushButton,QVBoxLayout)
class Task(QWidget):
def __init__(self, ID, name, est):
super(Task, self).__init__()
# Creates a small widget that will be added to a table widget
self.ID = ID
self.name = name
self.est = est
# These cell widgets represent tasks. So each task has a particular 'stage' it is at
self.stage = 'ToDo'
self.stages = ['Backlog', 'ToDo', 'WIP', 'Review', 'Done']
self.objects_labels = {}
self.initUI()
def initUI(self):
# adds a bunch of labels to the widget
layout = QVBoxLayout()
frame = QFrame()
frame.setFrameShape(QFrame.StyledPanel)
frame.setStyleSheet('background-color: red')
frame.setLineWidth(2)
layout.addWidget(frame)
info = [self.ID, self.name, self.est]
for section in info:
self.objects_labels[section] = QLabel(str(section))
layout.addWidget(self.objects_labels[section])
self.setLayout(layout)
self.setStyleSheet('background-color: yellow')
def task_move(self, forward = True):
# The main widget will allow me to change the stage of a particular Task
# The idea is that I update the Table widget to show everything in the right place
# This function finds out what stage it is at and increments/decrements by one
index = self.stages.index(self.stage)
print(self.stages)
print(index)
if forward:
print('--->')
if self.stage == self.stages[-1]:
print('Already at the end of process')
return
self.stage = self.stages[index + 1]
else:
print('<---')
if self.stage == self.stages[0]:
print('Already at the start of process')
return
self.stage = self.stages[index - 1]
MainWidget
class MainWidget(QWidget):
def __init__(self):
super().__init__()
self.tasks = self.make_tasks()
self.init_ui()
self.update_tw()
def make_tasks(self):
# Create a few tasks
a = Task(0, 'Name_A', 44)
b = Task(0, 'Name_B', 22)
c = Task(0, 'Name_C', 66)
d = Task(0, 'Name_D', 90)
return [a, b, c, d]
def init_ui(self):
layout_main = QVBoxLayout()
self.tw = QTableWidget()
self.tw.cellClicked.connect(self.cell_clicked)
self.tw.horizontalHeader().setDefaultSectionSize(120)
self.tw.verticalHeader().setDefaultSectionSize(120)
layout_main.addWidget(self.tw)
layout_bottom_button_bar = QHBoxLayout()
self.btn_task_backward = QPushButton('<--- Task')
self.btn_task_backward.clicked.connect(lambda: self.move_task(forward=False))
self.btn_task_forward = QPushButton('Task --->')
self.btn_task_forward.clicked.connect(lambda: self.move_task())
for widget in [self.btn_task_backward, self.btn_task_forward]:
layout_bottom_button_bar.addWidget(widget)
layout_main.addLayout(layout_bottom_button_bar)
self.setLayout(layout_main)
self.setGeometry(300, 300, 800, 600)
self.setWindowTitle('MainWidget')
self.show()
@property
def tw_header(self):
return {'Backlog': 0, 'ToDo': 1, 'WIP': 2, 'Review': 3, 'Done': 4}
@property
def selected_indices(self):
return [(x.row(), x.column()) for x in self.tw.selectedIndexes()]
@property
def selected_widgets(self):
selected_widgets = [self.tw.cellWidget(x[0], x[1]) for x in self.selected_indices]
print(selected_widgets)
return selected_widgets
def move_task(self, forward=True):
# Crashes if you select a non-widget cell, but thats a known issue
# Moves the task forward or backward and then prompts to update the TableWidget
for object in self.selected_widgets:
object.task_move(forward=forward)
self.tw.clearSelection()
self.update_tw()
def cell_clicked(self, row, column):
if self.tw.cellWidget(row, column):
print(self.selected_indices)
print(self.selected_widgets)
else:
print('No Cell Widget here')
def update_tw(self):
#I wanted to clear the Table widget and rebuild, but this crashes
# self.tw.clear()
self.tw.setHorizontalHeaderLabels(self.tw_header.keys())
rows = len(self.tasks)
columns = len(self.tw_header)
self.tw.setRowCount(rows)
self.tw.setColumnCount(columns)
# Looks through each task, and then gets it's stage, and then adds the widget to the correct column
for index, object in enumerate(self.tasks):
column = self.tw_header[object.stage]
print('Setting stage {} for {}\n...to r={}, c={}\n***'.format(object.stage, object, index, column))
self.tw.setCellWidget(index, column, object)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainWidget()
sys.exit(app.exec_())