因此,我正在开发一个应用程序,并且正在使用QTableWidget生成表。我想将桌子放在窗口的中央,但是我找不到解决方法,它占用了太多空间,并且卡在了窗口的左上方。我将表格和按钮放在QVBoxLayout中,表格后(底部和右侧)后面有一些空白,然后是远离表格的按钮。
那就是它的样子
那就是我想要的样子
现在我的代码是这样的:
from PyQt5.QtWidgets import QHeaderView, QPushButton, QMainWindow, QApplication, QMenuBar, QAction, QFileDialog, QWidget, QTableView, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem
from PyQt5.QtCore import QAbstractTableModel, Qt
from PyQt5 import QtGui
import sys
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.createWindow()
self.show()
def createWindow(self):
self.setWindowTitle('Pós Graduação')
self.setWindowIcon(QtGui.QIcon('icon.ico'))
self.setGeometry(300, 100, 700, 600)
self.table_widget = TableWidget(self)
self.setCentralWidget(self.table_widget)
class TableWidget(QWidget):
def __init__(self, parent):
super(TableWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
self.creatingTable(parent)
#self.setLayout(self.layout)
def creatingTable(self, parent):
tableWidget = QTableWidget()
tableWidget.setRowCount(6)
tableWidget.setColumnCount(4)
tableWidget.horizontalHeader().setVisible(False)
tableWidget.verticalHeader().setVisible(False)
header = tableWidget.horizontalHeader()
header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
self.layout.addWidget(tableWidget)
self.button1 = QPushButton("Button 1")
self.layout.addWidget(self.button1)
self.setLayout(self.layout)
if __name__ == '__main__':
App = QApplication(sys.argv)
App.setStyle('Fusion')
window = MyApp()
sys.exit(App.exec())
An item view has a default size "hint" for Qt, which is the size that the widget suggests as the best to show its contents and make it as usable as possible. Also, each widget has a sizePolicy
property, which tells how the widget behaves when it's part of a layout (should it shrink, grow, have a fixed size, etc).
Item views like QTableWidget (and its ancestor, QTableView) don't explicitly expose their contents, and that's for obvious reasons: a table could have thousands of rows and columns, and the layout shouldn't really care about them.
To be able to resize the table to its contents, the table has to cycle through all of them, and to do so it's better to do it whenever the contents change their sizes. The best approach is probably to connect to the signals the model and header provide, and set a fixed size each time they are fired, which is something that is better done with subclassing.
class TableWidgetSubclass(QTableWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# update the size each time columns or rows are changed
self.model().columnsInserted.connect(self.updateSize)
self.model().columnsRemoved.connect(self.updateSize)
self.model().rowsInserted.connect(self.updateSize)
self.model().rowsRemoved.connect(self.updateSize)
# the same, when a section is resized; note that Qt requires some "time"
# to do so, so the call to the update function has to be delayed
self.horizontalHeader().sectionResized.connect(lambda: QTimer.singleShot(0, self.updateSize))
self.verticalHeader().sectionResized.connect(lambda: QTimer.singleShot(0, self.updateSize))
# ensure that the widget uses only the maximum required size
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
# and disable the scrollbars
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
def updateSize(self):
width = 0
header = self.horizontalHeader()
# go through each column and add its size
for s in range(self.model().columnCount()):
width += header.sectionSize(s)
height = 0
header = self.verticalHeader()
# the same for rows
for s in range(self.model().rowCount()):
height += header.sectionSize(s)
size = QSize(width, height)
# since we've connected a lot of signals and the model could still
# be empty when calling this slot, ensure that the size is valid
if size.isValid():
self.setFixedSize(size)
Finally, when adding a widget to a layout, it usually uses as much space as possible. If it doesn't, it's aligned according to the default top-left. To avoid that, add the widget by specifying the alignment:
class TableWidget(QWidget):
def __init__(self, parent):
super(TableWidget, self).__init__(parent)
QVBoxLayout(self)
self.creatingTable(parent)
def creatingTable(self, parent):
tableWidget = TableWidgetSubclass()
# ...
self.layout().addWidget(tableWidget, alignment=Qt.AlignCenter)
self.button1 = QPushButton("Button 1")
self.layout().addWidget(self.button1, alignment=Qt.AlignCenter)
Note: as you can see, I didn't use self.layout =
, and then I used self.layout()
. That's for two reasons:
layout
is a property of every QWidget)setLayout
again, since it has already implicitly called.本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句