我有一个 QTableWidget,其中包含混合语言(阿拉伯语和英语)的列。由于阿拉伯语是 RTL,英语是 LTR,我想为每列设置不同的布局方向。我知道方法
setLayoutDirection()
,但这会改变整个表格的布局方向。 RTL方向:
注意第 8 行如何读作“方式(这就是我们的)”。它应该是“(这就是我们的)方式”,但由于布局的方向而颠倒了。如果我将布局的方向设置为 LTR,它就会被修复:
(但是整个桌子移到了屏幕的左侧,并且被翻转了)。
如何将表格保持在右侧,保持列的顺序不变,但为每列设置不同的文本方向?
编辑:最小工作示例:
# LTR
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem
from PySide6.QtCore import Qt
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
table = QTableWidget(2, 2)
table.setHorizontalHeaderLabels(["Arabic", "English"])
table.setLayoutDirection(Qt.LeftToRight) # LTR
table.setItem(0, 0, QTableWidgetItem("(الكلمة الأولى) خلية 1"))
table.setItem(1, 0, QTableWidgetItem("(الكلمة الثانية) خلية 2"))
table.setItem(0, 1, QTableWidgetItem("(First word) cell 1"))
table.setItem(1, 1, QTableWidgetItem("(Second word) cell 2"))
# Set the table as the central widget
self.setCentralWidget(table)
self.setWindowTitle("QTableWidget Example")
self.resize(400, 300)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
在上面的例子中,我将布局方向设置为LTR,英语看起来不错,阿拉伯语则相反,表格位于屏幕左侧:
与 RTL 布局方向相同的示例:
table.setLayoutDirection(Qt.RightToLeft) # RTL
现在阿拉伯语看起来不错,英语则相反,表格位于屏幕右侧。
期望的行为是:表格位于屏幕右侧,阿拉伯语和英语都不会颠倒。
该问题几年前就已经报告过(请参阅QTBUG-55012),但不幸的是从未在 API 中得到解决。
这是因为当绘制项目文本时,它假设小部件的布局方向始终与显示的文本相同,但这可能会导致某些字符(特别是圆括号、方括号等)出现问题。
有多种可能的方法可以解决这个问题,它们都依赖于这样一个事实:所有从左到右的文本字符串应始终以相关的 Unicode 文本控制字符开头,并具有基本的
\u200e
(LEFT-TO-RIGHT MARK
)是最明显的选择。
您可以手动将其添加到所有硬编码字符串中;例如,在您的示例代码中:
table.setItem(0, 1, QTableWidgetItem("\u200e(First word) cell 1"))
table.setItem(1, 1, QTableWidgetItem("\u200e(Second word) cell 2"))
或者,您可以使用自定义委托来检查每个项目的文本并尝试猜测字符串的布局方向。
class TextDirectionDelegate(QStyledItemDelegate):
def initStyleOption(self, opt, index):
super().initStyleOption(opt, index)
if not '\u200e' in opt.text:
for l in opt.text:
if bidirectional(l) == 'L':
opt.text = '\u200e' + opt.text
class MainWindow(QMainWindow):
def __init__(self):
...
table.setItemDelegate(TextDirectionDelegate(table))
请注意,上面是一个非常粗略的实现,没有考虑具有混合布局方向的可能性(请参阅此相关帖子的答案以获得更一致的解决方案)。
但是,在您的情况下,很明显特定列有自己的文本方向,因此不应涉及猜测:在任何情况下只需添加控制字符,并为相关列设置委托。
class TextDirectionDelegate(QStyledItemDelegate):
def initStyleOption(self, opt, index):
super().initStyleOption(opt, index)
if not opt.text.startswith('\u200e'):
opt.text = '\u200e' + opt.text
class MainWindow(QMainWindow):
def __init__(self):
...
table.setItemDelegateForColumn(1, TextDirectionDelegate(table))