Sophie

Sophie

distrib > Mageia > 7 > armv7hl > media > core-updates > by-pkgid > d5e62c01ae8d1e579463c6a871dd44bf > files > 4523

qtbase5-doc-5.12.6-2.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" />
<!-- customsortfiltermodel.qdoc -->
  <title>Custom Sort/Filter Model 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 >Custom Sort/Filter Model 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="#mysortfilterproxymodel-class-definition">MySortFilterProxyModel Class Definition</a></li>
<li class="level1"><a href="#mysortfilterproxymodel-class-implementation">MySortFilterProxyModel Class Implementation</a></li>
<li class="level1"><a href="#window-class-definition">Window Class Definition</a></li>
<li class="level1"><a href="#window-class-implementation">Window Class Implementation</a></li>
<li class="level1"><a href="#the-main-function">The Main() Function</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Custom Sort/Filter Model Example</h1>
<span class="subtitle"></span>
<!-- $$$itemviews/customsortfiltermodel-brief -->
<p>The Custom Sort/Filter Model example illustrates how to subclass <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a> to perform advanced sorting and filtering.</p>
<!-- @@@itemviews/customsortfiltermodel -->
<!-- $$$itemviews/customsortfiltermodel-description -->
<div class="descr"> <a name="details"></a>
<p class="centerAlign"><img src="images/customsortfiltermodel-example.png" alt="Screenshot of the Custom Sort/Filter Model Example" /></p><p>The <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a> class provides support for sorting and filtering data passed between another model and a view.</p>
<p>The model transforms the structure of a source model by mapping the model indexes it supplies to new indexes, corresponding to different locations, for views to use. This approach allows a given source model to be restructured as far as views are concerned, without requiring any transformations on the underlying data and without duplicating the data in memory.</p>
<p>The Custom Sort/Filter Model example consists of two classes:</p>
<ul>
<li>The <code>MySortFilterProxyModel</code> class provides a custom proxy model.</li>
<li>The <code>Window</code> class provides the main application window, using the custom proxy model to sort and filter a standard item model.</li>
</ul>
<p>We will first take a look at the <code>MySortFilterProxyModel</code> class to see how the custom proxy model is implemented, then we will take a look at the <code>Window</code> class to see how the model is used. Finally we will take a quick look at the <code>main()</code> function.</p>
<a name="mysortfilterproxymodel-class-definition"></a>
<h2 id="mysortfilterproxymodel-class-definition">MySortFilterProxyModel Class Definition</h2>
<p>The <code>MySortFilterProxyModel</code> class inherits the <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a> class.</p>
<p>Since <a href="../qtcore/qabstractproxymodel.html">QAbstractProxyModel</a> and its subclasses are derived from <a href="../qtcore/qabstractitemmodel.html">QAbstractItemModel</a>, much of the same advice about subclassing normal models also applies to proxy models.</p>
<p>On the other hand, it is worth noting that many of <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a>'s default implementations of functions are written so that they call the equivalent functions in the relevant source model. This simple proxying mechanism may need to be overridden for source models with more complex behavior. In this example we derive from the <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a> class to ensure that our filter can recognize a valid range of dates, and to control the sorting behavior.</p>
<pre class="cpp">

  <span class="keyword">class</span> MySortFilterProxyModel : <span class="keyword">public</span> <span class="type"><a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a></span>
  {
      Q_OBJECT

  <span class="keyword">public</span>:
      MySortFilterProxyModel(<span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);

      <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> filterMinimumDate() <span class="keyword">const</span> { <span class="keyword">return</span> minDate; }
      <span class="type">void</span> setFilterMinimumDate(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> <span class="operator">&amp;</span>date);

      <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> filterMaximumDate() <span class="keyword">const</span> { <span class="keyword">return</span> maxDate; }
      <span class="type">void</span> setFilterMaximumDate(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> <span class="operator">&amp;</span>date);

  <span class="keyword">protected</span>:
      bool filterAcceptsRow(<span class="type">int</span> sourceRow<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>sourceParent) <span class="keyword">const</span> override;
      bool lessThan(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>left<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>right) <span class="keyword">const</span> override;

  <span class="keyword">private</span>:
      bool dateInRange(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> <span class="operator">&amp;</span>date) <span class="keyword">const</span>;

      <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> minDate;
      <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> maxDate;
  };

