PDA

View Full Version : Problem in updating listwidget of friend class



dipeshtech
24th March 2011, 09:19
I am unable to update (addItem) to the private data member (i.e a listwidget) of friend class (here Spam_MessagesWidget). :crying:

I am trying to implement a feature in my application by which the selected message can be moved from Inbox Tab to Other Tab i.e removing from one listwidget and adding to other list widget.

To help me, just check the recentmessageswidget.cpp file and reportAsSpam() method in it.

The code is running and i am able to remove the selected item but unable to add it other tab listwidget. (Tested on Nokia QT SDK V1.0)




QListWidgetItem* RecentMessagesWidget::removeitemI()
{
int cr = m_messageListWidget->currentRow();
QListWidgetItem *temp = new QListWidgetItem(m_messageListWidget);
temp = m_messageListWidget->takeItem(cr);
m_messageListWidget->update();

return(temp);
}


//This function is called from a slot rspam() , in tabmain.cpp
void RecentMessagesWidget :: reportAsSpam()
{
QListWidgetItem *temp = removeitemI();

// trying to add the removed item from "RecentMessagesWidget Class" Listwidget to "Spam_MessagesWidget friend class Listwidget"

spm = new Spam_MessagesWidget(this, SpamMessagesCount);
spm->additemS(temp);

}





Your help will be appreciated and acknowledged.

stampede
24th March 2011, 09:39
I think you are doing something weird here:

QListWidgetItem *temp = new QListWidgetItem(m_messageListWidget);
temp = m_messageListWidget->takeItem(cr);
You create new item and then immediately assign different value for the temp pointer, why ? takeItem returns a pointer to QListWidgetItem, there is no need to "create" anything in "remove" method:

QListWidgetItem* RecentMessagesWidget::removeitemI()
{
int cr = m_messageListWidget->currentRow();
QListWidgetItem *temp = m_messageListWidget->takeItem(cr);
m_messageListWidget->update();
return(temp);
}
Another thing is the reportAsSpam method - you create new Spam_MessagesWidget on every new spam message reported, I think it's not what you meant. Keep the Spam_MessagesWidget as private member of RecentMessagesWidget class, and add new spam reports to that widget instead of creating new one each time.

dipeshtech
24th March 2011, 10:02
Actually "spm" is already a private member of RecentMessagesWidget class. (You can check out in attached code). I also tried after removing the line:



spm = new Spam_MessagesWidget(this, SpamMessagesCount);


and with only these lines in reportAsSpam() [I also applied the correction in removeitemI() as suggested.]


QListWidgetItem *temp = removeitemI();
spm->additemS(temp);


But , now the application crashes as soon as i click on action "Report as Spam", previously it was removing the selected item though not adding in the other tab listwidget.

stampede
24th March 2011, 10:08
I also tried after removing the line
Ok, but do you initialize the spm pointer in constructor (or somewhere else) ? If not, then it's obvious that it will crash.

dipeshtech
24th March 2011, 10:27
I am not sure exactly how to initialize it, but i tried the following way, but still it removes but doesn't add it to other list.

I initialized it in RecentMessagesWidget class setupUi() method:


spm = new Spam_MessagesWidget(this, SpamMessagesCount); // [added this line]

I have tried with simple strings also but faced the same problem. I am really struggling with the problem, Please help!!:crying:

stampede
24th March 2011, 11:14
setupUi() is automatically generated, don't change it because next time you run uic on the .ui file your changes will be overwritten. Initialize the private member in class constructor.

dipeshtech
24th March 2011, 11:29
No , this time also the same thing continues. The selected item is removed but not added to the other list.

As suggested, i changed here:



RecentMessagesWidget::RecentMessagesWidget(QWidget * parent, unsigned int maxRecent)
:
QWidget(parent),
m_messageListWidget(0),
m_statusLabel(0),
m_layout(0),
m_maxRecent(maxRecent),
m_service(new QMessageService(this)),
m_state(Unloaded)
{
setupUi();

spm = new Spam_MessagesWidget(this, SpamMessagesCount); // I added here [initialization]

connect(m_service,SIGNAL(messagesFound(const QMessageIdList&)),this,SLOT(messagesFound(const QMessageIdList&)));
connect(m_service,SIGNAL(stateChanged(QMessageServ ice::State)),this,SLOT(stateChanged(QMessageServic e::State)));

//register for message update notifications

connect(&m_manager, SIGNAL(messageUpdated(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)),
this, SLOT(messageUpdated(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)));
connect(&m_manager, SIGNAL(messageRemoved(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)),
this, SLOT(messageRemoved(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)));

m_storeFilterId = m_manager.registerNotificationFilter(QMessageFilte r::byStandardFolder(QMessage::InboxFolder));
}

stampede
24th March 2011, 11:32
maybe show us Spam_MessagesWidget::additemS code.

dipeshtech
24th March 2011, 11:37
Here it goes:



void Spam_MessagesWidget :: additemS(QListWidgetItem* temp)
{

m_messageListWidget->insertItem(0,temp);

m_messageListWidget->update();

}

stampede
24th March 2011, 13:46
You never call setLayout(m_layout) after creating layout objects, try to call this->setLayout(m_layout); after preparing ui elements.

dipeshtech
24th March 2011, 14:21
Still No Effect...!! I guess the function additemS() is not getting called from the RecentMessagesWidget class. I don't understand why the friend class function is not being called from here.

I am looking for a simple working example using friend classes or friend function that can update on the private members of both the classes. I started with this (https://www.forum.nokia.com/info/sw.nokia.com/id/e775b575-89be-44d5-ab48-738be0fb2100/Qt_QTabs_Example_v1_1_en.zip.html) simple example.

dipeshtech
25th March 2011, 00:43
I guess the sole problem is here:

I am posing the problem in a different form:



//File recentmessageswidget.h [A simple class Containing 2 listwidgets]

class RecentMessagesWidget : public QWidget
{
Q_OBJECT
public:
explicit RecentMessagesWidget(QWidget *parent = 0);
~RecentMessagesWidget();

public:
QListWidget* I_messageListWidget;
QListWidget* S_messageListWidget;

public slots:

void processResults();
void reportAsSpam();

};

//recentmessageswidget.cpp

#include "recentmessageswidget.h"

RecentMessagesWidget::RecentMessagesWidget(QWidget *parent) :
QWidget(parent)
{
I_messageListWidget = new QListWidget(this);
S_messageListWidget = new QListWidget(this);
processResults();
}
RecentMessagesWidget::~RecentMessagesWidget()
{

}

void RecentMessagesWidget::processResults()
{
//I_messageListWidget = new QListWidget(this);
I_messageListWidget->addItem(new QListWidgetItem("I1"));
I_messageListWidget->addItem(new QListWidgetItem("I2"));
I_messageListWidget->addItem(new QListWidgetItem("I3"));

//S_messageListWidget = new QListWidget(this);
S_messageListWidget->addItem(new QListWidgetItem("S1"));
S_messageListWidget->addItem(new QListWidgetItem("S2"));
S_messageListWidget->addItem(new QListWidgetItem("S3"));

S_messageListWidget->insertItem(4,QString("In fn PR")); // added in the list

}
void RecentMessagesWidget :: reportAsSpam()
{
int cr = I_messageListWidget->currentRow();
QListWidgetItem *temp = I_messageListWidget->takeItem(cr);
//I_messageListWidget->update();
//S_messageListWidget = new QListWidget(this);
S_messageListWidget->insertItem(0,temp); // PROBLEM is here...
S_messageListWidget->insertItem(5,QString("spm tab in fn")); // not added in the list

S_messageListWidget->update();
I_messageListWidget->update();

}


//In file tabmain.h

class TabMain : public QMainWindow
{
Q_OBJECT
public:
TabMain(QWidget *parent = 0);
~TabMain();
private:
void buildTabMenuBar(int index);

signals:

public slots:
void activeTabChanged(int index);
private:
QTabWidget* tabWidget;

};

class InBoxTab : public QWidget
{
Q_OBJECT

public:
InBoxTab(QWidget *parent = 0);
~InBoxTab();
void setupUi();
public slots:
void hello();
void rspam();
private:
RecentMessagesWidget* m_recentMessagesWidget;
};

class SpamBoxTab: public QWidget
{
Q_OBJECT

public:
SpamBoxTab(QWidget *parent = 0);
~SpamBoxTab();
void setupUi();
public slots:
void hello();
private:

RecentMessagesWidget* sm_recentMessagesWidget;


};



TabMain::TabMain(QWidget *parent) :
QMainWindow(parent)
{
setContextMenuPolicy(Qt::NoContextMenu);
this->setWindowTitle("SMSAssassin Alpha");

tabWidget = new QTabWidget(this);
tabWidget->setContextMenuPolicy(Qt::NoContextMenu);

QObject::connect(tabWidget, SIGNAL(currentChanged(int)),this, SLOT(activeTabChanged(int)));

InBoxTab* widget1 = new InBoxTab();
tabWidget->addTab(widget1, " INBOX ");
SpamBoxTab* widget2 = new SpamBoxTab();
tabWidget->addTab(widget2, " SPAMBOX ");
//adda();
setCentralWidget(tabWidget);



#ifdef Q_OS_SYMBIAN
QWidgetList widgets = QApplication::allWidgets();
QWidget* w = 0;
foreach(w,widgets)
{
w->setContextMenuPolicy(Qt::NoContextMenu);
}
#endif

}
TabMain::~TabMain()
{

}
void TabMain::activeTabChanged(int index)
{
buildTabMenuBar(index);
}
void TabMain::buildTabMenuBar(int index)
{
QMenuBar* menubar = menuBar();
menubar->clear();

switch(index)
{
case 0:
{
menubar -> addAction("Inbox user Menu", tabWidget->widget(index),SLOT( hello() ) );
menubar -> addAction("Report as Spam", tabWidget->widget(index), SLOT( rspam() ) );
break;
}
case 1:
{
menubar -> addAction("SpamBox user Menu", tabWidget->widget(index), SLOT(hello()) );
break;

}
default:
{
break;
}
}
}

InBoxTab::InBoxTab(QWidget *parent) :
QWidget(parent),
m_recentMessagesWidget(0)
{
setupUi();
}

InBoxTab:: ~InBoxTab()
{

}

void InBoxTab::setupUi()
{
QVBoxLayout* vbl = new QVBoxLayout(this);
m_recentMessagesWidget = new RecentMessagesWidget(this);
vbl->addWidget(m_recentMessagesWidget->I_messageListWidget);
this->setLayout(vbl);
}
void InBoxTab :: rspam()
{
m_recentMessagesWidget->reportAsSpam();
}

void InBoxTab::hello()
{
QString message = QString("Hello from %1").arg(metaObject()->className());
QMessageBox* messageBox = new QMessageBox(QMessageBox::Information, "QTabsExample", message,
QMessageBox::Ok, this);
messageBox->exec();
delete messageBox;
messageBox = 0;
}


SpamBoxTab::SpamBoxTab(QWidget *parent) :
QWidget(parent)
{
setupUi();

}
void SpamBoxTab::setupUi()
{
QVBoxLayout* vbl = new QVBoxLayout(this);
sm_recentMessagesWidget = new RecentMessagesWidget(this);
vbl->addWidget(sm_recentMessagesWidget->S_messageListWidget);
this->setLayout(vbl);
}



SpamBoxTab::~SpamBoxTab()
{

}
void SpamBoxTab::hello()
{
QString message = QString("Hello from %1").arg(metaObject()->className());
QMessageBox* messageBox = new QMessageBox(QMessageBox::Information, "QTabs", message,
QMessageBox::Ok, this);

messageBox->exec();
delete messageBox;
messageBox = 0;
}




The problem is same, item is removed from one tab but not gets added to other tab.

Rhayader
25th March 2011, 01:37
Attached is a very minimalist example of two listWidgets that shows that the code you think is problematic, is actually working. I don't know where and why there is an error in your program but you have to look for it somewhere else.

dipeshtech
25th March 2011, 08:56
In my case the problem is that on selection the item is removed from one Listwidget of one TAB but doesn't get added in other TAB.

May be my problem is due to the TAB thing. Attached is my project, You can check it, It doesn't work but doesn't throws any error too.

Rhayader
25th March 2011, 10:42
Besides your title and I don't see anywhere in your code to be declared a friend (as in C++ friend) class.
Your main widget is a tabBar that creates InBoxTar and SpamBoxTab both of type RecentMessageWidget. Now, in the RecentMessageWidget's constructor there are created two list widget (I_.. and S_...)
So what you have is
Tabbar----InBoxTab------RecentMessageWidget's ---I_messageListWidget (1)+S_messageListWidget (2)
Tabbar----SpamBoxTab---RecentMessageWidget's---I_messageListWidget (3)+S_messageListWidget (4)
(2) and (3) are invisible because they are not added in the layout, but does not mean they don't exist. What you are doing is a connection between (1) and (2), though what you want is a connection between (1) and (4) which simply exist in different objects.

My suggestion: Create only one listWidget. Maybe it's better RecentMessage to be a subclass of QListWidget. Add a method that returns the currentItem, and a method that reports this QListWidgetItem.


QListWidgetItem* RecentMessagesWidget::getCurrentItem();
void RecentMessagesWidget::reportAsSpam(QListWidgetItem *temp);

So in your tabBar class you can call something like


spamBox->reportAsSpam(inBox->getCurrentItem());

dipeshtech
25th March 2011, 10:56
Friend is in my original code which is in my first thread. Initially, i thought my problem is due to friend class.

And, Why i want to keep 2 listwidgets is that i wish to maintain 2 different lists containing different items in 2 tabs.

Rhayader
25th March 2011, 11:13
And, Why i want to keep 2 listwidgets is that i wish to maintain 2 different lists containing different items in 2 tabs.
Since this is by design then it's ok, but you have to let the two objects(1 and 4 in my previous post) to be known to eachother.

dipeshtech
25th March 2011, 12:04
If you have browsed my code, can you please help me in getting it work, the way i want it. If you can point out the changes to made (in my code) for this. I am just a month old to it.

Rhayader
25th March 2011, 15:08
See the changes made for the QListWidgetItem to be passed from Inbox object to SpamBox object.
Please note that I don't "agree" with your implementation. You are making things too complicated without reason (but I will not redesign your classes :p)

NOTE: I had to comment out many headers that were not in my system to compile but they are irrelevant to your problem

dipeshtech
25th March 2011, 16:18
Rhayader Thanks A TON...!! for your help and time. I learned few very very important things.

Forgive my ignorance on the problem. But, i am still thinking that there were 2 classes with 2 listwidget as members, i was thinking to have a friend function sort of thing which can be called as slot.

Actually, i also don't like my implementation but currently i am experimenting and i am not aware of many things. And sorry for those headers, that belong to my original project, i forgot to remove it for discussion here.

But thanks a Ton !
--
Dipesh