<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Saving QTableView state]]></title><description><![CDATA[<p dir="auto">If a user has moved/resized the table columns, I want to save that when the  table view is closed</p>
<ol>
<li>
<p dir="auto">Is that accomplished with e.g.</p>
<p dir="auto">QSettings settings;<br />
settings.setValue("windowState", saveState());</p>
</li>
</ol>
<p dir="auto">for the table view?</p>
<ol start="2">
<li>Is it possible to do this without sub-classing QTableView to add a closeEvent handler?   Can I do this in the owning widget's closeEvent() or has the TableView gone at that point?</li>
</ol>
<p dir="auto">Thanks<br />
David</p>
]]></description><link>https://forum.qt.io/topic/139535/saving-qtableview-state</link><generator>RSS for Node</generator><lastBuildDate>Thu, 05 Nov 2026 06:34:31 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/139535.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 24 Sep 2022 08:49:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Saving QTableView state on Sun, 25 Sep 2022 12:11:47 GMT]]></title><description><![CDATA[<p dir="auto">The final code to save the state of the Horizontal header in the QMainWindow::closeEvent handler reads like this:</p>
<pre><code>QSettings settings;
settings.setValue("geometry", saveGeometry());
settings.setValue("windowState", saveState());
QTableView* tableView = this-&gt;findChild&lt;QTableView*&gt;("tableView");
settings.setValue("Dialogs/StackingDlg/TableView/HorizontalHeader/windowState",
	tableView-&gt;horizontalHeader()-&gt;saveState());
</code></pre>
<p dir="auto">it relies on the tableView object being named but that is normally true.<br />
David</p>
]]></description><link>https://forum.qt.io/post/730096</link><guid isPermaLink="true">https://forum.qt.io/post/730096</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sun, 25 Sep 2022 12:11:47 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sun, 25 Sep 2022 12:10:44 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a> said in <a href="/post/730098">Saving QTableView state</a>:</p>
<blockquote>
<p dir="auto">Is this a statement about what you are "happy" with</p>
</blockquote>
<p dir="auto">Yes, I am happy with the normal default behaviour.</p>
<p dir="auto">I wasn't aware of all the stuff in your reply, but all are useful bits of information.</p>
<p dir="auto">I only have one table view to worry about :)</p>
<p dir="auto">Thanks<br />
D.</p>
]]></description><link>https://forum.qt.io/post/730099</link><guid isPermaLink="true">https://forum.qt.io/post/730099</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sun, 25 Sep 2022 12:10:44 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sun, 25 Sep 2022 12:26:47 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/perdrix">@<bdi>Perdrix</bdi></a> said in <a href="/post/730096">Saving QTableView state</a>:</p>
<blockquote>
<p dir="auto">it relies on the tableView object being named but is normally true.</p>
</blockquote>
<p dir="auto">Is this a statement about what you are "happy" with as your behaviour, or something you might like improved?  Just a couple of comments:</p>
<ul>
<li>
<p dir="auto"><em>IF</em> you have only one table view then (are you aware that) you can omit the object name and just go <code>this-&gt;findChild&lt;QTableView*&gt;()</code>, so you do not <em>have to</em> set any object name on it?</p>
</li>
<li>
<p dir="auto">If you have more than one, which one are you looking for to be saved under <code>Dialogs/StackingDlg/TableView/HorizontalHeader/windowState</code>?</p>
</li>
<li>
<p dir="auto">Instead of relying on the object name, you <em>might</em> consider adding a <em>property</em> to the/those table view(s) to indicate this is/should be "saved", and search among all table views for that/those which have this property.</p>
</li>
<li>
<p dir="auto">Of course, you could also subclass the <code>QTableView</code> to, say, a <code>QSaveableTableView</code> and search for that class.</p>
</li>
</ul>
]]></description><link>https://forum.qt.io/post/730098</link><guid isPermaLink="true">https://forum.qt.io/post/730098</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Sun, 25 Sep 2022 12:26:47 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sun, 25 Sep 2022 12:11:47 GMT]]></title><description><![CDATA[<p dir="auto">The final code to save the state of the Horizontal header in the QMainWindow::closeEvent handler reads like this:</p>
<pre><code>QSettings settings;
settings.setValue("geometry", saveGeometry());
settings.setValue("windowState", saveState());
QTableView* tableView = this-&gt;findChild&lt;QTableView*&gt;("tableView");
settings.setValue("Dialogs/StackingDlg/TableView/HorizontalHeader/windowState",
	tableView-&gt;horizontalHeader()-&gt;saveState());
