Hi all,
I found an interesting problem. I use a QListWidget for selection between items. I would like to ask the user if he is sure to change the current item. My plan is to use the currentItemChanged signal of the QListWidget, because it has the previous item pointer.
Sample code:
#include "mainwidget.h"
#include <QListWidget>
#include <QGridLayout>
#include <QMessageBox>
#include <QTimer>
{
mainLayout->addWidget(list);
setLayout(mainLayout);
list->addItem("Item1");
list->addItem("Item2");
list->addItem("Item3");
list->addItem("Item4");
}
MainWidget::~MainWidget()
{
delete list;
}
{
qDebug("CurrentItemChanged - Index: %d", list->row(current));
if ( list->row(current) == currentRow )
{
return;
}
{
//TODO: change back to the previous item
list->setCurrentItem(previous);
}
}
#include "mainwidget.h"
#include <QListWidget>
#include <QGridLayout>
#include <QMessageBox>
#include <QTimer>
MainWidget::MainWidget(QWidget *parent) : QWidget(parent)
{
list = new QListWidget(this);
QGridLayout* mainLayout = new QGridLayout();
mainLayout->addWidget(list);
setLayout(mainLayout);
list->addItem("Item1");
list->addItem("Item2");
list->addItem("Item3");
list->addItem("Item4");
connect(list, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(currentItemChanged(QListWidgetItem*,QListWidgetItem*)));
}
MainWidget::~MainWidget()
{
delete list;
}
void MainWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
qDebug("CurrentItemChanged - Index: %d", list->row(current));
if ( list->row(current) == currentRow )
{
return;
}
if ( QMessageBox::No == QMessageBox::question(this, "Question", "Really want to change?", QMessageBox::Yes | QMessageBox::No) )
{
//TODO: change back to the previous item
list->setCurrentItem(previous);
}
}
To copy to clipboard, switch view to plain text mode
That was my first idea, but of course it asks again the question, so I tried to temporally disable signals
{
//TODO: change back to the previous item
list->blockSignals(true);
list->setCurrentItem(previous);
list->blockSignals(false);
}
if ( QMessageBox::No == QMessageBox::question(this, "Question", "Really want to change?", QMessageBox::Yes | QMessageBox::No) )
{
//TODO: change back to the previous item
list->blockSignals(true);
list->setCurrentItem(previous);
list->blockSignals(false);
}
To copy to clipboard, switch view to plain text mode
The problem with this is that the current item changes back to the previous item, but the selection not and I don't really understand this behaviour.
For a workaround, I have this solution, but I think it's not very elegant.
{
qDebug("CurrentItemChanged - Index: %d", list->row(current));
if ( list->row(current) == currentRow )
{
return;
}
{
//TODO: change back to the previous item
QTimer::singleShot(0,
this,
SLOT(goBack
()));
}else
{
currentRow = list->row(current);
}
}
void MainWidget::goBack()
{
qDebug("GoBack: %d", currentRow);
list->setCurrentRow(currentRow);
}
void MainWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
qDebug("CurrentItemChanged - Index: %d", list->row(current));
if ( list->row(current) == currentRow )
{
return;
}
if ( QMessageBox::No == QMessageBox::question(this, "Question", "Really want to change?", QMessageBox::Yes | QMessageBox::No) )
{
//TODO: change back to the previous item
QTimer::singleShot(0, this, SLOT(goBack()));
}else
{
currentRow = list->row(current);
}
}
void MainWidget::goBack()
{
qDebug("GoBack: %d", currentRow);
list->setCurrentRow(currentRow);
}
To copy to clipboard, switch view to plain text mode
Do You have any explanation why this workaround works, and why the selection doesn't go back if I call it from the slot directly? Is it normal? Do You have any idea for a more elegant solution?
Thanks!
Bookmarks