</pre>
<p>We want to be able to filter our data by specifying a given period of time. For that reason, we implement the custom <code>setFilterMinimumDate()</code> and <code>setFilterMaximumDate()</code> functions as well as the corresponding <code>filterMinimumDate()</code> and <code>filterMaximumDate()</code> functions. We reimplement <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a>'s <a href="../qtcore/qsortfilterproxymodel.html#filterAcceptsRow">filterAcceptsRow()</a> function to only accept rows with valid dates, and <a href="../qtcore/qsortfilterproxymodel.html#lessThan">QSortFilterProxyModel::lessThan</a>() to be able to sort the senders by their email addresses. Finally, we implement a <code>dateInRange()</code> convenience function that we will use to determine if a date is valid.</p>
<a name="mysortfilterproxymodel-class-implementation"></a>
<h2 id="mysortfilterproxymodel-class-implementation">MySortFilterProxyModel Class Implementation</h2>
<p>The <code>MySortFilterProxyModel</code> constructor is trivial, passing the parent parameter on to the base class constructor:</p>
<pre class="cpp">

  MySortFilterProxyModel<span class="operator">::</span>MySortFilterProxyModel(<span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>parent)
      : <span class="type"><a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a></span>(parent)
  {
  }

</pre>
<p>The most interesting parts of the <code>MySortFilterProxyModel</code> implementation are the reimplementations of <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a>'s <a href="../qtcore/qsortfilterproxymodel.html#filterAcceptsRow">filterAcceptsRow()</a> and <a href="../qtcore/qsortfilterproxymodel.html#lessThan">lessThan()</a> functions. Let's first take a look at our customized <code>lessThan()</code> function.</p>
<pre class="cpp">

  bool MySortFilterProxyModel<span class="operator">::</span>lessThan(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>left<span class="operator">,</span>
                                        <span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>right) <span class="keyword">const</span>
  {
      <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> leftData <span class="operator">=</span> sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>data(left);
      <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> rightData <span class="operator">=</span> sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>data(right);

</pre>
<p>We want to sort the senders by their email addresses. The <a href="../qtcore/qsortfilterproxymodel.html#lessThan">lessThan()</a> function is used as the &lt; operator when sorting. The default implementation handles a collection of types including <a href="../qtcore/qdatetime.html">QDateTime</a> and String, but in order to be able to sort the senders by their email addresses we must first identify the address within the given string:</p>
<pre class="cpp">

      <span class="keyword">if</span> (leftData<span class="operator">.</span>type() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span><span class="operator">::</span>DateTime) {
          <span class="keyword">return</span> leftData<span class="operator">.</span>toDateTime() <span class="operator">&lt;</span> rightData<span class="operator">.</span>toDateTime();
      } <span class="keyword">else</span> {
          <span class="keyword">static</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qregularexpression.html">QRegularExpression</a></span> emailPattern(<span class="string">&quot;[\\w\\.]*@[\\w\\.]*&quot;</span>);

          <span class="type"><a href="../qtcore/qstring.html">QString</a></span> leftString <span class="operator">=</span> leftData<span class="operator">.</span>toString();
          <span class="keyword">if</span> (left<span class="operator">.</span>column() <span class="operator">=</span><span class="operator">=</span> <span class="number">1</span>) {
              <span class="keyword">const</span> <span class="type"><a href="../qtcore/qregularexpressionmatch.html">QRegularExpressionMatch</a></span> match <span class="operator">=</span> emailPattern<span class="operator">.</span>match(leftString);
              <span class="keyword">if</span> (match<span class="operator">.</span>hasMatch())
                  leftString <span class="operator">=</span> match<span class="operator">.</span>captured(<span class="number">0</span>);
          }
          <span class="type"><a href="../qtcore/qstring.html">QString</a></span> rightString <span class="operator">=</span> rightData<span class="operator">.</span>toString();
          <span class="keyword">if</span> (right<span class="operator">.</span>column() <span class="operator">=</span><span class="operator">=</span> <span class="number">1</span>) {
              <span class="keyword">const</span> <span class="type"><a href="../qtcore/qregularexpressionmatch.html">QRegularExpressionMatch</a></span> match <span class="operator">=</span> emailPattern<span class="operator">.</span>match(rightString);
              <span class="keyword">if</span> (match<span class="operator">.</span>hasMatch())
                  rightString <span class="operator">=</span> match<span class="operator">.</span>captured(<span class="number">0</span>);
          }

          <span class="keyword">return</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span><span class="operator">::</span>localeAwareCompare(leftString<span class="operator">,</span> rightString) <span class="operator">&lt;</span> <span class="number">0</span>;
      }
  }

