PDA

View Full Version : MessageBox appearnig twice.



ronak.vashi
17th May 2010, 10:58
Hi,

I am new to Qt GUI programming but well aware of C++ concepts. I am developing simple application which takes data from GUI and inserts into Database. Before inserting data into DB few validation are being performed for valid data.

Now to show validation failure I am using QMessageBox class as provided by Qt. Problem is coming when popping up message box with QMessageBox. After clicking OK button it displays the same message box again and again I have to click on OK button to close it.

While posting the Thread I am not having source code available but will be happy to share for better understanding of issue.

If any one has faced similar issue please let me know the solution.

Qt Version : 4.6.0
OS : Windows Vista 64-bit
Compiler : MinGW g++ 4.4.0 as supplied with Qt.
Database : Oracle 11g 64-bit

Thanks,
Ronak

aamer4yu
17th May 2010, 11:28
Put a breakpoint and check where the call to messagebox is coming from...

squidge
17th May 2010, 15:57
Message box runs its own event loop, so the chances are an event is happening in your event loop, you are creating message box and then getting another event and creating another message box, etc, as you can receive new events even if you are displaying message box.

ronak.vashi
17th May 2010, 20:16
Put a breakpoint and check where the call to messagebox is coming from...

Hi,
Tried debugging and found that function validateInput is getting called twice from qobject.cpp and hence MessageBox is appearing twice.

From thorough debugging it is found that in qobject.cpp statement @ line # 4 & line# 8 are returning two different Memory address hence two different Connection.

I am not sure what this Connections objects and why it has two different objects. :confused:

Also, one observation is as follow:


Application is having small login window asking User-name and password. Here also few validations are performed and QMessageBox is used to give appropriate error message,but here Message window is not appearing twice.



Here is a piece of code from validateInput function.

Function: validateInput.


QString expenseHead = ui->expenseHead->text();
int expenseCategory = ui->expenseClassCombo->currentIndex();
int expenseSubCategory = ui->expenseSubClassCombo->currentIndex();
QString amountSpent = ui->expenseAmount->text();
QString expenseDate = ui->expenseDate->text();
QString expenseRemarks = ui->remarks->toPlainText();

// QMessageBox::information(0,"Info",expenseHead + "|" + QString::number(expenseCategory) + "|"
// + QString::number(expenseSubCategory));
if(expenseHead.isEmpty()){
QMessageBox::critical(0,QObject::tr("Validation Error"),"Expense Head is required. It can't be left blank.");
//ui->expenseHead->setFocus();
return false;
}

if(expenseCategory == 0){
QMessageBox::critical(0,QObject::tr("Validation Error"),"Expense Category must be selected.");
ui->expenseClassCombo->setFocus();
return false;
}

if(expenseSubCategory == 0){
QMessageBox::critical(0,QObject::tr("Validation Error"),"Expense SubCategory must be selected.");
ui->expenseSubClassCombo->setFocus();
return false;
}

if(amountSpent.isEmpty()){
QMessageBox::critical(0,QObject::tr("Validation Error"),"Amount Spent is required. It can't be left blank.");
ui->expenseAmount->setFocus();
return false;
}

if(amountSpent.toDouble() == 0.00){
QMessageBox::critical(0,QObject::tr("Wrong Input"),"Amount must be greater than zero.");
ui->expenseAmount->setFocus();
return false;
}
return true;

File : qobject.cpp



...

do {
QObjectPrivate::Connection *c = connectionLists->at(signal_index).first;
if (!c) continue;
// We need to check against last here to ensure that signals added
// during the signal emission are not emitted in this emission.
QObjectPrivate::Connection *last = connectionLists->at(signal_index).last;

do {
if (!c->receiver)
continue;

QObject * const receiver = c->receiver;

// determine if this connection should be sent immediately or
// put into the event queue
if ((c->connectionType == Qt::AutoConnection
&& (currentThreadData != sender->d_func()->threadData
|| receiver->d_func()->threadData != sender->d_func()->threadData))
|| (c->connectionType == Qt::QueuedConnection)) {
queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
continue;
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
continue;
}

const int method = c->method;
QObjectPrivate::Sender currentSender;
currentSender.sender = sender;
currentSender.signal = signal_absolute_index;
currentSender.ref = 1;
QObjectPrivate::Sender *previousSender = 0;
if (currentThreadData == receiver->d_func()->threadData)
previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
locker.unlock();

if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
qt_signal_spy_callback_set.slot_begin_callback(rec eiver,
method,
argv ? argv : empty_argv);
}

#if defined(QT_NO_EXCEPTIONS)
metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
#else
QT_TRY {
metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
} QT_CATCH(...) {
locker.relock();

QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);

--connectionLists->inUse;
Q_ASSERT(connectionLists->inUse >= 0);
if (connectionLists->orphaned && !connectionLists->inUse)
delete connectionLists;
QT_RETHROW;
}
#endif

