Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt:使TableView的宽度适合于内容的宽度_Qt_Pyside_Qtableview - Fatal编程技术网

Qt:使TableView的宽度适合于内容的宽度

Qt:使TableView的宽度适合于内容的宽度,qt,pyside,qtableview,Qt,Pyside,Qtableview,我有一个窗口,其中包含一个QTableView,其中列根据内容进行调整,并且宽度固定。QTableView嵌套在QWidget中,QWidget又嵌套在qscrollara中,qscrollara又嵌套在选项卡QMdiArea中,QMdiArea是QMainWindow的中心widget 当显示QScrollArea时,QTableView在我要删除的最后一列的右侧有额外的空间: 我希望QTableView与列的确切宽度相匹配(即最右边的列后面没有额外的空间) 我尝试使用tableView.s

我有一个窗口,其中包含一个
QTableView
,其中列根据内容进行调整,并且宽度固定。
QTableView
嵌套在
QWidget
中,QWidget又嵌套在
qscrollara
中,qscrollara又嵌套在选项卡
QMdiArea
中,QMdiArea是
QMainWindow
中心widget

当显示
QScrollArea
时,
QTableView
在我要删除的最后一列的右侧有额外的空间:

我希望
QTableView
与列的确切宽度相匹配(即最右边的列后面没有额外的空间)

我尝试使用
tableView.setFixedWidth(desired\u width)
但唯一可行的方法是迭代所有列,得到它们的宽度并将它们相加,然后添加
verticalHeader
宽度和滚动条宽度,并将其作为
desired\u width
传递

它确实是这样工作的,但对于这样一个明显的要求来说似乎非常复杂:我认为许多程序开发人员希望他们的表的宽度与列的宽度相匹配,这让我想知道,也许有一种方法可以自动完成,而无需额外的计算,而我并不知道

所以我的问题是:有没有更简单的方法来达到同样的结果

以下是我的代码供参考:

负责创建
QMainWindow
t_main
模块的代码:

import sys
import t_wdw
from PySide import QtGui

class Main_Window(QtGui.QMainWindow):
    def __init__(self):
        super(Main_Window,self).__init__()
        self.initUI()


    def initUI(self):
        self.statusBar()
        # Defines QActions for menu
        self.new_window=QtGui.QAction("&Window alpha",self)
        self.new_window.triggered.connect(self.open_window)
        # Creates the menu
        self.menu_bar=self.menuBar()
        self.menu1=self.menu_bar.addMenu('&Menu 1')
        self.menu1.addAction(self.new_window)
        # Creates a QMdiArea to manage all windows.
        self.wmanager=QtGui.QMdiArea()
        self.wmanager.setViewMode(QtGui.QMdiArea.TabbedView)
        self.setCentralWidget(self.wmanager)
        self.showMaximized()

    # Opens the new window that holds the QTableView
    def open_window(self):
        t_wdw.launch_window()
        t_wdw.window_alpha=self.wmanager.addSubWindow(t_wdw.window)
        t_wdw.window_alpha.show()

def main():
    app=QtGui.QApplication(sys.argv)
    main_wdw=Main_Window()
    sys.exit(app.exec_())

if __name__=="__main__":
    main()
负责使用
QTableView
创建
子窗口的
t_wdw
模块的代码

from PySide import QtGui
from PySide import QtCore

def launch_window():
    global window
    # Creates a new window
    window=QtGui.QScrollArea()
    window1=QtGui.QWidget()
    row=0
    data=[["VH"+str(row+i),1,2,3] for i in range(20)]
    headers=["HH1","HH2","HH3"]
    # Creates a table view with columns resized to fit the content.
    model=my_table(data,headers)
    tableView=QtGui.QTableView()
    tableView.setModel(model)
    tableView.resizeColumnsToContents()
    # Fixes the width of columns and the height of rows.
    tableView.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
    tableView.verticalHeader().setResizeMode(QtGui.QHeaderView.Fixed)

    """
    Here is the solution I resorted to to fix the tableView width 
    equal to its content and that I want to make simpler
    """
    vhwidth=tableView.verticalHeader().width()
    desired_width=QtGui.QStyle.PM_ScrollBarExtent*2+vhwidth+1
    for i in range(len(headers)):
        desired_width+=tableView.columnWidth(i)
    tableView.setFixedWidth(desired_width)

    """
    Sets the layouts and widgets using a QHBoxLayout because
    I want the QTableView to be centered on the window
    and more widgets and layouts are to be added later.
    """

    window1.main_layout=QtGui.QHBoxLayout()
    window1.main_layout.addStretch(0)
    window1.main_layout.addWidget(tableView)
    window1.main_layout.addStretch(0)
    window.setLayout(window1.main_layout)
    window.setWidget(window1)

