<?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[Restore TextInput after invalid input]]></title><description><![CDATA[<p dir="auto">I have a TextInput whose text property is bound to a model role. On successful input, the model role is updated, while invalid inputs are rejected and the model is not updated. In the latter case, I tried setting the text property to its default "--", but of course this broke the binding with the model. I've gotten around this by using a Binding {} to restore the binding after text is assigned to manually, but these seems rather convoluted.</p>
<p dir="auto">Is there a cleaner way to programmatically reset the TextInput so that it reverts to whatever is in the model?</p>
]]></description><link>https://forum.qt.io/topic/164040/restore-textinput-after-invalid-input</link><generator>RSS for Node</generator><lastBuildDate>Thu, 10 Sep 2026 14:15:09 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/164040.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 04 Jan 2026 14:22:19 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Restore TextInput after invalid input on Thu, 08 Jan 2026 11:34:07 GMT]]></title><description><![CDATA[<p dir="auto">It does make you wonder what setData()'s return value is used for.</p>
]]></description><link>https://forum.qt.io/post/835290</link><guid isPermaLink="true">https://forum.qt.io/post/835290</guid><dc:creator><![CDATA[ECEC]]></dc:creator><pubDate>Thu, 08 Jan 2026 11:34:07 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Wed, 07 Jan 2026 19:35:49 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/ecec">@<bdi>ECEC</bdi></a> said in <a href="/post/835261">Restore TextInput after invalid input</a>:</p>
<blockquote>
<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/grecko">@<bdi>GrecKo</bdi></a> Indeed, which is why I've had to resort to always emitting dataChanged and never returning false.</p>
</blockquote>
<p dir="auto">I was surprised, but it does return the TextInput to the model's value. Full code:</p>
<p dir="auto">Main.qml</p>
<pre><code class="language-js">import QtQuick

Window {
    visible: true
    required property QtObject m

    ListView {
        anchors.fill: parent
        model: m
        delegate: TextInput {
            text: display
            onEditingFinished: display = text
        }
    }
}
</code></pre>
<p dir="auto">main.cpp:</p>
<pre><code class="language-C++">#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;
#include &lt;QStandardItemModel&gt;

class Model : public QStandardItemModel {
public:
    bool setData(const QModelIndex &amp;index, const QVariant &amp;value, int role) override {
        auto updated = (role == Qt::ItemDataRole::DisplayRole) ? value.toString().toUpper() : value;
        if (role == Qt::ItemDataRole::DisplayRole &amp;&amp; updated.toString().contains('!')) {
            return false;
        }

        return QStandardItemModel::setData(index, updated, role);
    }
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    Model model;
    model.appendRow(new QStandardItem("something"));

    QQmlApplicationEngine engine;
    engine.setInitialProperties({ {"m", QVariant::fromValue(&amp;model)} });
    engine.loadFromModule("untitled1", "Main");