if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(recei ver, method);

locker.relock();

QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);

if (connectionLists->orphaned)
break;
} while (c != last && (c = c->nextConnectionList) != 0);

if (connectionLists->orphaned)
break;
} while (signal_index >= 0 && (signal_index = -1)); //start over for -1 (all signal)

...

ronak.vashi
26th May 2010, 09:04
Hi all,

Any idea, how to avoid double appearance of messagebox ?:confused:
I have got stuck due to this weird behavior.

Please help..

high_flyer
26th May 2010, 09:56
I take it that validateInput() is a slot.
Can you show which signals did you connect to this slot?

It looks like you have connected several objects to this slot, and any of these signals trigger the slot, and since you are doing a lot of checking on various widgets in the slots it self, it is very well possible that multiple conditions are true, and thus trigger multiple message boxes.

ronak.vashi
26th May 2010, 18:06
I take it that validateInput() is a slot.
Can you show which signals did you connect to this slot?

It looks like you have connected several objects to this slot, and any of these signals trigger the slot, and since you are doing a lot of checking on various widgets in the slots it self, it is very well possible that multiple conditions are true, and thus trigger multiple message boxes.

Hi,
validateInput() is not a slot but called by slot on_addButton_clicked() when "Add Button" is clicked. As shown in below code.

Here are few thing about application, which may help to understand the issue.
1). I have created QMainWindow GUI with various menu and submenus.
2). On clicking Add -> Expense -> Add Single Entry I am creating SingleEntry widget with QMainWindow as parent where in all text boxes, dropdown and button stuff comes into picture.
3). On this singleentry widget while performing validation this issue is occurring.
4). setupSingleEntry function is called when "Add Single Entry" submenu option is clicked.

Let me know if further input is required.


void SingleEntry::setupSingleEntry(){
setupSingleEntrySignalSlots();
populateExpenseCategory();
ui->expenseDate->setDate(QDate::currentDate());
ui->expenseDate->setMaximumDate(QDate::currentDate()); /* Restrict user from selecting Future Dates */
}

void SingleEntry::setupSingleEntrySignalSlots(){
connect(ui->expenseClassCombo,SIGNAL(currentIndexChanged(int)) ,this,SLOT(on_expenseClassCombo_currentIndexChange d()));
connect(ui->adjustmentCheckBox,SIGNAL(clicked()),this,SLOT(on_ adjustmentCheckBox_clicked()));
connect(ui->addButton,SIGNAL(clicked()),this,SLOT(on_addButton _clicked()));
}

void SingleEntry::on_addButton_clicked(){
if(validateInput()){
QMessageBox::information(0,"Success","Validation Successful");
}
else{

}
}

ronak.vashi
30th November 2010, 07:45
Hi All,

Issue got resolved. Actual problem was in setupSingleEntrySignalSlots()function. I am connecting addButton with SLOT on_addButton_clicked() second time. First time it is already done Qt with in-built function connectSlotsByName(). So on_addButton_clicked() was getting called twice and hence appearance of messagebox :cool:.

Thanks for your suggestions.


Hi,
validateInput() is not a slot but called by slot on_addButton_clicked() when "Add Button" is clicked. As shown in below code.

Here are few thing about application, which may help to understand the issue.
1). I have created QMainWindow GUI with various menu and submenus.
2). On clicking Add -> Expense -> Add Single Entry I am creating SingleEntry widget with QMainWindow as parent where in all text boxes, dropdown and button stuff comes into picture.
3). On this singleentry widget while performing validation this issue is occurring.
4). setupSingleEntry function is called when "Add Single Entry" submenu option is clicked.

Let me know if further input is required.


void SingleEntry::setupSingleEntry(){
setupSingleEntrySignalSlots();
populateExpenseCategory();
ui->expenseDate->setDate(QDate::currentDate());
ui->expenseDate->setMaximumDate(QDate::currentDate()); /* Restrict user from selecting Future Dates */
}

void SingleEntry::setupSingleEntrySignalSlots(){
connect(ui->expenseClassCombo,SIGNAL(currentIndexChanged(int)) ,this,SLOT(on_expenseClassCombo_currentIndexChange d()));
connect(ui->adjustmentCheckBox,SIGNAL(clicked()),this,SLOT(on_ adjustmentCheckBox_clicked()));
connect(ui->addButton,SIGNAL(clicked()),this,SLOT(on_addButton _clicked()));
}

void SingleEntry::on_addButton_clicked(){
if(validateInput()){
QMessageBox::information(0,"Success","Validation Successful");
}
else{

}
}