Sophie

Sophie

distrib > Mageia > 7 > armv7hl > by-pkgid > b796bb6846bef0871594624de2c980c0 > files > 4552

qtbase5-doc-5.12.6-4.mga7.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- frozencolumn.qdoc -->
  <title>Frozen Column Example | Qt Widgets 5.12.6</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td >Qt 5.12</td><td ><a href="qtwidgets-index.html">Qt Widgets</a></td><td ><a href="examples-itemviews.html">Item Views Examples</a></td><td >Frozen Column Example</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right"><a href="qtwidgets-index.html">Qt 5.12.6 Reference Documentation</a></td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#freezetablewidget-class-definition">FreezeTableWidget Class Definition</a></li>
<li class="level1"><a href="#freezetablewidget-class-implementation">FreezeTableWidget Class Implementation</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Frozen Column Example</h1>
<span class="subtitle"></span>
<!-- $$$itemviews/frozencolumn-brief -->
<p>This example demonstrates how to freeze a column within a <a href="qtableview.html">QTableView</a>.</p>
<!-- @@@itemviews/frozencolumn -->
<!-- $$$itemviews/frozencolumn-description -->
<div class="descr"> <a name="details"></a>
<p class="centerAlign"><img src="images/frozencolumn-example.png" alt="&quot;Screenshot of the example&quot;" /></p><p>We use Qt's model/view framework to implement a table with its first column frozen. This technique can be aplied to several columns or rows, as long as they are on the edge of the table.</p>
<p>The model/view framework allows for one model to be displayed in different ways using multiple views. For this example, we use two views on the same model - two <a href="qtableview.html">table views</a> sharing one model. The frozen column is a child of the main tableview, and we provide the desired visual effect using an overlay technique which will be described step by step in the coming sections.</p>
<p class="centerAlign"><img src="images/frozencolumn-tableview.png" alt="" /></p><a name="freezetablewidget-class-definition"></a>
<h2 id="freezetablewidget-class-definition">FreezeTableWidget Class Definition</h2>
<p>The <code>FreezeTableWidget</code> class has a constructor and a destructor. Also, it has two private members: the table view that we will use as an overlay, and the shared model for both table views. Two slots are added to help keep the section sizes in sync, as well as a function to readjust the frozen column's geometry. In addition, we reimplement two functions: <a href="qabstractitemview.html#resizeEvent">resizeEvent()</a> and <a href="qtableview.html#moveCursor">moveCursor()</a>.</p>
<pre class="cpp">

  <span class="keyword">class</span> FreezeTableWidget : <span class="keyword">public</span> <span class="type"><a href="qtableview.html">QTableView</a></span> {
       Q_OBJECT

  <span class="keyword">public</span>:
        FreezeTableWidget(<span class="type"><a href="../qtcore/qabstractitemmodel.html">QAbstractItemModel</a></span> <span class="operator">*</span> model);
        <span class="operator">~</span>FreezeTableWidget();

  <span class="keyword">protected</span>:
        <span class="type">void</span> resizeEvent(<span class="type"><a href="../qtgui/qresizeevent.html">QResizeEvent</a></span> <span class="operator">*</span>event) override;
        <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> moveCursor(CursorAction cursorAction<span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>KeyboardModifiers modifiers) override;
        <span class="type">void</span> scrollTo (<span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span> index<span class="operator">,</span> ScrollHint hint <span class="operator">=</span> EnsureVisible) override;

  <span class="keyword">private</span>:
        <span class="type"><a href="qtableview.html">QTableView</a></span> <span class="operator">*</span>frozenTableView;
        <span class="type">void</span> init();
        <span class="type">void</span> updateFrozenTableGeometry();

  <span class="keyword">private</span> <span class="keyword">slots</span>:
        <span class="type">void</span> updateSectionWidth(<span class="type">int</span> logicalIndex<span class="operator">,</span> <span class="type">int</span> oldSize<span class="operator">,</span> <span class="type">int</span> newSize);
        <span class="type">void</span> updateSectionHeight(<span class="type">int</span> logicalIndex<span class="operator">,</span> <span class="type">int</span> oldSize<span class="operator">,</span> <span class="type">int</span> newSize);

  };

