gpt4 book ai didi

python - 用空行填充QtableView的底部空间

转载 作者:行者123 更新时间:2023-11-30 05:32:24 24 4
gpt4 key购买 nike

我有QTableView,我想通过添加空行来填充它的底部空间:

  • 如果QTableView中没有数据,最后这个必须填n空行 n = QTableView.height()/QTableView.rowHeight()
  • 如果(QTableView)有 m 行底部有空白,我们必须添加 n 空行行到 QTableViewn = (QTableView.height()/QTableView.rowHeight()) - m
  • 否则什么都不做

我真正的问题是,在调整 QTableView 大小时,我们必须以 TableView 必须保持填充的方式添加/删除空行(当没有 ScrollBar 时)

我正在寻找一种方法来更新 QTableView 项目,因为它的尺寸发生变化。

注意:

  • 当有ScrollBar时,不需要添加任何空行。
  • 我在计算空行数时确实计算了 QHeader 的高度。
  • 您无法获取QTableView 的当前高度,因为QTableView.height() 不会返回准确的高度除非您在QTableView 具有已显示

我真的遇到了这个问题,但我没有找到任何解决方案,我有一些想法,但它们似乎并不实用。

更新:

到目前为止,我的代码有了很大的进步,但仍然不是我想要的。

最大的问题是,在添加或删除行时,我不知道应该考虑采用哪种方法。

这是我的问题的示例代码。

主类:

import sys
from math import floor

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QEvent
from PyQt4.QtGui import QTableView, QAbstractItemView

from modeltest import TestModel

DEFAULT_ROW_HEIGHT = 30


class App(QtGui.QApplication):
"""Main application class"""

def __init__(self, sys_argv):
"""Constructor for App"""
super(App, self).__init__(sys_argv)

self.tableView = QTableView()
self.tableView.resize(500, 400)
self.tableView.setAttribute(QtCore.Qt.WA_DeleteOnClose) # Fix QObject::startTimer error message.
self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.setAlternatingRowColors(True)
self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)

self.tableView.installEventFilter(self)

self.model = TestModel()
self.tableView.setModel(self.model)

self.tableView.show()

def eventFilter(self, source, event):
if event.type() == QEvent.Resize and source is self.tableView:
totalRowsNumber = (self.tableView.height() - 31) / DEFAULT_ROW_HEIGHT
if totalRowsNumber > self.model.tasksCount():
emptyRowsToAdd = totalRowsNumber - self.model.tasksCount()
else:
emptyRowsToAdd = 0

self.model.emptyRowCount = floor(emptyRowsToAdd)

return QtGui.QWidget.eventFilter(self, source, event)

if __name__ == '__main__':
app = App(sys.argv)
sys.exit(app.exec_())

模型类:

from PyQt4 import QtCore


class TestModel(QtCore.QAbstractTableModel):
"""The model associated with tasks table view"""

def __init__(self, parent=None):
"""Constructor for TestModel"""
super(TestModel, self).__init__(parent)
self.__tasks = [['Task 1', 141546123, 80],
['Task 2', 141546123, 80],
['Task 3', 141546123, 80],
['Task 4', 141546123, 80],
['Task 5', 141546123, 80]]
# self.__tasks = [[]]
self.__header = ['Task', 'Timestamp', 'Status']
self.__empty_row_count = 0

@property
def emptyRowCount(self):
return self.__empty_row_count

@emptyRowCount.setter
def emptyRowCount(self, n):
self.reset() # reset model data.
self.__empty_row_count = n

def tasksCount(self):
if len(self.__tasks) == 1 and self.__tasks[0] == []:
return 0
return len(self.__tasks)

def rowCount(self, parent=None, *args, **kwargs):
return self.tasksCount() + self.__empty_row_count

def columnCount(self, parent=None, *args, **kwargs):
return len(self.__header) + 1

def flags(self, index):
row = index.row()
if row >= self.tasksCount():
return QtCore.Qt.ItemIsEnabled

return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

def data(self, index, role=QtCore.Qt.DisplayRole):
row = index.row()
column = index.column()
if row < self.tasksCount() and column < len(self.__header):
if role == QtCore.Qt.DisplayRole:
return self.__tasks[row][column]

def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
if section < len(self.__header):
return self.__header[section]

最佳答案

