title: Qt : Fit width of TableView to width of content
body: <p>I have a window that contains a <code>QTableView</code> which <strong>columns are adjusted to content</strong> and are <strong>fixed in width</strong>. The <code>QTableView</code> is nested within a <code>QWidget</code> that in turn is nested within a <code>QScrollArea</code> that in turn is nested within a <strong>tabbed</strong> <code>QMdiArea</code> which is the <code>centralWidget</code> of a <code>QMainWindow</code>.</p>
  
  <p>When the <code>QScrollArea</code> is shown, the <code>QTableView</code> has extra space to the right of the last column that I want to be removed :</p>
  
  <p><img src="https://i.stack.imgur.com/ugT9O.png" alt="Screenshot of TableView"></p>
  
  <p>I want the <code>QTableView</code> to fit the exact width of the columns (i.e. no extra space after the rightmost column).</p>
  
  <p>I tried to use <code>tableView.setFixedWidth(desired_width)</code> but then the only way it could work was to iterate over all the columns and get their widths and sum them up together and add the <code>verticalHeader</code> width and the scroll-bars width and pass it as the <code>desired_width</code>. </p>
  
  <p>It does work this way but it seems to be very complex for such an obvious requirement : I think a lot of program developers want their tables' width to fit the columns' width and this is what makes me wonder that maybe there is a method that does that automatically without the extra calculations and that I'm unaware of.</p>
  
  <p>So my question is : is there a simpler way to achieve the same result ?</p>
  
  <p>Here is my code for reference :</p>
  
  <p>The code for the <code>t_main</code> module responsible for creating the <code>QMainWindow</code> :</p>
  
  <pre><code>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("&amp;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('&amp;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()
  </code></pre>
  
  <p>The code for <code>t_wdw</code> module that is responsible for creating the <code>SubWindow</code> with the <code>QTableView</code>.</p>
  
  <pre><code>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]
  </code></pre>
  
  <p>An extra question for those who read the code : Why do I need to multiply <code>PM_ScrollBarExtent</code> by 2 to get the correct result ?</p>
  
  <p>P.S : I'm using PySide 1.2.1 but answers in PyQt or C++ are fine.</p>