    return app.exec();
}
</code></pre>
]]></description><link>https://forum.qt.io/post/835266</link><guid isPermaLink="true">https://forum.qt.io/post/835266</guid><dc:creator><![CDATA[jeremy_k]]></dc:creator><pubDate>Wed, 07 Jan 2026 19:35:49 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Wed, 07 Jan 2026 18:51:30 GMT]]></title><description><![CDATA[<p dir="auto">note that you could still return false.</p>
]]></description><link>https://forum.qt.io/post/835264</link><guid isPermaLink="true">https://forum.qt.io/post/835264</guid><dc:creator><![CDATA[GrecKo]]></dc:creator><pubDate>Wed, 07 Jan 2026 18:51:30 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Wed, 07 Jan 2026 14:01:08 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/grecko">@<bdi>GrecKo</bdi></a> Indeed, which is why I've had to resort to always emitting dataChanged and never returning false.</p>
]]></description><link>https://forum.qt.io/post/835261</link><guid isPermaLink="true">https://forum.qt.io/post/835261</guid><dc:creator><![CDATA[ECEC]]></dc:creator><pubDate>Wed, 07 Jan 2026 14:01:08 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Wed, 07 Jan 2026 12:27:14 GMT]]></title><description><![CDATA[<p dir="auto">uh that doesn't modify back the <code>text</code> of the TextInput when the setData is refused unless I'm mistaken.</p>
]]></description><link>https://forum.qt.io/post/835260</link><guid isPermaLink="true">https://forum.qt.io/post/835260</guid><dc:creator><![CDATA[GrecKo]]></dc:creator><pubDate>Wed, 07 Jan 2026 12:27:14 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Tue, 06 Jan 2026 23:29:43 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/grecko">@<bdi>GrecKo</bdi></a> said in <a href="/post/835242">Restore TextInput after invalid input</a>:</p>
<blockquote>
<blockquote>
<p dir="auto"><code>onEditingFinished: m.setData(m.index(index, 0), text)</code></p>
</blockquote>
<p dir="auto">No need to call <code>setData</code> either in 6.9, you can do it with <code>onEditingFinished: model.display = text</code>.</p>
</blockquote>
<p dir="auto">Indeed. Simplifying further:</p>
<pre><code>ListView {
    anchors.fill: parent
    model: m
    delegate: TextInput {
        text: display
        onEditingFinished: display = text
    }
}
</code></pre>
<pre><code class="language-C++">bool setData(const QModelIndex &amp;index, const QVariant &amp;value, int role) override {
    auto updated = (role == Qt::ItemDataRole::DisplayRole) ? value.toString().toUpper() : value;
    if (role == Qt::ItemDataRole::DisplayRole &amp;&amp; updated.toString().contains('!')) {
        return false;
    }
   return QStandardItemModel::setData(index, updated, role);
}
</code></pre>
]]></description><link>https://forum.qt.io/post/835243</link><guid isPermaLink="true">https://forum.qt.io/post/835243</guid><dc:creator><![CDATA[jeremy_k]]></dc:creator><pubDate>Tue, 06 Jan 2026 23:29:43 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Tue, 06 Jan 2026 22:57:43 GMT]]></title><description><![CDATA[<blockquote>
<p dir="auto"><code>onEditingFinished: m.setData(m.index(index, 0), text)</code></p>
</blockquote>
<p dir="auto">No need to call <code>setData</code> either in 6.9, you can do it with <code>onEditingFinished: model.display = text</code>.</p>
]]></description><link>https://forum.qt.io/post/835242</link><guid isPermaLink="true">https://forum.qt.io/post/835242</guid><dc:creator><![CDATA[GrecKo]]></dc:creator><pubDate>Tue, 06 Jan 2026 22:57:43 GMT</pubDate></item><item><title><![CDATA[Reply to Restore TextInput after invalid input on Tue, 06 Jan 2026 11:59:45 GMT]]></title><description><![CDATA[<p dir="auto">For Qt 6.10 (and later presumably): <a href="https://doc.qt.io/qt-6/qtquick-modelviewsdata-modelview.html#changing-model-data" target="_blank" rel="noopener noreferrer nofollow ugc">Changing Model Data</a></p>
<p dir="auto">For earlier versions, the delegate can call the model's <code>setData()</code>, which can emit <code>dataChanged()</code> even if the change attempt is rejected. This works for me with Qt 6.9:<br />
QML:</p>
<pre><code>ListView {
    model: m
    delegate: TextInput {
        text: display
        onEditingFinished: m.setData(m.index(index, 0), text)
    }
}
</code></pre>
<p dir="auto">C++</p>
<pre><code>bool setData(const QModelIndex &amp;index, const QVariant &amp;value, int role) override
{
    auto updated = (role == Qt::ItemDataRole::EditRole) ?
                   value.toString().toUpper() : value;
    if (role == Qt::ItemDataRole::EditRole &amp;&amp; updated.toString().contains('!')) {
        emit dataChanged(index, index, { Qt::ItemDataRole::DisplayRole });
        return false;
    }
    return QStandardItemModel::setData(index, updated, role);
}
</code></pre>
<p dir="auto">Another option is the Qt Widgets model-view pattern, with a separate editor that is displayed when the delegate instance is activated. On completion of editing, the editor calls <code>setData()</code>. The delegate itself remains bound to model data, and is unaware of intermediate or invalid edits. Exchange more code in the delegate for less code in the model.</p>
]]></description><link>https://forum.qt.io/post/835226</link><guid isPermaLink="true">https://forum.qt.io/post/835226</guid><dc:creator><![CDATA[jeremy_k]]></dc:creator><pubDate>Tue, 06 Jan 2026 11:59:45 GMT</pubDate></item></channel></rss>