<?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[Extra row in QTableView]]></title><description><![CDATA[<p dir="auto">If I add three rows to my empty table model, the table view display the three rows I inserted, plus an extra blank row.</p>
<p dir="auto">I'd much prefer not to have that!</p>
<p dir="auto">If this isn't normal behaviour, what might cause this to happen?</p>
<p dir="auto">Thanks<br />
D</p>
]]></description><link>https://forum.qt.io/topic/139518/extra-row-in-qtableview</link><generator>RSS for Node</generator><lastBuildDate>Wed, 07 Oct 2026 09:42:25 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/139518.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 23 Sep 2022 09:36:46 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 14:56:20 GMT]]></title><description><![CDATA[<p dir="auto">For my convenience, the FrameList class had this:</p>
<pre><code>inline FrameList&amp; beginInsertRows(int count) noexcept
{
	auto first{ imageGroups[index].pictures.rowCount() };	// Insert after end
	auto last{ first + count };
	imageGroups[index].pictures.beginInsertRows(QModelIndex(), first, last);
	return (*this);
}
</code></pre>
<p dir="auto">which I now realise had an "off by one" error!</p>
<p dir="auto">I changed the code to read:</p>
<p dir="auto">auto last{ first + count -1};</p>
<p dir="auto">and it now works as I would hope!!</p>
<p dir="auto">I also changed addImage() to read:</p>
<pre><code>void ImageListModel::addImage(ListBitMap image)
{
    Q_ASSERT(std::find(mydata.begin(), mydata.end(), image) == mydata.end());
            
    mydata.emplace_back(std::move(image));
}
</code></pre>
<p dir="auto">as it should never actually attempt to add the same file twice (there are other checks).</p>
<p dir="auto">Thanks for the help in tracking this down.</p>
<p dir="auto">D.</p>
]]></description><link>https://forum.qt.io/post/729967</link><guid isPermaLink="true">https://forum.qt.io/post/729967</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Fri, 23 Sep 2022 14:56:20 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 15:59:02 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/729966">Extra row in QTableView</a>:</p>
<blockquote>
<p dir="auto">What Python got to do with it?</p>
</blockquote>
<p dir="auto">Absolutely nothing :)  I suddenly thought you had been writing in Python, and were somehow getting away with passing too few parameters, upon looking now I have no idea why!</p>
]]></description><link>https://forum.qt.io/post/729976</link><guid isPermaLink="true">https://forum.qt.io/post/729976</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Fri, 23 Sep 2022 15:59:02 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 14:56:20 GMT]]></title><description><![CDATA[<p dir="auto">For my convenience, the FrameList class had this:</p>
<pre><code>inline FrameList&amp; beginInsertRows(int count) noexcept
{
	auto first{ imageGroups[index].pictures.rowCount() };	// Insert after end
	auto last{ first + count };
	imageGroups[index].pictures.beginInsertRows(QModelIndex(), first, last);
	return (*this);
}
</code></pre>
<p dir="auto">which I now realise had an "off by one" error!</p>
<p dir="auto">I changed the code to read:</p>
<p dir="auto">auto last{ first + count -1};</p>
<p dir="auto">and it now works as I would hope!!</p>
<p dir="auto">I also changed addImage() to read:</p>
<pre><code>void ImageListModel::addImage(ListBitMap image)
{
    Q_ASSERT(std::find(mydata.begin(), mydata.end(), image) == mydata.end());
            
    mydata.emplace_back(std::move(image));
}
</code></pre>
<p dir="auto">as it should never actually attempt to add the same file twice (there are other checks).</p>
<p dir="auto">Thanks for the help in tracking this down.</p>
<p dir="auto">D.</p>
]]></description><link>https://forum.qt.io/post/729967</link><guid isPermaLink="true">https://forum.qt.io/post/729967</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Fri, 23 Sep 2022 14:56:20 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 14:31:47 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/729947">Extra row in QTableView</a>:</p>
<blockquote>
<p dir="auto">What is your<br />
frameList.beginInsertRows(files.size())</p>
</blockquote>
<p dir="auto">it was 1 - I checked in the debugger.</p>
<p dir="auto">What Python got to do with it?</p>
<p dir="auto">David</p>
]]></description><link>https://forum.qt.io/post/729966</link><guid isPermaLink="true">https://forum.qt.io/post/729966</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Fri, 23 Sep 2022 14:31:47 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 14:17:11 GMT]]></title><description><![CDATA[<p dir="auto">The implementation of <code>beginInsertRows()</code> for frameList model sub-class must allow just the number of rows as a single parameter but apparently isn't calling the <a href="https://doc.qt.io/qt-6/qabstractitemmodel.html#beginInsertRows" target="_blank" rel="noopener noreferrer nofollow ugc">base class implementation</a> correctly as <a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a> points out.</p>
]]></description><link>https://forum.qt.io/post/729964</link><guid isPermaLink="true">https://forum.qt.io/post/729964</guid><dc:creator><![CDATA[mchinand]]></dc:creator><pubDate>Fri, 23 Sep 2022 14:17:11 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 13:39:04 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/perdrix">@<bdi>Perdrix</bdi></a><br />
I admit I cannot spot what the issue is. [* Now see <strong>UPDATE</strong> below.]</p>
<p dir="auto">Remove <em>all</em> your code (for reading files, inserting into list/table, images, <code>beginInsertRows()</code>, etc.)!  Just have <code>rowCount()</code> unconditionally <code>return 1;</code>.  What does the table look like now? :)</p>
<p dir="auto">You return <code>mydata.size()</code>.  But <code>mageListModel::addImage()</code> does not append an item to <code>mydata</code> if the <code>image</code> is already "found" in the list.  Is that relevant?</p>
<p dir="auto">You have not said anything about your model, but I <em>assume</em> you are implementing your own <code>QAbstractItemModel</code>.  Strange things happen if the implementation is incorrect.  There is a <a href="https://doc.qt.io/qt-6/qabstractitemmodeltester.html" target="_blank" rel="noopener noreferrer nofollow ugc">QAbstractItemModelTester Class</a> to test implementations, of ten it uncovers something.</p>
<p dir="auto"><strong>UPDATE</strong>  STOP!!<br />
What is your</p>
<pre><code>frameList.beginInsertRows(files.size());
</code></pre>
<p dir="auto">??  How does this get through Python? <a href="https://doc.qt.io/qtforpython/PySide6/QtCore/QAbstractItemModel.html#PySide6.QtCore.PySide6.QtCore.QAbstractItemModel.beginInsertRows" target="_blank" rel="noopener noreferrer nofollow ugc">https://doc.qt.io/qtforpython/PySide6/QtCore/QAbstractItemModel.html#PySide6.QtCore.PySide6.QtCore.QAbstractItemModel.beginInsertRows</a></p>
<blockquote>
<p dir="auto"><code>PySide6.QtCore.QAbstractItemModel.beginInsertRows(parent, first, last)</code></p>
<p dir="auto">PARAMETERS</p>
<p dir="auto">parent – PySide6.QtCore.QModelIndex</p>
<p dir="auto">first – int</p>
<p dir="auto">last – int</p>
</blockquote>
<p dir="auto">So apart from wrong number of parameters, note that <code>last</code> would need to be <code>mydata.size() - 1</code>....  Looks like you are telling it you're inserting 1 more than you are, hence an extra blank row at end? :)</p>
]]></description><link>https://forum.qt.io/post/729947</link><guid isPermaLink="true">https://forum.qt.io/post/729947</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Fri, 23 Sep 2022 13:39:04 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 12:42:53 GMT]]></title><description><![CDATA[<p dir="auto">Here's what the view looks like b4 loading a file:</p>
<p dir="auto"><img src="https://ddgobkiprc33d.cloudfront.net/0345950d-ecc2-4f31-8789-b564eeeb2695.png" alt="d26e1573-964b-4218-9b24-9fefcf6e709c-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">and now after loading one file:</p>
<p dir="auto"><img src="https://ddgobkiprc33d.cloudfront.net/f5dff615-b60c-4a7e-a8bb-7694e556bbff.png" alt="9c40537c-d38b-4259-8c1e-ec66ca2c6c7c-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">Here's the code that did it:</p>
<pre><code>		if (QDialog::Accepted == fileDialog.exec())
		{
			QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
			QStringList files = fileDialog.selectedFiles();

			//
			// Before attempting to add the files prune out those that have already been loaded
			// and issue an error message
			//
			auto it = std::remove_if(files.begin(), files.end(), 
				[&amp;](const QString&amp; s) { return fileAlreadyLoaded(s.toStdU16String()); });
			files.erase(it, files.end());

			//
			// Now add the images to the end of the current group in the frame list remembering
			// that we need to bracket the code  that adds the with beginInsertRows(rowcount) and
			// endInsertRows(), so the table model is informed of the new rows
			//
			frameList.beginInsertRows(files.size());
			for (int i = 0; i &lt; files.size(); i++)
			{
				fs::path file(files.at(i).toStdU16String());		// as UTF-16

				frameList.addFile(file);

				if (file.has_parent_path())
					directory = QString::fromStdU16String(file.parent_path().generic_u16string());
				else
					directory = QString::fromStdU16String(file.root_path().generic_u16string());

				extension = QString::fromStdU16String(file.extension().generic_u16string());
			}
			frameList.endInsertRows();
</code></pre>
<p dir="auto">the addFile mf of FrameList class reads like:</p>
<pre><code>		virtual bool addFile(fs::path file, PICTURETYPE PictureType = PICTURETYPE_LIGHTFRAME, bool bCheck = false, int nItem = -1)
		{
			imageGroups[index].addFile(file, PictureType, bCheck);
			return true;
		}
</code></pre>
<p dir="auto">and the mf that calls looks like:</p>
<pre><code>	void Group::addFile(fs::path file, PICTURETYPE PictureType, bool bCheck, &lsqb;&lsqb;maybe_unused&rsqb;&rsqb; int32_t nItem)
	{
		ZFUNCTRACE_RUNTIME();

		ListBitMap			lb;

		lb.m_groupId = Index;

		if (lb.InitFromFile(file, PictureType))
		{
                      : stuff deleted
		};

		pathToGroup.emplace(file, Index);

		pictures.addImage(lb);
</code></pre>
<p dir="auto">pictures is an instance of a derived class of QAbstractTableModel which stores a std::vector&lt;ListBitmap&gt; as its backing data.</p>
<p dir="auto">the addImage() mf looks like:</p>
<pre><code>    //
    // Add an image (row) to the table, Before calling addImage, Qt requires that 
    // beginInsertRows() be called, and once batch of images is added, then
    // endInsertRows() must be called.
    //
    void ImageListModel::addImage(ListBitMap image)
    {
        if (std::find(mydata.begin(), mydata.end(), image) != mydata.end())
            return;
        mydata.emplace_back(std::move(image));
    }
</code></pre>
<p dir="auto">the rowCount mf() is simply:</p>
<pre><code>        int rowCount(const QModelIndex&amp; parent = QModelIndex()) const override
        {
            // Return number of images we know about
            return static_cast&lt;int&gt;(mydata.size());
        };
</code></pre>
<p dir="auto">I checked using the debugger and rowCount is returning 1 after adding one file as I would expect.</p>
]]></description><link>https://forum.qt.io/post/729941</link><guid isPermaLink="true">https://forum.qt.io/post/729941</guid><dc:creator><![CDATA[Perdrix]]></dc:creator><pubDate>Fri, 23 Sep 2022 12:42:53 GMT</pubDate></item><item><title><![CDATA[Reply to Extra row in QTableView on Fri, 23 Sep 2022 09:53:30 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/perdrix">@<bdi>Perdrix</bdi></a><br />
"Nothing" would make that happen.  And what about when you have 0 rows in the table without inserting anything?  Are you sure your "extra blank row" is not just the empty area at the bottom/right of a <code>QTreeView</code> depending on its size?  Otherwise show screenshot and code.</p>
]]></description><link>https://forum.qt.io/post/729918</link><guid isPermaLink="true">https://forum.qt.io/post/729918</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Fri, 23 Sep 2022 09:53:30 GMT</pubDate></item></channel></rss>