</pre>
<p>We use <a href="../qtcore/qregularexpression.html">QRegularExpression</a> to define a pattern for the addresses we are looking for. The <a href="../qtcore/qregularexpression.html#match">match()</a> function returns a <a href="../qtcore/qregularexpressionmatch.html">QRegularExpressionMatch</a> object which contains the result of the matching. If there is a match, <a href="../qtcore/qregularexpressionmatch.html#hasMatch">hasMatch()</a> returns true. The result of the match can be retrieved with <a href="../qtcore/qregularexpressionmatch.html">QRegularExpressionMatch</a>'s <a href="../qtcore/qregularexpressionmatch.html#captured-2">captured()</a> function. The entire match has index 0 and the parenthesized subexpressions have indexes starting from 1 (excluding non-capturing parentheses).</p>
<pre class="cpp">

  bool MySortFilterProxyModel<span class="operator">::</span>filterAcceptsRow(<span class="type">int</span> sourceRow<span class="operator">,</span>
          <span class="keyword">const</span> <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> <span class="operator">&amp;</span>sourceParent) <span class="keyword">const</span>
  {
      <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> index0 <span class="operator">=</span> sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>index(sourceRow<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> sourceParent);
      <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> index1 <span class="operator">=</span> sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>index(sourceRow<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> sourceParent);
      <span class="type"><a href="../qtcore/qmodelindex.html">QModelIndex</a></span> index2 <span class="operator">=</span> sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>index(sourceRow<span class="operator">,</span> <span class="number">2</span><span class="operator">,</span> sourceParent);

      <span class="keyword">return</span> (sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>data(index0)<span class="operator">.</span>toString()<span class="operator">.</span>contains(filterRegExp())
              <span class="operator">|</span><span class="operator">|</span> sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>data(index1)<span class="operator">.</span>toString()<span class="operator">.</span>contains(filterRegExp()))
              <span class="operator">&amp;</span><span class="operator">&amp;</span> dateInRange(sourceModel()<span class="operator">-</span><span class="operator">&gt;</span>data(index2)<span class="operator">.</span>toDate());
  }

</pre>
<p>The <a href="../qtcore/qsortfilterproxymodel.html#filterAcceptsRow">filterAcceptsRow()</a> function, on the other hand, is expected to return true if the given row should be included in the model. In our example, a row is accepted if either the subject or the sender contains the given regular expression, and the date is valid.</p>
<pre class="cpp">

  bool MySortFilterProxyModel<span class="operator">::</span>dateInRange(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> <span class="operator">&amp;</span>date) <span class="keyword">const</span>
  {
      <span class="keyword">return</span> (<span class="operator">!</span>minDate<span class="operator">.</span>isValid() <span class="operator">|</span><span class="operator">|</span> date <span class="operator">&gt;</span> minDate)
              <span class="operator">&amp;</span><span class="operator">&amp;</span> (<span class="operator">!</span>maxDate<span class="operator">.</span>isValid() <span class="operator">|</span><span class="operator">|</span> date <span class="operator">&lt;</span> maxDate);
  }

