繁体   English   中英

隐藏小部件后的绘画被剪裁

[英]Painting after hiding a widget get clipped

我正在尝试将 QLineEdit 添加到 QHeaderView 以便我可以过滤来自 QSortFilterProxyModel 的单词。

起初,header 可能只显示标题和搜索图标。 当用户点击该图标时,QLineEdit 在右侧打开,覆盖搜索按钮,并且标题移动到 header 的左侧。

当editingFinished 信号发出时,QLineEdit 保存当前文本,并且paintSection 在header 上绘制标题和QLineEdit,就像代表所做的那样。 如果 QLineEdit 为空,则搜索结束并且paintSection 只是返回到第一个布局,只有带有搜索图标的标题。

但是,在我的代码中,当搜索结束时,paintSection 仅刷新被 QLineEdit 覆盖的部分,而未被它覆盖的部分保持不变,直到某种事件触发重新绘制。

行为

我对Qt的painter系统不太友好,所以我对这个问题感到非常沮丧。

这是我当前的 HeaderView 代码。 不包括负责打开 QLineEdit 的 Function。 HeaderData 只是一个简单的 class ,其中包含 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

好的,我做了一些事件过滤和东西,发现当调用editingFinished时,只有layoutRequest事件因为隐藏了编辑器小部件而引发,并且这个事件当然没有重新绘制背景。

所以我尝试在编辑结束时添加repaintupdate editingFinished ,但他们根本没有调用任何事件。 当我在小部件隐藏之前调用它们时,现在它们触发了paintEvent ,但仅触发了放置我的小部件的区域。

之后,我在 Python 文档的 Qt 中找到了一个插槽updateSection ,它确实有效。 我不确定它是否适用于 C++ ZE8801102A40AD89DDCFDCAEBF008D25Z 因为我在 C++ ZE8801102A40ADBFDCAEBF008D25Z 上找不到相同的插槽。

我仍然很好奇为什么当我使用“重绘”或“更新”时 header 没有更新,但这是另一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM