laszlo.gosztola
12th May 2012, 03:21
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>
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*,QListWi dgetItem*)), this, SLOT(currentItemChanged(QListWidgetItem*,QListWidg etItem*)));
}
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);
}
}
That was my first idea, but of course it asks again the question, so I tried to temporally disable signals
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);
}
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.
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);
}
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!
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>
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*,QListWi dgetItem*)), this, SLOT(currentItemChanged(QListWidgetItem*,QListWidg etItem*)));
}
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);
}
}
That was my first idea, but of course it asks again the question, so I tried to temporally disable signals
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);
}
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.
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);
}
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!