</code></pre>
<p dir="auto">it relies on the tableView object being named but that is normally true.<br />
David</p>
]]></description><link>https://forum.qt.io/post/730096</link><guid isPermaLink="true">https://forum.qt.io/post/730096</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sun, 25 Sep 2022 12:11:47 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 16:10:51 GMT]]></title><description><![CDATA[<p dir="auto">Arrghh forgot I was saving that in the class !!!</p>
<p dir="auto">Except of course ui is private in DSS:StackingDlg.  So I had to make the main window a friend of DSS::StackingDlg</p>
<p dir="auto">And it worked fine</p>
<p dir="auto">Thanks all<br />
D.</p>
]]></description><link>https://forum.qt.io/post/730046</link><guid isPermaLink="true">https://forum.qt.io/post/730046</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sat, 24 Sep 2022 16:10:51 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 15:32:31 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/perdrix">@<bdi>Perdrix</bdi></a> said in <a href="/post/730043">Saving QTableView state</a>:</p>
<blockquote>
<p dir="auto">It's a royal mess to access the tableView from the closeEvent of the QMainWindow.</p>
</blockquote>
<p dir="auto">Why ?</p>
<pre><code>stackingDlg = new DSS::StackingDlg(widget);
stackingDlg-&gt;setObjectName("stackingDlg");
</code></pre>
<p dir="auto">stackingDlg not a variable of your mainWindow ?<br />
you can even retrieve it by its name ;)</p>
]]></description><link>https://forum.qt.io/post/730044</link><guid isPermaLink="true">https://forum.qt.io/post/730044</guid><dc:creator><![CDATA[mpergand]]></dc:creator><pubDate>Sat, 24 Sep 2022 15:32:31 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 15:34:45 GMT]]></title><description><![CDATA[<p dir="auto">Hmmm the closeEvent() of StackingDlg also doesn't get triggered.</p>
<p dir="auto">It's a royal mess to access the tableView from the closeEvent of the QMainWindow.</p>
<p dir="auto"><s>Would the destroy() mf for StackingDlg (which owns the QTableView) be a good location to save the horizontal header state for the table view?</s></p>
<p dir="auto">UPDATE!  Arrgh QWidget::destroy() isn't virtual so I can't use that!</p>
<p dir="auto">So what can I use simply to detect the one of my Widgets is going away.</p>
<p dir="auto">PS setting the context menu policy for the table view to Qt::CustomContextMenu and having:</p>
<pre><code>void StackingDlg::on_tableView_customContextMenuRequested(const QPoint&amp; pos)
</code></pre>
<p dir="auto">is a really nice way to handle the popup menu!</p>
<p dir="auto">Thanks<br />
David</p>
]]></description><link>https://forum.qt.io/post/730043</link><guid isPermaLink="true">https://forum.qt.io/post/730043</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sat, 24 Sep 2022 15:34:45 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 12:46:55 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/perdrix">@<bdi>Perdrix</bdi></a> said in <a href="/post/730032">Saving QTableView state</a>:</p>
<blockquote>
<p dir="auto">I sub-classed QTableView:</p>
</blockquote>
<p dir="auto">No need to subclass, neither for save/restore state, nor for context menu.</p>
<p dir="auto">As <a class="plugin-mentions-user plugin-mentions-a" href="/user/sgaist">@<bdi>SGaist</bdi></a>  said, do the all thing in the top level widget.<br />
showEvent and closeEvent for the state,<br />
and use customContextMenuRequested signal, see setContextMenuPolicy().</p>
]]></description><link>https://forum.qt.io/post/730038</link><guid isPermaLink="true">https://forum.qt.io/post/730038</guid><dc:creator><![CDATA[mpergand]]></dc:creator><pubDate>Sat, 24 Sep 2022 12:46:55 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 12:18:22 GMT]]></title><description><![CDATA[<p dir="auto">So does that mean only the QMainWindow gets a closeEvent, or that if the TableView is a child of a Widget called StackingDlg, that it will get a closeEvent() ?</p>
<p dir="auto">In this case the StackingDlg is someway down the hierarchy from QMainWindow:</p>
<pre><code>	widget = new QWidget(this);
	widget-&gt;setObjectName("centralWidget");
	setCentralWidget(widget);

	QHBoxLayout* horizontalLayout{ new QHBoxLayout(widget) };
	widget-&gt;setLayout(horizontalLayout);
	ZTRACE_RUNTIME("Creating Horizontal Splitter");
	splitter = new QSplitter(Qt::Horizontal, widget);
	splitter-&gt;setObjectName("splitter");

	ZTRACE_RUNTIME("Creating Explorer Bar (Left Panel)");
	explorerBar = new ExplorerBar(widget);
	explorerBar-&gt;setObjectName("explorerBar");
	splitter-&gt;addWidget(explorerBar);

	ZTRACE_RUNTIME("Creating stackedWidget");
	stackedWidget = new QStackedWidget(splitter);
	stackedWidget-&gt;setObjectName("stackedWidget");
	splitter-&gt;addWidget(stackedWidget);

	ZTRACE_RUNTIME("Creating Stacking Panel");
	stackingDlg = new DSS::StackingDlg(widget);
	stackingDlg-&gt;setObjectName("stackingDlg");

	ZTRACE_RUNTIME("Adding Stacking Panel to stackedWidget");
	stackedWidget-&gt;addWidget(stackingDlg);

	winHost = new QWinHost(stackedWidget);
	winHost-&gt;setObjectName("winHost");
	stackedWidget-&gt;addWidget(winHost);

	ZTRACE_RUNTIME("Creating Processing Panel");
	BOOL result = processingDlg.Create(IDD_PROCESSING);
	//processingDlg.OnInitDialog();

	HWND hwnd{ processingDlg.GetSafeHwnd() };
	Q_ASSERT(NULL != hwnd);
	winHost-&gt;setWindow(hwnd);

	splitter-&gt;setStretchFactor(1, 1);		// Want Stacking part to take any spare space.

	horizontalLayout-&gt;addWidget(splitter);
