PDA

View Full Version : Designer UI widget in qtablewidget / setCellWidget



tpf80
3rd July 2007, 07:47
I may be a lughead, but I can not seem to figure out the proper direction to take with what I am trying to accomplish. Basically I have a QTableWidget with some data in cells as follows:

----------------------
ID | name | phone #|
----------------------
|*tool* | e-mail |
----------------------
ID | name | phone #|
----------------------
|*tool* | e-mail |
----------------------
repeat....

I have the table widget working properly to display my data how I want, but in the *tool* cells I would like to put some buttons/icons that someone could click to spawn a popup about the person shown in the table.

I created a widget UI file from designer, and I have read docs about setCellWidget(). I am still at a loss however about how to use the UI file (my small toolbar) with setCellWidget(), and then connecting slots to the signals that the toolbar generates.

I have made lots of dialog popups, and my main window with UI files and designer, just not quite sure how to place it within many cells in a table.

tpf80
3rd July 2007, 10:34
So far here is what I have:

My Header to use the (tools_contacts.h):


#ifndef TOOLS_CONTACTS_H
#define TOOLS_CONTACTS_H

//user interface items:
#include "ui_tools_contacts.h"

//Qt functions:
#include <QString>

class toolsContacts : public QWidget, private Ui::toolsContacts {

Q_OBJECT

public:
//functions:
toolsContacts(QWidget *parent = 0);

private slots:

private:

};

#endif



the tools_contacts.cpp:


#include <QtGui>

#include "tools_contacts.h"

//setup interface of main window:
toolsContacts::toolsContacts(QWidget *parent) : QWidget(parent) {

setupUi(this);

}



The test code to invoke it from my main window:


toolsContacts contactListTool(this);
ui.tableWidget->setCellWidget(1, 1, contactListTool);


I think I am close, however when I compile I get the following errors:

This I believe is from an issue somewhere within my class to use the UI file:


In file included from tools_contacts.h:5,
from calculatorform.h:15,
from calculatorform.cpp:3:
ui_tools_contacts.h:25: error: expected unqualified-id before "delete"
ui_tools_contacts.h:25: error: abstract declarator `QToolButton*' used as declaration
ui_tools_contacts.h:25: error: expected `;' before "delete"
ui_tools_contacts.h: In member function `void Ui_toolsContacts::setupUi(QWidget*)':
ui_tools_contacts.h:42: error: expected primary-expression before '=' token
ui_tools_contacts.h:43: error: expected primary-expression before '->' token
ui_tools_contacts.h:44: error: expected primary-expression before '->' token
ui_tools_contacts.h:45: error: expected primary-expression before '->' token
ui_tools_contacts.h: In member function `void Ui_toolsContacts::retranslateUi(QWidget*)':
ui_tools_contacts.h:57: error: expected primary-expression before '->' token


This comes from me not being able to tell the setCellWidget function that my toolsContacts is a widget:




error: no matching function for call to `QTableWidget::setCellWidget(int, int, toolsContacts&)'

tpf80
4th July 2007, 00:46
Well I have solved part of the issue now:

the errors within the ui_tools_contacts.h file were caused by me naming a button within the .ui file "delete" once I renamed it to "trash" then those errors went away. So I guess I am still stuck on how to actually place the widget in my table, i still get this error:




calculatorform.cpp: In member function `void ProgramMain::showContacts()':
calculatorform.cpp:1683: error: no matching function for call to `QTableWidget::setCellWidget(int, int, toolsContacts&)'
../../include/QtGui/../../src/gui/itemviews/qtablewidget.h:249: note: candidates are: void QTableWidget::setCellWidget(int, int, QWidget*)

C:\Qt\4.3.0\Kdevelop\housing>

jpn
4th July 2007, 08:48
The cell widget should be allocated on the heap:


toolsContacts* contactListTool = new toolsContacts(this);
ui.tableWidget->setCellWidget(1, 1, contactListTool);

tpf80
4th July 2007, 09:36
your awesome, this made the toolbar show up in the cell just like I wanted it to.

Do I access the signals in the contactListTool by contactListTool.signal()? Also, is there a way to have the object names be variable? since I would not be able to know how many of these ui's would be shown, due to an unknown table size until runtime.

jpn
4th July 2007, 20:48
your awesome, this made the toolbar show up in the cell just like I wanted it to.
Great :)


Do I access the signals in the contactListTool by contactListTool.signal()?
Sorry, what do you mean? You connect cell widget signals like any other signals:


toolsContacts* contactListTool = new toolsContacts(this);
ui.tableWidget->setCellWidget(1, 1, contactListTool);
connect(contactListTool, SIGNAL(someSignal()), ....);



Also, is there a way to have the object names be variable? since I would not be able to know how many of these ui's would be shown, due to an unknown table size until runtime.
You can later access any particular cell widget via QTableWidget::cellWidget(). Is this what you mean?

tpf80
6th July 2007, 04:42
You can later access any particular cell widget via QTableWidget::cellWidget(). Is this what you mean?

Kindof, But when I create them, they have to have a different name correct? so say I have a loop that creates table rows, and in each row adds the widget. How could I give them a variable name? Perhaps this is more of a general c++ question than a Qt specific one.

For instance in php I could have ${$something}, and if $something was "cat" then id have a variable $cat, but if $something was "dog" then id have a variable $dog. In this way, I could have a variable with a variable name. A use would be like ${"variable_" . $index} and a for loop would create variables each named by the index (but not an array).

Assuming that the widgets can't have the same name, and I wouldn't know how many of them I would have until the table is filled with data, it would make sense to use this kind of logic when I create them.

jpn
6th July 2007, 07:18
You don't need variables with variable names:


// how to create and set a cell widget in each cell:
for (int row = 0; row < ui.tableWidget->rowCount(); ++row)
{
for (int col = 0; col < ui.tableWidget->columnCount(); ++col)
{
toolsContacts* contactListTool = new toolsContacts(ui.tableWidget);
ui.tableWidget->setCellWidget(row, col, contactListTool);
}
}

// how to access a cell widget in particular cell:
toolsContacts* contactListTool = dynamic_cast<toolsContacts*>(ui.tableWidget->cellWidget(2, 3)); // row, col
if (contactListTool)
{
// the cell contains a cell widget and it's of type toolsContacts
contactListTool->doSomething();
}

tpf80
6th July 2007, 08:17
Thanks a lot for all your help, I now understand a lot better how this all fits together!:)

tpf80
9th July 2007, 21:35
one thing I forgot to ask about, but I want to make sure I use good programming techniques.

The table can be refreshed to have new rows in it, and since there will not be too many and I want the latest info to be there, every time I grab new data, I first use:


tableWidget->setRowCount(0)

to clear the table (which is working nicely for this task), then I add new rows with the new data. Since the table could be refreshed often, my main concern is memory leaks in this case.

When I clear the table, do the toolsContacts widgets contained within the cells automatically get deleted too? Or are they still in memory, requiring me to make a function to clean them up as part of the process of clearing the table? Also, if there are any slots connected to them, do I need to "disconnect" them before clearing the table, or are their connections removed when the widgets are deleted?

Thanks a lot for all your help!

jpn
9th July 2007, 23:02
Yes, setting row count to 0 makes items and cell widgets to get properly deleted. Does the row count vary between updates? If not, QTableWidget::clear() would be more natural choice.

And yes, QObject disconnects associated signal slot connections upon destruction. See QObject::~QObject() (http://doc.trolltech.com/4.3/qobject.html#dtor.QObject) docs for more details.