嗯,在我看来,我找到了一个可以接受的答案,我希望它是好的,但肯定有更好的答案。

不过,我确实使用了上面的相同代码以及一些核心更改。

注意:

  • 您可以通过按 ReturnDelete 按钮来测试添加或删除行。

主类

import sys
from math import floor

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QEvent
from PyQt4.QtGui import QTableView, QAbstractItemView

from modeltest import TestModel

DEFAULT_ROW_HEIGHT = 30


class App(QtGui.QApplication):
"""Main application class"""

def __init__(self, sys_argv):
"""Constructor for App"""
super(App, self).__init__(sys_argv)

self.tableView = QTableView()
self.tableView.resize(500, 400)
self.tableView.setAttribute(QtCore.Qt.WA_DeleteOnClose) # Fix QObject::startTimer error message.
self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.setAlternatingRowColors(True)
self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)

self.tableView.installEventFilter(self)

self.model = TestModel()
self.tableView.setModel(self.model)

self.tableView.show()

def setScrollBarVisibility(self, emptyRowCount):
if emptyRowCount > 0:
self.tableView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
else:
self.tableView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)

def eventFilter(self, source, event):
if event.type() == QEvent.Resize and source is self.tableView:
totalRowNumber = (self.tableView.height()) / DEFAULT_ROW_HEIGHT
self.model.updateRows(floor(totalRowNumber))
self.setScrollBarVisibility(self.model.emptyRowCount())
if event.type() == QEvent.KeyPress:
if event.key() == QtCore.Qt.Key_Return:
self.model.addRow()
self.setScrollBarVisibility(self.model.emptyRowCount())
elif event.key() == QtCore.Qt.Key_Delete:
self.model.delRow()
self.setScrollBarVisibility(self.model.emptyRowCount())

return QtGui.QWidget.eventFilter(self, source, event)

if __name__ == '__main__':
app = App(sys.argv)
sys.exit(app.exec_())

模型类

from PyQt4 import QtCore


class TestModel(QtCore.QAbstractTableModel):
"""The model associated with tasks table view"""

def __init__(self, parent=None):
"""Constructor for TestModel"""
super(TestModel, self).__init__(parent)
self.__tasks = [['Task 1', 141546123, 80],
['Task 2', 141546123, 80],
['Task 3', 141546123, 80],
['Task 4', 141546123, 80],
['Task 5', 141546123, 80]]
# self.__tasks = [[]]
self.__header = ['Task', 'Timestamp', 'Status']
self.__empty_row_count = 0
self.__total_row_count = 0 # Max visible rows.

def updateRows(self, n):
self.__total_row_count = n
if n > self.tasksCount(): # If the view has an empty space.
self.__empty_row_count = n - self.tasksCount()
else:
self.__empty_row_count = 0

self.reset() # Reset the view, results to call rowCount method.

def emptyRowCount(self):
return self.__empty_row_count

def tasksCount(self):
if len(self.__tasks) == 1 and self.__tasks[0] == []:
return 0
return len(self.__tasks)

def rowCount(self, parent=None, *args, **kwargs):
return self.tasksCount() + self.__empty_row_count
# Data rows + empty rows.

def columnCount(self, parent=None, *args, **kwargs):
return len(self.__header) + 1
# headers + the last stretched column

def flags(self, index):
row = index.row()
if row >= self.tasksCount(): # If it's an empty row.
return QtCore.Qt.ItemIsEnabled # Non selectable.

return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

def data(self, index, role=QtCore.Qt.DisplayRole):
row = index.row()
column = index.column()
if row < self.tasksCount() and column < len(self.__header):
if role == QtCore.Qt.DisplayRole:
return self.__tasks[row][column]

def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
if section < len(self.__header):
return self.__header[section]

def addRow(self):

success = self.__tasks.append(['Task x', 141546123, 80])
if self.__empty_row_count > 0:
self.__empty_row_count -= 1
self.reset() # Update the view.

return success

def delRow(self):
if self.__tasks:
self.__tasks = self.__tasks[:-1]
if self.__empty_row_count == 0: # If the visible view was full before the deleting.
if self.__total_row_count - self.tasksCount() == 1: # If the view didn't remain full.
self.__empty_row_count += 1
else:
self.__empty_row_count += 1
self.reset() # Update the view.
return True

关于python - 用空行填充QtableView的底部空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35130694/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com