</code></pre>
]]></description><link>https://forum.qt.io/post/730034</link><guid isPermaLink="true">https://forum.qt.io/post/730034</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sat, 24 Sep 2022 12:18:22 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 12:09:48 GMT]]></title><description><![CDATA[<p dir="auto">Hi,</p>
<p dir="auto">Your error is to assume that all widgets get a close event. That's not the case. It's the case for the top level widget but not for its children.</p>
<p dir="auto">Also, the saving and loading of setting should rather be handled by the widget that manages it.</p>
]]></description><link>https://forum.qt.io/post/730033</link><guid isPermaLink="true">https://forum.qt.io/post/730033</guid><dc:creator><![CDATA[SGaist]]></dc:creator><pubDate>Sat, 24 Sep 2022 12:09:48 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 12:07:38 GMT]]></title><description><![CDATA[<p dir="auto">I sub-classed QTableView:</p>
<pre><code>#include &lt;QTableView&gt;

class QCloseEvent;
class QContextMenuEvent;

namespace DSS
{
    class TableView :
        public QTableView
    {
        typedef QTableView
            Inherited;

        Q_OBJECT

    public:
        explicit TableView(QWidget* parent = nullptr);

        ~TableView() noexcept
        {
        }

    protected:
        void closeEvent(&lsqb;&lsqb;maybe_unused&rsqb;&rsqb; QCloseEvent* e) override;

        void contextMenuEvent(&lsqb;&lsqb;maybe_unused&rsqb;&rsqb; QContextMenuEvent* event) override;
    };
}
</code></pre>
<p dir="auto">and in the cpp file:</p>
<pre><code>TableView::TableView(QWidget* parent) :
	QTableView{ parent }
{
	QSettings settings;
	horizontalHeader()-&gt;restoreState(
		settings.value("Dialogs/StackingDlg/TableView/HorizontalHeader/windowState").toByteArray());
}

