PDA

View Full Version : Question with QTreeWidgetItem



denumbaone
1st March 2011, 21:30
I have a TreeView class with QTreeWidgetItem's set as check boxes with the following code:


QTreeWidgetItem *cities = new QTreeWidgetItem(treeWidget);
cities->setText(0, tr("Places"));
cities->setCheckState(0, Qt::Checked);

I try to send a signal with the following code:


connect(cities, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, setChecked);

When I compile the code, the following errors come up:


treeview.cpp:56: error: no matching function for call to ‘TreeView::connect(QTreeWidgetItem*&, const char*, TreeView* const, <unresolved overloaded function type>)’

qobject.h:209: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)

qobject.h:314: bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const


I'm not sure but I believe the reason for this is that there are no signals for QTreeWidgetItem. Please confirm if this is the reason, or if it's not, to show me a possible signal for it that will make it work. Thank you in advance.

mcosta
1st March 2011, 21:37
The correct syntax is


connect(cities, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(setChecked());

denumbaone
1st March 2011, 21:52
Oh sorry about that, I have corrected it:


connect(cities, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(setChecked()));

But still recieved the same errors. Any ideas?

mcosta
1st March 2011, 22:08
Have you declared setChecked slot in you TreeView class?

denumbaone
1st March 2011, 22:26
Yes I have. Here is all of the code that I have pertaining to it:

in treeview.h


public slots:
virtual void setChecked();

in treeview.cpp


connect(cities, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(setChecked()));

void TreeView::setChecked()
{
if(Qt::Checked)
{
std::cout << "Checked\n" << std::endl;
//citiesChild->setCheckState(0, Qt::Checked);
}
else
{
std::cout << "Unchecked\n" << std::endl;
}
}

Added after 5 minutes:

Ok, I see that I accidentally made it a "public" slot instead of a "private" slot. But now I am recieving the error


:: error: collect2: ld returned 1 exit status

The code works without all of the code that I have displayed above, so the problem is within it.

Ok, I corrected that problem, but am now recieving the same errors as before:


treeview.cpp:56: error: no matching function for call to ‘TreeView::connect(QTreeWidgetItem*&, const char*, TreeView* const, const char*)’

/opt/qtsdk-2010.04/qt/include/QtCore/qobject.h:209: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)

/opt/qtsdk-2010.04/qt/include/QtCore/qobject.h:314: bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const

any ideas?

mcosta
1st March 2011, 22:32
The itemClicked signal is emitted from QTreeView!!
The correct use is


connect(treeView, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(setChecked()));

denumbaone
1st March 2011, 22:48
What i'm trying to do with this program is when the "cities" is toggled, it sends a signal. What signal can I use to make this possible?

mcosta
1st March 2011, 23:04
QTreeWidgetItem doesn't emit signals itself.

You can catch signal emitted from QTreeWidget and write slot like this

void TreeView::setChecked(QTreeWidgetItem *item)
{
if (item == this->cities) {
if (Qt::Checked == item->checkState(0))
qDebug ("Checked");
else
qDebug ("Unchecked");
}
}

denumbaone
2nd March 2011, 04:08
I still can't figure out how to do something like that; I've never had to do anything like that to manipulate a signal. Can you show me a way that you can catch a signal emitted from QTreeWidget with this code:


QTreeWidgetItem *cities = new QTreeWidgetItem(treeWidget);
cities->setText(0, tr("Places"));
cities->setCheckState(0, Qt::Checked);

Whenever the checkbox for cities is toggled, I want to send a signal. Thank you very much for your help.

Berryblue031
2nd March 2011, 13:48
After you create your QTreeWidgetItem you need to add it to a selectable QTreeWidget



mTreeWidget->setSelectionMode(QAbstractItemView::MultiSelection );
...
mTreeWidget->addTopLevelItem(cities);


Whenever any item in the tree is selected the tree emits an itemClicked signal which you connect to like


QObject::connect(mTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(onClicked(QTreeWidgetItem*, int)));

onClicked(QTreeWidgetItem* item, int column)
{
//Do whatever you want to the item here
}



You actually shouldn't need to set you objects checked state manually the tree will do that automatically

denumbaone
3rd March 2011, 19:51
I've tried the code that you have provided. It compiles but it doesn't seem to jump to the slot. I have provided my code below.

in treeview.h:


private slots:
void setChecked(QTreeWidgetItem *, int);

in treeview.cpp:


QTreeWidgetItem *cities = new QTreeWidgetItem(treeWidget);
cities->setText(0, tr("Places"));
cities->setCheckState(0, Qt::Checked);

mTreeWidget->setSelectionMode(QAbstractItemView::MultiSelection );
mTreeWidget->addTopLevelItem(cities);

QObject::connect(mTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(setChecked(QTreeWidgetItem*,int)));

void TreeView::setChecked(QTreeWidgetItem *item, int)
{
qDebug ("Cities Clicked");
cout << "Cities Clicked" << endl;
}

As you can see, I've added a simple cout and qDebug to signify if the slot has been reached and it does not. Any suggestions?

Berryblue031
4th March 2011, 08:19
So your tree displays properly with the cities item in it and when you click the item in the gui the signal is not being triggered?

Double check you are not getting any error messages other then that it's hard to debug your program with only code snippets