</pre>
<p>We use our custom <code>dateInRange()</code> function to determine if a date is valid.</p>
<p>To be able to filter our data by specifying a given period of time, we also implement functions for getting and setting the minimum and maximum dates:</p>
<pre class="cpp">

  <span class="type">void</span> MySortFilterProxyModel<span class="operator">::</span>setFilterMinimumDate(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> <span class="operator">&amp;</span>date)
  {
      minDate <span class="operator">=</span> date;
      invalidateFilter();
  }

  <span class="type">void</span> MySortFilterProxyModel<span class="operator">::</span>setFilterMaximumDate(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qdate.html">QDate</a></span> <span class="operator">&amp;</span>date)
  {
      maxDate <span class="operator">=</span> date;
      invalidateFilter();
  }

</pre>
<p>The get functions, <code>filterMinimumDate()</code> and <code>filterMaximumDate()</code>, are trivial and implemented as inline function in the header file.</p>
<p>This completes our custom proxy model. Let's see how we can use it in an application.</p>
<a name="window-class-definition"></a>
<h2 id="window-class-definition">Window Class Definition</h2>
<p>The <code>CustomFilter</code> class inherits <a href="qwidget.html">QWidget</a>, and provides this example's main application window:</p>
<pre class="cpp">

  <span class="keyword">class</span> Window : <span class="keyword">public</span> <span class="type"><a href="qwidget.html">QWidget</a></span>
  {
      Q_OBJECT

  <span class="keyword">public</span>:
      Window();

      <span class="type">void</span> setSourceModel(<span class="type"><a href="../qtcore/qabstractitemmodel.html">QAbstractItemModel</a></span> <span class="operator">*</span>model);

  <span class="keyword">private</span> <span class="keyword">slots</span>:
      <span class="type">void</span> textFilterChanged();
      <span class="type">void</span> dateFilterChanged();

  <span class="keyword">private</span>:
      MySortFilterProxyModel <span class="operator">*</span>proxyModel;

      <span class="type"><a href="qgroupbox.html">QGroupBox</a></span> <span class="operator">*</span>sourceGroupBox;
      <span class="type"><a href="qgroupbox.html">QGroupBox</a></span> <span class="operator">*</span>proxyGroupBox;
      <span class="type"><a href="qtreeview.html">QTreeView</a></span> <span class="operator">*</span>sourceView;
      <span class="type"><a href="qtreeview.html">QTreeView</a></span> <span class="operator">*</span>proxyView;
      <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>filterPatternLabel;
      <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>fromLabel;
      <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>toLabel;
      FilterWidget <span class="operator">*</span>filterWidget;
      <span class="type"><a href="qdateedit.html">QDateEdit</a></span> <span class="operator">*</span>fromDateEdit;
      <span class="type"><a href="qdateedit.html">QDateEdit</a></span> <span class="operator">*</span>toDateEdit;
  };

</pre>
<p>We implement two private slots, <code>textFilterChanged()</code> and <code>dateFilterChanged()</code>, to respond to the user changing the filter pattern, case sensitivity, or any of the dates. In addition, we implement a public <code>setSourceModel()</code> convenience function to set up the model/ view relation.</p>
<a name="window-class-implementation"></a>
<h2 id="window-class-implementation">Window Class Implementation</h2>
<p>In this example, we have chosen to create and set the source model in the <code>main</code> () function (which we will come back to later). So when constructing the main application window, we assume that a source model already exists and start by creating an instance of our custom proxy model:</p>
<pre class="cpp">

  Window<span class="operator">::</span>Window()
  {
      proxyModel <span class="operator">=</span> <span class="keyword">new</span> MySortFilterProxyModel(<span class="keyword">this</span>);

</pre>
<p>We set the <a href="../qtcore/qsortfilterproxymodel.html#dynamicSortFilter-prop">dynamicSortFilter</a> property that holds whether the proxy model is dynamically sorted and filtered. By setting this property to true, we ensure that the model is sorted and filtered whenever the contents of the source model change.</p>
<p>The main application window shows views of both the source model and the proxy model. The source view is quite simple:</p>
<pre class="cpp">

  sourceView <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtreeview.html">QTreeView</a></span>;
  sourceView<span class="operator">-</span><span class="operator">&gt;</span>setRootIsDecorated(<span class="keyword">false</span>);
  sourceView<span class="operator">-</span><span class="operator">&gt;</span>setAlternatingRowColors(<span class="keyword">true</span>);

</pre>
<p>The <a href="qtreeview.html">QTreeView</a> class provides a default model/view implementation of a tree view. Our view implements a tree representation of items in the application's source model.</p>
<pre class="cpp">

  sourceLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(sourceView);
  sourceGroupBox <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgroupbox.html">QGroupBox</a></span>(tr(<span class="string">&quot;Original Model&quot;</span>));
  sourceGroupBox<span class="operator">-</span><span class="operator">&gt;</span>setLayout(sourceLayout);

</pre>
<p>The <a href="qtreeview.html">QTreeView</a> class provides a default model/view implementation of a tree view; our view implements a tree representation of items in the application's source model. We add our view widget to a layout that we install on a corresponding group box.</p>
<p>The proxy model view, on the other hand, contains several widgets controlling the various aspects of transforming the source model's data structure:</p>
<pre class="cpp">

  filterWidget <span class="operator">=</span> <span class="keyword">new</span> FilterWidget;
  filterWidget<span class="operator">-</span><span class="operator">&gt;</span>setText(<span class="string">&quot;Grace|Sports&quot;</span>);
  connect(filterWidget<span class="operator">,</span> <span class="operator">&amp;</span>FilterWidget<span class="operator">::</span>filterChanged<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> <span class="operator">&amp;</span>Window<span class="operator">::</span>textFilterChanged);

  filterPatternLabel <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qlabel.html">QLabel</a></span>(tr(<span class="string">&quot;&amp;Filter pattern:&quot;</span>));
  filterPatternLabel<span class="operator">-</span><span class="operator">&gt;</span>setBuddy(filterWidget);

  fromDateEdit <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qdateedit.html">QDateEdit</a></span>;
  fromDateEdit<span class="operator">-</span><span class="operator">&gt;</span>setDate(<span class="type"><a href="../qtcore/qdate.html">QDate</a></span>(<span class="number">1970</span><span class="operator">,</span> <span class="number">01</span><span class="operator">,</span> <span class="number">01</span>));
  fromLabel <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qlabel.html">QLabel</a></span>(tr(<span class="string">&quot;F&amp;rom:&quot;</span>));
  fromLabel<span class="operator">-</span><span class="operator">&gt;</span>setBuddy(fromDateEdit);

  toDateEdit <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qdateedit.html">QDateEdit</a></span>;
  toDateEdit<span class="operator">-</span><span class="operator">&gt;</span>setDate(<span class="type"><a href="../qtcore/qdate.html">QDate</a></span>(<span class="number">2099</span><span class="operator">,</span> <span class="number">12</span><span class="operator">,</span> <span class="number">31</span>));
  toLabel <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qlabel.html">QLabel</a></span>(tr(<span class="string">&quot;&amp;To:&quot;</span>));
  toLabel<span class="operator">-</span><span class="operator">&gt;</span>setBuddy(toDateEdit);

  connect(filterWidget<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qlineedit.html">QLineEdit</a></span><span class="operator">::</span>textChanged<span class="operator">,</span>
          <span class="keyword">this</span><span class="operator">,</span> <span class="operator">&amp;</span>Window<span class="operator">::</span>textFilterChanged);
  connect(fromDateEdit<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qdatetimeedit.html">QDateTimeEdit</a></span><span class="operator">::</span>dateChanged<span class="operator">,</span>
          <span class="keyword">this</span><span class="operator">,</span> <span class="operator">&amp;</span>Window<span class="operator">::</span>dateFilterChanged);
  connect(toDateEdit<span class="operator">,</span> <span class="operator">&amp;</span><span class="type"><a href="qdatetimeedit.html">QDateTimeEdit</a></span><span class="operator">::</span>dateChanged<span class="operator">,</span>
  <span class="keyword">this</span><span class="operator">,</span> <span class="operator">&amp;</span>Window<span class="operator">::</span>dateFilterChanged);

</pre>
<p>Note that whenever the user changes one of the filtering options, we must explicitly reapply the filter. This is done by connecting the various editors to functions that update the proxy model.</p>
<pre class="cpp">

  proxyView <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtreeview.html">QTreeView</a></span>;
  proxyView<span class="operator">-</span><span class="operator">&gt;</span>setRootIsDecorated(<span class="keyword">false</span>);
  proxyView<span class="operator">-</span><span class="operator">&gt;</span>setAlternatingRowColors(<span class="keyword">true</span>);
  proxyView<span class="operator">-</span><span class="operator">&gt;</span>setModel(proxyModel);
  proxyView<span class="operator">-</span><span class="operator">&gt;</span>setSortingEnabled(<span class="keyword">true</span>);
  proxyView<span class="operator">-</span><span class="operator">&gt;</span>sortByColumn(<span class="number">1</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>AscendingOrder);

  <span class="type"><a href="qgridlayout.html">QGridLayout</a></span> <span class="operator">*</span>proxyLayout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgridlayout.html">QGridLayout</a></span>;
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(proxyView<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">3</span>);
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(filterPatternLabel<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span>);
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(filterWidget<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span>);
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(fromLabel<span class="operator">,</span> <span class="number">3</span><span class="operator">,</span> <span class="number">0</span>);
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(fromDateEdit<span class="operator">,</span> <span class="number">3</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">2</span>);
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(toLabel<span class="operator">,</span> <span class="number">4</span><span class="operator">,</span> <span class="number">0</span>);
  proxyLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(toDateEdit<span class="operator">,</span> <span class="number">4</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">2</span>);

  proxyGroupBox <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgroupbox.html">QGroupBox</a></span>(tr(<span class="string">&quot;Sorted/Filtered Model&quot;</span>));
  proxyGroupBox<span class="operator">-</span><span class="operator">&gt;</span>setLayout(proxyLayout);

</pre>
<p>The sorting will be handled by the view. All we have to do is to enable sorting for our proxy view by setting the <a href="qtreeview.html#sortingEnabled-prop">QTreeView::sortingEnabled</a> property (which is false by default). Then we add all the filtering widgets and the proxy view to a layout that we install on a corresponding group box.</p>
<pre class="cpp">

  <span class="type"><a href="qvboxlayout.html">QVBoxLayout</a></span> <span class="operator">*</span>mainLayout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qvboxlayout.html">QVBoxLayout</a></span>;
  mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(sourceGroupBox);
  mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(proxyGroupBox);
  setLayout(mainLayout);

  setWindowTitle(tr(<span class="string">&quot;Custom Sort/Filter Model&quot;</span>));
  resize(<span class="number">500</span><span class="operator">,</span> <span class="number">450</span>);
  }

</pre>
<p>Finally, after putting our two group boxes into another layout that we install on our main application widget, we customize the application window.</p>
<p>As mentioned above, we create the source model in the <code>main</code> () function, calling the <code>Window::setSourceModel()</code> function to make the application use it:</p>
<pre class="cpp">

  <span class="type">void</span> Window<span class="operator">::</span>setSourceModel(<span class="type"><a href="../qtcore/qabstractitemmodel.html">QAbstractItemModel</a></span> <span class="operator">*</span>model)
  {
      proxyModel<span class="operator">-</span><span class="operator">&gt;</span>setSourceModel(model);
      sourceView<span class="operator">-</span><span class="operator">&gt;</span>setModel(model);
  }

</pre>
<p>The <a href="../qtcore/qsortfilterproxymodel.html#setSourceModel">QSortFilterProxyModel::setSourceModel</a>() function makes the proxy model process the data in the given model, in this case out mail model. The <a href="qabstractitemview.html#setModel">setModel()</a> that the view widget inherits from the <a href="../qtcore/qabstractitemmodel.html">QAbstractItemModel</a> class, sets the model for the view to present. Note that the latter function will also create and set a new selection model.</p>
<pre class="cpp">

  <span class="type">void</span> Window<span class="operator">::</span>textFilterChanged()
  {
      <span class="type"><a href="../qtcore/qregexp.html">QRegExp</a></span> regExp(filterWidget<span class="operator">-</span><span class="operator">&gt;</span>text()<span class="operator">,</span>
                     filterWidget<span class="operator">-</span><span class="operator">&gt;</span>caseSensitivity()<span class="operator">,</span>
                     filterWidget<span class="operator">-</span><span class="operator">&gt;</span>patternSyntax());
      proxyModel<span class="operator">-</span><span class="operator">&gt;</span>setFilterRegExp(regExp);
  }

</pre>
<p>The <code>textFilterChanged()</code> function is called whenever the user changes the filter pattern or the case sensitivity.</p>
<p>We first retrieve the preferred syntax (the <a href="../qtcore/qregexp.html#PatternSyntax-enum">QRegExp::PatternSyntax</a> enum is used to interpret the meaning of the given pattern), then we determine the preferred case sensitivity. Based on these preferences and the current filter pattern, we set the proxy model's <a href="../qtcore/qsortfilterproxymodel.html#filterRegExp-prop">filterRegExp</a> property. The <a href="../qtcore/qsortfilterproxymodel.html#filterRegExp-prop">filterRegExp</a> property holds the regular expression used to filter the contents of the source model. Note that calling <a href="../qtcore/qsortfilterproxymodel.html">QSortFilterProxyModel</a>'s <a href="../qtcore/qsortfilterproxymodel.html#filterRegExp-prop">setFilterRegExp()</a> function also updates the model.</p>
<pre class="cpp">

  <span class="type">void</span> Window<span class="operator">::</span>dateFilterChanged()
  {
      proxyModel<span class="operator">-</span><span class="operator">&gt;</span>setFilterMinimumDate(fromDateEdit<span class="operator">-</span><span class="operator">&gt;</span>date());
      proxyModel<span class="operator">-</span><span class="operator">&gt;</span>setFilterMaximumDate(toDateEdit<span class="operator">-</span><span class="operator">&gt;</span>date());
  }

</pre>
<p>The <code>dateFilterChanged()</code> function is called whenever the user modifies the range of valid dates. We retrieve the new dates from the user interface, and call the corresponding functions (provided by our custom proxy model) to set the proxy model's minimum and maximum dates. As we explained above, calling these functions also updates the model.</p>
<a name="the-main-function"></a>
<h2 id="the-main-function">The Main() Function</h2>
<p>In this example, we have separated the application from the source model by creating the model in the <code>main</code> () function. First we create the application, then we create the source model:</p>
<pre class="cpp">

  <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
  {
      <span class="type"><a href="qapplication.html">QApplication</a></span> app(argc<span class="operator">,</span> argv);
      Window window;
      window<span class="operator">.</span>setSourceModel(createMailModel(<span class="operator">&amp;</span>window));
      window<span class="operator">.</span>show();
      <span class="keyword">return</span> app<span class="operator">.</span>exec();
  }

</pre>
<p>The <code>createMailModel()</code> function is a convenience function provided to simplify the constructor. All it does is to create and return a model describing a collection of emails. The model is an instance of the <a href="../qtgui/qstandarditemmodel.html">QStandardItemModel</a> class, i.e&#x2e;, a generic model for storing custom data typically used as a repository for standard Qt data types. Each mail description is added to the model using <code>addMail()</code>, another convenience function. See <a href="qtwidgets-itemviews-customsortfiltermodel-main-cpp.html">main.cpp</a> for details.</p>
<p>Files:</p>
<ul>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-customsortfiltermodel-pro.html">itemviews/customsortfiltermodel/customsortfiltermodel.pro</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-customsortfiltermodel-qrc.html">itemviews/customsortfiltermodel/customsortfiltermodel.qrc</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-filterwidget-cpp.html">itemviews/customsortfiltermodel/filterwidget.cpp</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-filterwidget-h.html">itemviews/customsortfiltermodel/filterwidget.h</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-main-cpp.html">itemviews/customsortfiltermodel/main.cpp</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-mysortfilterproxymodel-cpp.html">itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-mysortfilterproxymodel-h.html">itemviews/customsortfiltermodel/mysortfilterproxymodel.h</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-window-cpp.html">itemviews/customsortfiltermodel/window.cpp</a></li>
<li><a href="qtwidgets-itemviews-customsortfiltermodel-window-h.html">itemviews/customsortfiltermodel/window.h</a></li>
</ul>
<p>Images:</p>
<ul>
<li><a href="images/used-in-examples/itemviews/customsortfiltermodel/images/find.png">itemviews/customsortfiltermodel/images/find.png</a></li>
</ul>
</div>
<!-- @@@itemviews/customsortfiltermodel -->
        </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>