QSortFilterProxyModel から単語をフィルタリングできるように、QLineEdit を QHeaderView に追加しようとしています。
最初は、ヘッダーにタイトルと検索アイコンしか表示されない場合があります。ユーザーがアイコンをクリックすると、右側に QLineEdit が開き、検索ボタンが覆われ、タイトルがヘッダーの左側に移動します。
editFinished シグナルが発行されると、QLineEdit は現在のテキストを保存し、paintSection はデリゲートのようにヘッダーにタイトルと QLineEdit を描画します。QLineEdit が空の場合、検索は終了し、paintSection は最初のレイアウトに戻り、タイトルのみに検索アイコンが表示されます。
ただし、私のコードでは、検索が終了すると、paintSection は QLineEdit で覆われた部分のみを更新し、QLineEdit で覆われていない部分は、何らかのイベントが再描画をトリガーするまで同じままです。
私は Qt のペインタ システムにあまり慣れていないので、この問題に本当にイライラしています。
これは、HeaderView の現在のコードです。QLineEdit を開く機能は含まれていません。HeaderData は、Header の情報を持つ単純なクラスです。
class HeaderView(QHeaderView):
def __init__(self, orientation=Qt.Horizontal):
super().__init__(orientation)
self.setSectionsMovable(True)
self.setSectionsClickable(True)
self.editIndex = -1
self.headers = []
self.searchImage = QImage('search.png')
h = HeaderData()
self.headers.append(h)
self.line = QLineEdit(self.viewport())
self.line.hide()
self.line.editingFinished.connect(self.editingFinished)
self.line.textChanged.connect(self.textChanged)
def paintSection(self, painter, rect, logicalIndex):
if self.headers[logicalIndex].search is True: # currently searching
# Left half is filled with title
text_rect = QRect(rect.x(), rect.y(), rect.width()//2, rect.height())
painter.drawText(text_rect, Qt.AlignCenter, self.model().headerData(logicalIndex, self.orientation(), Qt.DisplayRole))
# Right half is area for QLineEdit
rel_pos = painter.deviceTransform().map(QPoint(rect.x(), rect.y()))
line_rect = QRect(rect.width() // 2, 0, rect.width() // 2, rect.height())
line_pos = rel_pos + line_rect.topLeft()
device = painter.device()
w = QLineEdit()
w.resize(line_rect.size())
w.setText(self.headers[logicalIndex].line_text)
w.render(device, line_pos, QRegion(0, 0, w.width(), w.height()), QWidget.RenderFlag.DrawChildren)
self.headers[logicalIndex].line_rect = line_rect
else: # not searching
painter.drawText(rect, Qt.AlignCenter, self.model().headerData(logicalIndex, self.orientation(), Qt.DisplayRole))
point = rect.topLeft()
offset = QPoint(rect.width() - rect.height(), rect.height()//4)
icon_size = QSize(rect.height()//2, rect.height()//2))
painter.drawImage(point + offset, self.searchImage.scaled(icon_size)
self.headers[logicalIndex].search_rect = QRect(offset, icon_size)
def openEditor(self, index):
self.editIndex = index
line_rect = self.headers[index].line_rect.translated(self.sectionViewportPosition(index), 0)
self.line.setGeometry(line_rect)
self.line.setText(self.headers[index].line_text)
self.line.setVisible(True)
def textChanged(self, text):
self.headers[self.editIndex].line_text = text
def editingFinished(self):
if self.line.text() == '':
self.headers[self.editIndex].search = False
self.line.hide()
self.headers[self.editIndex].line_text = self.line.text()
self.editIndex = -1