如何将 TextEdit 放入 QTableWidget - Pyqt5 的单元格中?
How to put a TextEdit inside a cell in QTableWidget - Pyqt5?
我设法使用以下代码将 TextEdit 放入我的 QTableWidget 的单元格中:
for i in range(10):
rowCount = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowCount)
combo = QTextEdit(self)
self.tableWidget_3.setCellWidget(i, 0, combo)
self.tableWidget_3.cellWidget(i, 0).setText(str(per_picture[i]))
#Adjusting the TextEdit
docHeight = self.tableWidget_3.cellWidget(i, 0).document().size().height()
self.tableWidget_3.cellWidget(i, 0).setMinimumHeight(docHeight)
一切正常,直到我调整 TextEdit 的大小以匹配文本的大小。 2 文本编辑在调整大小时似乎重叠了,就像这个
.
如何解决这 2 个 TextEdit 重叠问题?
如何在 TableWidget 中调整 TextEdit 的大小?
这些是重现问题所需的文件:
MyApp.py:
from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit
from PyQt5 import uic
from PyQt5 import QtWidgets
import sys
text = """In order to have a complete sentence, the sentence must
have a minimum of three word types: a subject, a verb,
and an object. In most cases, the subject is a noun or
a pronoun."""
class MyApp(QWidget):
def __init__(self):
super().__init__()
uic.loadUi("MyApp.ui", self)
self.tableWidget_3.verticalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
for i in range(10):
rowCount = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowCount)
combo = QTextEdit(self)
self.tableWidget_3.setCellWidget(i, 0, combo)
self.tableWidget_3.cellWidget(i, 0).setText(text)
#self.tableWidget_3.cellWidget(i, 0).adjustSize()
docHeight = self.tableWidget_3.cellWidget(i, 0).document().size().height()
self.tableWidget_3.cellWidget(i, 0).setMinimumHeight(int(docHeight))
app = QApplication(sys.argv)
myApp = MyApp()
myApp.show()
try:
sys.exit(app.exec())
except:
print('Closing Window')
MyApp.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>421</height>
</rect>
</property>
<property name="windowTitle">
<string>Editor</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>421</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<item>
<widget class="QTableWidget" name="tableWidget_3">
<column>
<property name="text">
<string>New Column</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
问题是设置单元格小部件的最小尺寸 而不是 设置部分的最小尺寸。默认情况下,所有部分都有标准项目大小(使用默认字体和 system/style 配置计算),并且由于未考虑小部件的最小大小,结果是您只能看到编辑器的一部分.
由于您隐藏了垂直 header,我想您希望行自动调整大小,这可以通过正确实施编辑器的 sizeHint
来完成。然后,您可以在 table 上安装一个事件过滤器,以便它会自动尝试根据内容调整行的大小:
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.textChanged.connect(self.updateGeometry)
def sizeHint(self):
hint = super().sizeHint()
if self.toPlainText():
doc = self.document().clone()
width = self.width() - self.frameWidth() * 2
if self.verticalScrollBar().isVisible():
width -= self.verticalScrollBar().width()
doc.setTextWidth(width)
height = round(doc.size().height())
else:
height = self.fontMetrics().height()
height += self.document().documentMargin() * 2
height += self.frameWidth() * 2
hint.setHeight(height)
return hint
class MyApp(QWidget):
def __init__(self):
super().__init__()
uic.loadUi("MyApp.ui", self)
self.tableWidget_3.verticalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setSectionResizeMode(
0, QtWidgets.QHeaderView.Stretch)
for i in range(10):
rowCount = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowCount)
combo = TextEdit(self)
self.tableWidget_3.setCellWidget(i, 0, combo)
combo.setText(text)
combo.textChanged.connect(
lambda i=i: self.tableWidget_3.resizeRowToContents(i))
self.tableWidget_3.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == event.Resize:
QTimer.singleShot(0, self.tableWidget_3.resizeRowsToContents)
return super().eventFilter(source, event)
注意:您没有在主 window 上正确设置布局:您只是添加了一个“浮动”布局,当 window 调整大小时该布局被完全忽略;将 table 移到它外面,删除该布局,右键单击 window 的空白区域,然后 select 从“布局”子菜单中选择垂直或水平布局。
此外,为了将来参考,如果您的示例只需要几个小部件,则不需要使用 Designer 文件:只需创建一个基本的 QWidget 子class,为其设置布局,并添加您需要使用的小部件;您的示例可以减少到 MyApp
class 中的 3 行,而不需要 UI 文件:
layout = QVBoxLayout(self)
self.tableWidget = QTableWidget()
layout.addWidget(self.tableWidget)
这将使您的示例更简单,也将使我们的工作更容易,因为我们只需要 copy/paste 一个文件。
我设法使用以下代码将 TextEdit 放入我的 QTableWidget 的单元格中:
for i in range(10):
rowCount = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowCount)
combo = QTextEdit(self)
self.tableWidget_3.setCellWidget(i, 0, combo)
self.tableWidget_3.cellWidget(i, 0).setText(str(per_picture[i]))
#Adjusting the TextEdit
docHeight = self.tableWidget_3.cellWidget(i, 0).document().size().height()
self.tableWidget_3.cellWidget(i, 0).setMinimumHeight(docHeight)
一切正常,直到我调整 TextEdit 的大小以匹配文本的大小。 2 文本编辑在调整大小时似乎重叠了,就像这个
如何解决这 2 个 TextEdit 重叠问题? 如何在 TableWidget 中调整 TextEdit 的大小?
这些是重现问题所需的文件:
MyApp.py:
from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit
from PyQt5 import uic
from PyQt5 import QtWidgets
import sys
text = """In order to have a complete sentence, the sentence must
have a minimum of three word types: a subject, a verb,
and an object. In most cases, the subject is a noun or
a pronoun."""
class MyApp(QWidget):
def __init__(self):
super().__init__()
uic.loadUi("MyApp.ui", self)
self.tableWidget_3.verticalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
for i in range(10):
rowCount = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowCount)
combo = QTextEdit(self)
self.tableWidget_3.setCellWidget(i, 0, combo)
self.tableWidget_3.cellWidget(i, 0).setText(text)
#self.tableWidget_3.cellWidget(i, 0).adjustSize()
docHeight = self.tableWidget_3.cellWidget(i, 0).document().size().height()
self.tableWidget_3.cellWidget(i, 0).setMinimumHeight(int(docHeight))
app = QApplication(sys.argv)
myApp = MyApp()
myApp.show()
try:
sys.exit(app.exec())
except:
print('Closing Window')
MyApp.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>421</height>
</rect>
</property>
<property name="windowTitle">
<string>Editor</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>421</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<item>
<widget class="QTableWidget" name="tableWidget_3">
<column>
<property name="text">
<string>New Column</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
问题是设置单元格小部件的最小尺寸 而不是 设置部分的最小尺寸。默认情况下,所有部分都有标准项目大小(使用默认字体和 system/style 配置计算),并且由于未考虑小部件的最小大小,结果是您只能看到编辑器的一部分.
由于您隐藏了垂直 header,我想您希望行自动调整大小,这可以通过正确实施编辑器的 sizeHint
来完成。然后,您可以在 table 上安装一个事件过滤器,以便它会自动尝试根据内容调整行的大小:
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.textChanged.connect(self.updateGeometry)
def sizeHint(self):
hint = super().sizeHint()
if self.toPlainText():
doc = self.document().clone()
width = self.width() - self.frameWidth() * 2
if self.verticalScrollBar().isVisible():
width -= self.verticalScrollBar().width()
doc.setTextWidth(width)
height = round(doc.size().height())
else:
height = self.fontMetrics().height()
height += self.document().documentMargin() * 2
height += self.frameWidth() * 2
hint.setHeight(height)
return hint
class MyApp(QWidget):
def __init__(self):
super().__init__()
uic.loadUi("MyApp.ui", self)
self.tableWidget_3.verticalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setVisible(False)
self.tableWidget_3.horizontalHeader().setSectionResizeMode(
0, QtWidgets.QHeaderView.Stretch)
for i in range(10):
rowCount = self.tableWidget_3.rowCount()
self.tableWidget_3.insertRow(rowCount)
combo = TextEdit(self)
self.tableWidget_3.setCellWidget(i, 0, combo)
combo.setText(text)
combo.textChanged.connect(
lambda i=i: self.tableWidget_3.resizeRowToContents(i))
self.tableWidget_3.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == event.Resize:
QTimer.singleShot(0, self.tableWidget_3.resizeRowsToContents)
return super().eventFilter(source, event)
注意:您没有在主 window 上正确设置布局:您只是添加了一个“浮动”布局,当 window 调整大小时该布局被完全忽略;将 table 移到它外面,删除该布局,右键单击 window 的空白区域,然后 select 从“布局”子菜单中选择垂直或水平布局。
此外,为了将来参考,如果您的示例只需要几个小部件,则不需要使用 Designer 文件:只需创建一个基本的 QWidget 子class,为其设置布局,并添加您需要使用的小部件;您的示例可以减少到 MyApp
class 中的 3 行,而不需要 UI 文件:
layout = QVBoxLayout(self)
self.tableWidget = QTableWidget()
layout.addWidget(self.tableWidget)
这将使您的示例更简单,也将使我们的工作更容易,因为我们只需要 copy/paste 一个文件。