如何移除PyQt5中QTableView聚焦项的虚线框
如何移除PyQt5 QTableView聚焦项的虚线框(Windows环境)
我正在编写一个简单的PyQt5应用,使用QTableView组件,想要移除聚焦项周围的虚线框。以下是最小可复现代码:
import sys from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, main_window): main_window.setObjectName("main_window") main_window.resize(640, 480) self.main_container = QtWidgets.QWidget(main_window) self.main_container.setObjectName("main_container") self.verticalLayout = QtWidgets.QVBoxLayout(self.main_container) self.verticalLayout.setObjectName("verticalLayout") self.model = QtGui.QStandardItemModel(0, 2, main_window) for col1, col2 in (("foo", "bar"), ("fizz", "buzz")): it_col1 = QtGui.QStandardItem(col1) it_col2 = QtGui.QStandardItem(col2) self.model.appendRow([it_col1, it_col2]) self.view = QtWidgets.QTableView( self.main_container, showGrid=False, selectionBehavior=QtWidgets.QAbstractItemView.SelectRows ) self.view.setModel(self.model) self.verticalLayout.addWidget(self.view) main_window.setCentralWidget(self.main_container) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
运行后聚焦项会显示虚线框,我尝试过以下方法但均无效:
- 使用
outline: none样式表:无任何变化 - 使用
border: none样式表:保留虚线框且项背景变为白色 - 设置
setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus):视觉效果符合要求,但导致单元格无法编辑、无法响应键盘事件
环境:Windows系统,PyQt5 5.15.4,PyQt5-Qt5 5.15.2
解决方案1:修正样式表写法
Windows下QTableView的焦点虚线框属于系统级焦点指示,需要在样式表中同时指定选中状态的背景色和文本色,避免默认样式被覆盖后出现异常,同时移除焦点边框:
# 在self.view.setModel(self.model)后添加 self.view.setStyleSheet(""" QTableView::item:focus { border: none; outline: none; background: palette(highlight); color: palette(highlighted-text); } QTableView::item:selected:focus { border: none; outline: none; } """)
这样既移除了虚线框,又保留了选中项的高亮样式,同时不影响单元格编辑和键盘操作。
解决方案2:自定义委托(更灵活)
如果样式表无法满足需求,可以通过自定义QStyledItemDelegate,重写paint方法,跳过焦点矩形的绘制:
class NoFocusDelegate(QtWidgets.QStyledItemDelegate): def paint(self, painter, option, index): # 移除焦点状态的标记 option.state &= ~QtWidgets.QStyle.State_HasFocus super().paint(painter, option, index) # 在设置model后使用该委托 self.view.setModel(self.model) self.view.setItemDelegate(NoFocusDelegate(self.view))
这种方法完全控制了项的绘制逻辑,彻底移除焦点虚线框,同时保留所有交互功能。
内容的提问来源于stack exchange,提问作者Евгений Крамаров
相关产品推荐
相关产品推荐