class my_table(QtCore.QAbstractTableModel):

    def __init__(self,data,headers,parent=None):
        QtCore.QAbstractTableModel.__init__(self,parent)
        self.__data=data
        self.__headers=headers

    def rowCount(self,parent):
        return len(self.__data)

    def columnCount(self,parent):
        return len(self.__headers)

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            return self.__data[row][column+1]

    def headerData(self,section,orientation,role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self.__headers[section]
            if orientation == QtCore.Qt.Vertical:
                return self.__data[section][0]
对于阅读代码的人来说,还有一个额外的问题:为什么我需要将
PM\u ScrollBarExtent
乘以2才能得到正确的结果


S:我使用PyStay1.2.1,但是在PyQt或C++中答案很好。

< P>有一些关于你的宽度计算错误的事情。

首先,您尝试使用
QtGui.QStyle.PM_ScrollBarExtent
获取垂直滚动条的宽度-但这是一个常量,不是属性。相反,您需要使用:

其次,您不考虑tableview框架的宽度,可以这样计算:

tableView.frameWidth() * 2
将这些值与收割台的尺寸放在一起,最终计算应为:

vwidth = tableView.verticalHeader().width()
hwidth = tableView.horizontalHeader().length()
swidth = tableView.style().pixelMetric(QtGui.QStyle.PM_ScrollBarExtent)
fwidth = tableView.frameWidth() * 2

tableView.setFixedWidth(vwidth + hwidth + swidth + fwidth)
这应该正好为垂直滚动条留出所需的空间

附言:

由于要为tableview设置固定宽度,因此还可以取消水平滚动条,这是多余的:

tableView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

在C++中你可以做这样的事情:< /P>
tableview->resizeColumnsToContents();

QHeaderView* header = tableview->horizontalHeader();
header->setStretchLastSection(true);
tablewview->setHorizontalHeader(header);

从Qt 5.2开始,您可以使用以下功能:

view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);


您可以使用类似于
tableView.visualRect(model.index(0,model.columnCount()-1)).right()
的方法,而不是迭代所有列。谢谢,但似乎不起作用,visualRect返回(0,0,0,0)。我成功地使用了
tableView.horizontalHeader().length()
取而代之的是避免迭代,但我仍然需要用
tableView.verticalHeader().width()对其进行总结
PM\u ScrollBarExtent*2
。感谢您的回答,但是
setStretchLastSection
只是拉伸最后一列,以填充
tableView
中的剩余空间,而我正试图做相反的事情,即将
tableView
缩小到列的宽度。感谢您的回答,我最终使用了
tableView.horizontalHeader().length()
tableView.verticalHeader().width()
,正如我在评论中所说的,我忘了说,但我用
tableView.verticalScrollBar().sizeHint().width()替换了
QtGui.QStyle.PM\u scrollberextent
。现在我不确定哪一个更正确,
sizeHint()
还是您的方法?但我一直在添加1个像素以获得合适的结果,我想现在,多亏了你的回答,这个像素占了
tableView.frameWidth()*2
。很遗憾,没有更简单的方法。再次感谢你。@Ekhumaro这真的很有帮助。奇怪的是,我仍然需要添加6个像素以获得精确的匹配。我认为这可能是由于列之间的行添加了像素,但无论显示多少列,它都是6像素。现在,我只是把它作为一个捏造的因素,但不想…@neuronet。很难说没有看到实际的代码。请开始一个新问题,并包括一个演示该问题的最小工作示例。你可能也应该说你在哪个平台上。@Ekhumaro:刚刚发布:这些对我来说没什么区别。
view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);