void TableView::closeEvent(&lsqb;&lsqb;maybe_unused&rsqb;&rsqb; QCloseEvent* e)
{
	QSettings settings;
	settings.setValue("Dialogs/StackingDlg/TableView/HorizontalHeader/windowState", 
		horizontalHeader()-&gt;saveState());
}

void TableView::contextMenuEvent(&lsqb;&lsqb;maybe_unused&rsqb;&rsqb; QContextMenuEvent* e)
{
	QMenu menu(this);

	menu.exec(e-&gt;globalPos());
}
</code></pre>
<p dir="auto">But the closeEvent mf was not called (placed a breakpoint in there)???  (The ctor was invoked)</p>
<p dir="auto">What am I doing wrong?</p>
<p dir="auto">Thanks<br />
David</p>
]]></description><link>https://forum.qt.io/post/730032</link><guid isPermaLink="true">https://forum.qt.io/post/730032</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Sat, 24 Sep 2022 12:07:38 GMT</pubDate></item><item><title><![CDATA[Reply to Saving QTableView state on Sat, 24 Sep 2022 09:09:29 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/perdrix">@<bdi>Perdrix</bdi></a><br />
What do you think your <code>saveState()</code> is a member of?  Your <code>QTableView</code>??  It is <a href="https://doc.qt.io/qt-6/qmainwindow.html#saveState" target="_blank" rel="noopener noreferrer nofollow ugc">a method in <code>QMainWindow</code></a>:</p>
<blockquote>
<p dir="auto">Saves the current state of this mainwindow's toolbars and dockwidgets. This includes the corner settings which can be set with setCorner().</p>
</blockquote>
<p dir="auto">There is <a href="https://doc.qt.io/qt-6/qwidget.html#saveGeometry" target="_blank" rel="noopener noreferrer nofollow ugc">QWidget::saveGeometry()</a>, but:</p>
<blockquote>
<p dir="auto">Saves the current geometry and state for top-level widgets.</p>
</blockquote>
<p dir="auto">Your <code>QTableView</code> perhaps is not a "top-level" widget, and I think this would only save geometry, nothing about any columns.</p>
<p dir="auto">Ah, I see there is a <a href="https://doc.qt.io/qt-6/qheaderview.html#saveState" target="_blank" rel="noopener noreferrer nofollow ugc">QHeaderView::saveState()</a>.  I would assume this is what you want.</p>
<p dir="auto">Yes you should be able to call this from, say, "the owning widget's closeEvent() ".  That is delivered <em>before</em> the widget is closed, upon a <em>request</em> to close, because you can e.g. choose to <em>ignore</em> the event and the widget will not close.  The example at <a href="https://doc.qt.io/qt-6/qtwidgets-mainwindows-application-example.html#close-event-handler" target="_blank" rel="noopener noreferrer nofollow ugc">https://doc.qt.io/qt-6/qtwidgets-mainwindows-application-example.html#close-event-handler</a> is often used as the place to save settings.</p>
]]></description><link>https://forum.qt.io/post/730020</link><guid isPermaLink="true">https://forum.qt.io/post/730020</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Sat, 24 Sep 2022 09:09:29 GMT</pubDate></item></channel></rss>