如何在 QListWidget 中每次编辑一行时发出信号?

发布于 2025-01-08 03:36:35 字数 937 浏览 3 评论 0原文

class genericTaskList : public QListWidget
{
    Q_OBJECT  
    public:
        QListWidgetItem *defaultText;

        genericTaskList (QWidget *parentWidget)
        {
            setParent      (parentWidget);
            setFixedSize (445, 445);

            defaultText = new QListWidgetItem ("Double click here to compose the task");
            defaultText->setFlags (defaultText->flags () | Qt :: ItemIsEditable);

            insertItem     (0, defaultText);

            QObject :: connect (this, SIGNAL (currentRowChanged (int)), this, SLOT (addDefaultText (int)));
        }

    public slots:
        void addDefaultText (int rr)
        {
            std::cout << "\ndsklfjsdklfhsdklhfkjsdf\n";

            insertItem (++rr, defaultText);
        }
};

该代码应该在每次编辑该行时发出一个信号。

在构造函数中调用“insertItem”后,会发出信号。
但是,就是这样。此后它永远不会被发布 - 无论我编辑该行多少次。

我缺少什么?

class genericTaskList : public QListWidget
{
    Q_OBJECT  
    public:
        QListWidgetItem *defaultText;

        genericTaskList (QWidget *parentWidget)
        {
            setParent      (parentWidget);
            setFixedSize (445, 445);

            defaultText = new QListWidgetItem ("Double click here to compose the task");
            defaultText->setFlags (defaultText->flags () | Qt :: ItemIsEditable);

            insertItem     (0, defaultText);

            QObject :: connect (this, SIGNAL (currentRowChanged (int)), this, SLOT (addDefaultText (int)));
        }

    public slots:
        void addDefaultText (int rr)
        {
            std::cout << "\ndsklfjsdklfhsdklhfkjsdf\n";

            insertItem (++rr, defaultText);
        }
};

This code is supposed to issue a signal each time the row gets edited.

After I call "insertItem" in the constructor, the signal is issued.
But, that's it. It never gets issued after that - no matter how many times I edit the row.

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七秒鱼° 2025-01-15 03:36:35

起初,看起来 QListWidget::itemChanged 是可行的方法,但很快您就会遇到问题:为所有内容发送信号 - 插入、删除、更改颜色、复选框等!因此,您最终会尝试通过拦截各种信号来添加标志并过滤各处,以查明编辑是否是实际事件。它变得非常混乱。

还有 QAbstractItemModel::dataChanged ,这似乎是一个很好的解决方案。它甚至有一个参数“const QVector& lstRoles”,因此您可以扫描 Qt::EditRole 并查看它是否真的被编辑过。唉,有一个问题 - 就像 QListWidget::itemChanged 一样,它会被调用,但不幸的是,对于 QListWidget,角色参数在调用时始终为空(我尝试过)。这个想法就这么多了...

幸运的是,仍然有希望...这个解决方案成功了! :

http://falsinsoft.blogspot.com/2013/ 11/qlistwidget-and-item-edit-event.html

他使用 QAbstractItemDelegate::closeEditor,但我更喜欢使用QAbstractItemDelegate::commitData。

因此,像这样进行连接...

connect(ui.pLstItems->itemDelegate(), &QAbstractItemDelegate::commitData, this, &MyWidget::OnLstItemsCommitData);

然后像这样实现插槽...

void MyWidget::OnLstItemsCommitData(QWidget* pLineEdit)
{
        QString strNewText = reinterpret_cast<QLineEdit*>(pLineEdit)->text();
    int nRow = ui.pLstItems->currentRow();
        // do whatever you need here....
}

现在您有了一个仅当列表项的文本被编辑时才会被调用的插槽!

At first it seems like QListWidget::itemChanged is the way to go, but soon you run into a problem: the signal is sent for everything - inserts, removes, changing colors, checking boxes, etc! So then you end up trying to put in flags and filter everywhere by intercepting various signals to find out if editing was the actual event. It gets very messy.

There is also QAbstractItemModel::dataChanged , which would seem like a good solution. It even has a parameter "const QVector& lstRoles" so you could scan for Qt::EditRole and see if it was really edited. Alas, there's a catch - it gets called for everything just like QListWidget::itemChanged and unfortunately, for QListWidget anyway, the roles parameter is always empty when it's called (I tried it). So much for that idea...

Fortunately, there's still hope... This solution does the trick! :

http://falsinsoft.blogspot.com/2013/11/qlistwidget-and-item-edit-event.html

He uses QAbstractItemDelegate::closeEditor, but I prefer using QAbstractItemDelegate::commitData.

So make a connect like so...

connect(ui.pLstItems->itemDelegate(), &QAbstractItemDelegate::commitData, this, &MyWidget::OnLstItemsCommitData);

Then implement the slot like this...

void MyWidget::OnLstItemsCommitData(QWidget* pLineEdit)
{
        QString strNewText = reinterpret_cast<QLineEdit*>(pLineEdit)->text();
    int nRow = ui.pLstItems->currentRow();
        // do whatever you need here....
}

Now you have a slot that gets called only when the list item's text has been edited!

望笑 2025-01-15 03:36:35

currentRowChanged 表示行选择已更改,而不是行的内容。也许您想使用 currentTextChangeditemChanged 来代替。

QT 文档中重复使用“当前”和“已更改”一词非常令人困惑。

currentRowChanged indicates the row selection has changed, not the content of the row. Perhaps you want to use currentTextChanged or itemChanged instead.

The reuse of the word current and changed in the QT docs is quite confusing.

病毒体 2025-01-15 03:36:35

警告:一个 QListWidgetItem 只能添加到一个 QListWidget 一次。多次将相同的 QListWidgetItem 添加到 QListWidget 将导致未定义的行为。

因此,即使它会发出信号,我认为你应该最好添加新创建的项目。
您希望何时插入新行? -
一旦双击项目或完成编辑 - 它们就会有所不同。

Warning: A QListWidgetItem can only be added to a QListWidget once. Adding the same QListWidgetItem multiple times to a QListWidget will result in undefined behavior.

So even if it will emit the signal I think you should better to add newly created Item.
And when do you want the new row to be inserted ? -
as soon as item is double clicked or finishing edit - they differ.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文