denumbaone
6th March 2011, 15:48
Here is my code for the treeview. Everything compiles, and I only get a warning for an unused parameter "item."

treeview.h


#ifndef TREEVIEW_H
#define TREEVIEW_H

#include <QMainWindow>

class QAction;
class QTreeWidget;
class QTreeWidgetItem;
class QCheckBox;

namespace Ui {
class TreeView;
}

class TreeView : public QMainWindow
{
Q_OBJECT

public:
explicit TreeView(QWidget *parent = 0);
~TreeView();

private slots:
void setChecked(QTreeWidgetItem *, int);

private:
Ui::TreeView *ui;
void setupTreeItems();
// void manageTreeItems();

TreeView * treeView;
//TreeView * check;

QAction *ascendingAction;
QTreeWidget *treeWidget;
QTreeWidget *mTreeWidget;
};

#endif // TREEVIEW_H

treeview.cpp


#include "treeview.h"
//#include "ui_treeview.h"
//#include "dialog.h"

#include <iostream>
#include <QTreeWidget>
#include <QInputDialog>
#include <QCheckBox>
#include <QStandardItem>
#include <Qt>
#include <iostream>

using namespace std;

TreeView::TreeView(QWidget *parent) :
QMainWindow(parent)
//ui(new Ui::TreeView)
{
//ui->setupUi(this);

treeWidget = new QTreeWidget(/*this*/);
mTreeWidget = new QTreeWidget;

treeWidget->setColumnCount(1);

QStringList headers;
headers << tr("Legend");
treeWidget->setHeaderLabels(headers);

setupTreeItems();

setCentralWidget(treeWidget);
setWindowTitle(tr("Tree Widget"));
}

TreeView::~TreeView()
{
//delete ui;
}

void TreeView::setupTreeItems()
{


QTreeWidgetItem *cities = new QTreeWidgetItem(treeWidget);
cities->setText(0, tr("Places"));
cities->setCheckState(0, Qt::Checked);

QTreeWidgetItem *citiesChild = new QTreeWidgetItem();
cities->insertChild(0, citiesChild);
citiesChild->setText(0, tr("USA Cities"));
citiesChild->setCheckState(0, Qt::Checked);

mTreeWidget->setSelectionMode(QAbstractItemView::MultiSelection );
mTreeWidget->addTopLevelItem(cities);

QObject::connect(mTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(setChecked(QTreeWidgetItem*,int)));
}

void TreeView::setChecked(QTreeWidgetItem *item, int)
{
cout << "Cities Clicked" << endl;
qDebug("Cities Clicked");
}

Sorry for the lengthy post, I'm just really having trouble with this problem. When I do anything with the checkbox, it doesn't seem to jump to the slot. Do you have any suggestions?

Berryblue031
8th March 2011, 12:50
Ok I think one of the big problems you have is in the code you listed you declare 3 QTreeWidgets, one in the ui file, then one named "treewidget" and one named "mTreeWidget". The tree widget you actually see when you run the program is the one you declared in the ui file so you need to only use that one in your code.


#ifndef TREEVIEW_H
#define TREEVIEW_H

#include <QMainWindow>

class QAction;
class QTreeWidget;
class QTreeWidgetItem;
class QCheckBox;

#include "ui_treeview.h"

class TreeView : public QMainWindow
{
Q_OBJECT

public:
explicit TreeView(QWidget *parent = 0);
virtual ~TreeView(); //In general always make destructors virtual

private slots:
void setChecked(QTreeWidgetItem *, int);

private:
Ui::TreeView ui;
void setupTreeItems();
QTreeWidget* getTreeWidget(){ return ui.whatever_the_widgets_name_is_in_the_ui_file; }
QAction *ascendingAction;
};

#endif // TREEVIEW_H


#include "treeview.h"

//#include "dialog.h"

#include <QDebug>
#include <QTreeWidget>
#include <QInputDialog>
#include <QCheckBox>
#include <QStandardItem>
#include <Qt>

TreeView::TreeView(QWidget *parent) :
QMainWindow(parent)
{
ui.setupUi(this);

//can be done in ui file
getTreeWidget()->setSelectionMode(QAbstractItemView::MultiSelection );

//Connecting the tree widgets slot only needs to be done once, not for every item
QObject::connect(getTreeWidget(), SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(setChecked(QTreeWidgetItem*,int)));

QStringList headers;
qDebug() << "Legend: " << headers;
getTreeWidget()->setHeaderLabels(headers);

setupTreeItems();
}

TreeView::~TreeView()
{
}

void TreeView::setupTreeItems()
{
QTreeWidgetItem *cities = new QTreeWidgetItem(getTreeWidget(), QTreeWidgetItem::UserType + 1);
cities->setText(0, tr("Places"));

QTreeWidgetItem *citiesChild = new QTreeWidgetItem();
cities->addChild(citiesChild);
citiesChild->setText(0, tr("USA Cities"));

getTreeWidget()->addTopLevelItem(cities);
}

void TreeView::setChecked(QTreeWidgetItem *item, int)
{
if(item->type() == QTreeWidgetItem::UserType + 1)
{
qDebug() << "cities clicked";
}
else
{
qDebug() << "cities child clicked";
}
}


I hope that helps.