</pre>
<p><b>Note: </b><a href="qabstractitemview.html">QAbstractItemView</a> is <a href="qtableview.html">QTableView</a>'s ancestor.</p><a name="freezetablewidget-class-implementation"></a>
<h2 id="freezetablewidget-class-implementation">FreezeTableWidget Class Implementation</h2>
<p>The constructor takes <i>model</i> as an argument and creates a table view that we will use to display the frozen column. Then, within the constructor, we invoke the <code>init()</code> function to set up the frozen column. Finally, we connect the <a href="qheaderview.html#sectionResized">QHeaderView::sectionResized</a>() signals (for horizontal and vertical headers) to the appropriate slots. This ensures that our frozen column's sections are in sync with the headers. We also connect the vertical scrollbars together so that the frozen column scrolls vertically with the rest of our table.</p>
<pre class="cpp">

  FreezeTableWidget<span class="operator">::</span>FreezeTableWidget(<span class="type"><a href="../qtcore/qabstractitemmodel.html">QAbstractItemModel</a></span> <span class="operator">*</span> model)
  {
        setModel(model);
        frozenTableView <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtableview.html">QTableView</a></span>(<span class="keyword">this</span>);

        init();

        <span class="comment">//connect the headers and scrollbars of both tableviews together</span>
        connect(horizontalHeader()<span class="operator">,</span><span class="operator">&amp;</span><span class="type"><a href="qheaderview.html">QHeaderView</a></span><span class="operator">::</span>sectionResized<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span>
                <span class="operator">&amp;</span>FreezeTableWidget<span class="operator">::</span>updateSectionWidth);
        connect(verticalHeader()<span class="operator">,</span><span class="operator">&amp;</span><span class="type"><a href="qheaderview.html">QHeaderView</a></span><span class="operator">::</span>sectionResized<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span>
                <span class="operator">&amp;</span>FreezeTableWidget<span class="operator">::</span>updateSectionHeight);

        connect(frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>verticalScrollBar()<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qabstractslider.html">QAbstractSlider</a></span><span class="operator">::</span>valueChanged<span class="operator">,</span>
                verticalScrollBar()<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qabstractslider.html">QAbstractSlider</a></span><span class="operator">::</span>setValue);
        connect(verticalScrollBar()<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qabstractslider.html">QAbstractSlider</a></span><span class="operator">::</span>valueChanged<span class="operator">,</span>
                frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>verticalScrollBar()<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qabstractslider.html">QAbstractSlider</a></span><span class="operator">::</span>setValue);

  }

</pre>
<p>In the <code>init()</code> function, we ensure that the overlay table view responsible for displaying the frozen column, is set up properly. This means that this table view, <code>frozenTableView</code>, has to have the same model as the main table view. However, the difference here is: <code>frozenTableView</code>'s only visible column is its first column; we hide the others using <a href="qtableview.html#setColumnHidden">setColumnHidden()</a></p>
<pre class="cpp">

  <span class="type">void</span> FreezeTableWidget<span class="operator">::</span>init()
  {
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setModel(model());
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setFocusPolicy(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>NoFocus);
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>verticalHeader()<span class="operator">-</span><span class="operator">&gt;</span>hide();
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>horizontalHeader()<span class="operator">-</span><span class="operator">&gt;</span>setSectionResizeMode(<span class="type"><a href="qheaderview.html">QHeaderView</a></span><span class="operator">::</span>Fixed);

        viewport()<span class="operator">-</span><span class="operator">&gt;</span>stackUnder(frozenTableView);

</pre>
<p>In terms of the frozen column's z-order, we stack it on top of the viewport. This is achieved by calling <a href="qwidget.html#stackUnder">stackUnder()</a> on the viewport. For appearance's sake, we prevent the column from stealing focus from the main tableview. Also, we make sure that both views share the same selection model, so only one cell can be selected at a time. A few other tweaks are done to make our application look good and behave consistently with the main tableview. Note that we called <code>updateFrozenTableGeometry()</code> to make the column occupy the correct spot.</p>
<pre class="cpp">

        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setStyleSheet(<span class="string">&quot;QTableView { border: none;&quot;</span>
                                       <span class="string">&quot;background-color: #8EDE21;&quot;</span>
                                       <span class="string">&quot;selection-background-color: #999}&quot;</span>); <span class="comment">//for demo purposes</span>
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setSelectionModel(selectionModel());
        <span class="keyword">for</span> (<span class="type">int</span> col <span class="operator">=</span> <span class="number">1</span>; col <span class="operator">&lt;</span> model()<span class="operator">-</span><span class="operator">&gt;</span>columnCount(); <span class="operator">+</span><span class="operator">+</span>col)
              frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setColumnHidden(col<span class="operator">,</span> <span class="keyword">true</span>);

        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setColumnWidth(<span class="number">0</span><span class="operator">,</span> columnWidth(<span class="number">0</span>) );

        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setHorizontalScrollBarPolicy(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>ScrollBarAlwaysOff);
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setVerticalScrollBarPolicy(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>ScrollBarAlwaysOff);
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>show();

        updateFrozenTableGeometry();

        setHorizontalScrollMode(ScrollPerPixel);
        setVerticalScrollMode(ScrollPerPixel);
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setVerticalScrollMode(ScrollPerPixel);
  }

</pre>
<p>When you resize the frozen column, the same column on the main table view must resize accordingly, to provide seamless integration. This is accomplished by getting the new size of the column from the <code>newSize</code> value from the <a href="qheaderview.html#sectionResized">sectionResized()</a> signal, emitted by both the horizontal and vertical header.</p>
<pre class="cpp">

  <span class="type">void</span> FreezeTableWidget<span class="operator">::</span>updateSectionWidth(<span class="type">int</span> logicalIndex<span class="operator">,</span> <span class="type">int</span> <span class="comment">/* oldSize */</span><span class="operator">,</span> <span class="type">int</span> newSize)
  {
        <span class="keyword">if</span> (logicalIndex <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span>){
              frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setColumnWidth(<span class="number">0</span><span class="operator">,</span> newSize);
              updateFrozenTableGeometry();
        }
  }

  <span class="type">void</span> FreezeTableWidget<span class="operator">::</span>updateSectionHeight(<span class="type">int</span> logicalIndex<span class="operator">,</span> <span class="type">int</span> <span class="comment">/* oldSize */</span><span class="operator">,</span> <span class="type">int</span> newSize)
  {
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setRowHeight(logicalIndex<span class="operator">,</span> newSize);
  }

</pre>
<p>Since the width of the frozen column is modified, we adjust the geometry of the widget accordingly by invoking <code>updateFrozenTableGeometry()</code>. This function is further explained below.</p>
<p>In our reimplementation of <a href="qabstractitemview.html#resizeEvent">QTableView::resizeEvent</a>(), we call <code>updateFrozenTableGeometry()</code> after invoking the base class implementation.</p>
<pre class="cpp">

  <span class="type">void</span> FreezeTableWidget<span class="operator">::</span>resizeEvent(<span class="type"><a href="../qtgui/qresizeevent.html">QResizeEvent</a></span> <span class="operator">*</span> event)
  {
        <span class="type"><a href="qtableview.html">QTableView</a></span><span class="operator">::</span>resizeEvent(event);
        updateFrozenTableGeometry();
   }

</pre>
<p>When navigating around the table with the keyboard, we need to ensure that the current selection does not disappear behind the frozen column. To synchronize this, we reimplement <a href="qtableview.html#moveCursor">QTableView::moveCursor</a>() and adjust the scrollbar positions if needed, after calling the base class implementation.</p>
<pre class="cpp">

  <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> FreezeTableWidget<span class="operator">::</span>moveCursor(CursorAction cursorAction<span class="operator">,</span>
                                            <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>KeyboardModifiers modifiers)
  {
        <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> current <span class="operator">=</span> <span class="type"><a href="qtableview.html">QTableView</a></span><span class="operator">::</span>moveCursor(cursorAction<span class="operator">,</span> modifiers);

        <span class="keyword">if</span> (cursorAction <span class="operator">=</span><span class="operator">=</span> MoveLeft <span class="operator">&amp;</span><span class="operator">&amp;</span> current<span class="operator">.</span>column() <span class="operator">&gt;</span> <span class="number">0</span>
                <span class="operator">&amp;</span><span class="operator">&amp;</span> visualRect(current)<span class="operator">.</span>topLeft()<span class="operator">.</span>x() <span class="operator">&lt;</span> frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>columnWidth(<span class="number">0</span>) ){
              <span class="keyword">const</span> <span class="type">int</span> newValue <span class="operator">=</span> horizontalScrollBar()<span class="operator">-</span><span class="operator">&gt;</span>value() <span class="operator">+</span> visualRect(current)<span class="operator">.</span>topLeft()<span class="operator">.</span>x()
                                   <span class="operator">-</span> frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>columnWidth(<span class="number">0</span>);
              horizontalScrollBar()<span class="operator">-</span><span class="operator">&gt;</span>setValue(newValue);
        }
        <span class="keyword">return</span> current;
  }

</pre>
<p>The frozen column's geometry calculation is based on the geometry of the table underneath, so it always appears in the right place. Using the <a href="qframe.html#frameWidth-prop">QFrame::frameWidth</a>() function helps to calculate this geometry correctly, no matter which style is used. We rely on the geometry of the viewport and headers to set the boundaries for the frozen column.</p>
<pre class="cpp">

  <span class="type">void</span> FreezeTableWidget<span class="operator">::</span>updateFrozenTableGeometry()
  {
        frozenTableView<span class="operator">-</span><span class="operator">&gt;</span>setGeometry(verticalHeader()<span class="operator">-</span><span class="operator">&gt;</span>width() <span class="operator">+</span> frameWidth()<span class="operator">,</span>
                                     frameWidth()<span class="operator">,</span> columnWidth(<span class="number">0</span>)<span class="operator">,</span>
                                     viewport()<span class="operator">-</span><span class="operator">&gt;</span>height()<span class="operator">+</span>horizontalHeader()<span class="operator">-</span><span class="operator">&gt;</span>height());
  }

</pre>
<p>Files:</p>
<ul>
<li><a href="qtwidgets-itemviews-frozencolumn-freezetablewidget-cpp.html">itemviews/frozencolumn/freezetablewidget.cpp</a></li>
<li><a href="qtwidgets-itemviews-frozencolumn-freezetablewidget-h.html">itemviews/frozencolumn/freezetablewidget.h</a></li>
<li><a href="qtwidgets-itemviews-frozencolumn-frozencolumn-pro.html">itemviews/frozencolumn/frozencolumn.pro</a></li>
<li><a href="qtwidgets-itemviews-frozencolumn-grades-qrc.html">itemviews/frozencolumn/grades.qrc</a></li>
<li><a href="qtwidgets-itemviews-frozencolumn-main-cpp.html">itemviews/frozencolumn/main.cpp</a></li>
</ul>
</div>
<!-- @@@itemviews/frozencolumn -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2019 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br/>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br/>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>