QTreeView with QAbstractItemModel and parent not known in the datamodel - qt

I want to use QTreeView to visualize my class hierarchy. That hierarchy is given and I couldn't change it. But QAbstractItemModel force me to implement a parent() method in it. How can I do that?
So I have:
class ItemA
{
std::vector<Items1> items1;
std::vector<Items2> items2;
std::vector<Items3> items3;
};
class Items2
{
std::vector<Items1X> items1X;
std::vector<Items2X> items2X;
std::vector<Items3X> items3X;
};
...
How can I implement a QModelIndex parent(const QModelIndex &index) const; method for QAbstractItemModel?

Related

QSqlQueryModel - How to add and delete rows?

I am making my model which inherits from QSqlQueryModel
#include <QSqlQueryModel>
class SqlQueryModelBorrowingUsers : public QSqlQueryModel
{
Q_OBJECT
//some class members
};
I also have a view that I set in BorrowingUsersWindow class and pass my model to that view.
in this view, i have two QPushButtons add record and delete record
class BorrowingUsersWindow : public QDialog
{
Q_OBJECT
//some class members
private:
SqlQueryModelBorrowingUsers *myModel; //my model
QTableView *tblViewUserData; //my view
QPushButton *bttAddRecord, *bttRemoveRecord; //I have a two buttons add and remove
};
Looking at the classes that QSqlQueryModel inherits from, I found
two functions in the QAbstractItemModel class
insertRow(int row, const QModelIndex &parent = QModelIndex())
removeRow(int row, const QModelIndex &parent = QModelIndex())
So the question is this. How can I implement adding and deleting rows with these two functions? Will someone give you a sample code?

QTableWidget with automatic restore of old cell value

I'm just getting started with QT, so please exercise a little patience...
I've an editable QTableWidget (actually a subclassing), and need to implement the following behavior.
When the user types a non acceptable value I would like:
1) to restore the original value;
2) to keep the focus in the cell and set it in edit mode.
I'm currently using the itemChanged SIGNAL, and a subclassing of QTableWidgetItem.
Which one is the best way to get what I need?
Any tip, suggestion or reference is really welcome.
If you think it as useful I can post some code.
Ciao
Alf.
I'm currently using the itemChanged SIGNAL...
You should subclass QStyledItemDelegate
class CustomTableDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CustomTableDelegate (QObject * parent = 0);
QWidget * createEditor (QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const;
bool editorEvent (QEvent *, QAbstractItemModel *, const QStyleOptionViewItem &, const QModelIndex &);
void setEditorData (QWidget *, const QModelIndex &) const;
void setModelData (QWidget *, QAbstractItemModel *, const QModelIndex &) const;
};
And implement validation inside setModelData.
To use custom delegate you need set it for your QTableWidget:
table->setItemDelegate (new CustomTableDelegate () );

Correctly implementing QStyledItemDelegate

I have a class (EditorTagManager) that contains a QTreeWidget. During runtime, the tree can contain any number of tag items, all of which are checkable. I'm trying to add horizontal lines between the QTreeWidgetItems in order to make it clear that these tags are unrelated and are meant to be separate from one another (each item is a root-level node).
From my research on the subject, I've figured out the only way to control the appearance of QtreeWidgetItems to any meaningful extent is to subclass QStyledItemDelegate and bind the delegate to the QTreeWidget. It's kind of an abstract concept so I don't fully understand it. Since I’ve never had to subclass a Qt object before, I'm not sure if I’m doing it correctly.
Since the Qt Documentation didn't really explain how to do this, I used the settingsdialog.cpp/.h files from the Clementine 1.0.1 source code as my guide/reference because Clementine's preferences window uses similar separators on its QTreeWidget. I'm trying to reverse-engineer my own solution from Clementine's code, the only problem is Clementine's implementation of this does things I don't need (so I have to figure out what's relevant to my code and what's not). That's what got me up to this point; my code is very similar to the Clementine code (I just changed the delegate class name):
Here is my current delegate header declaration in editortreemanager.h:
class TagListDelegate : public QWidget
{
public:
TagListDelegate(QObject* parent);
void paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const;
};
Here is my current delegate source in editortreemanager.cpp:
TagListDelegate::TagListDelegate(QObject *parent) :
TagListDelegate(parent){
}
void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const{
}
Even though TagListDelegate::paint() doesn't actually do anything yet, I just want to get this code working correctly before I try to change the appearance of the QTreeWidgetItems. My goal is to keep this as simple as possible for now.
Everything compiled fine until I told the QTreeWidget (ui->AvailableTags) to use the delegate:
ui->AvailableTags->setItemDelegate(new TagListDelegate(this));
The compiler error reads:
/home/will/qt_projects/robojournal/ui/editortagmanager.cpp:211: error:
no matching function for call to
'QTreeWidget::setItemDelegate(TagListDelegate*)'
I’m in a bit over my head here so I would definitely appreciate some help in figuring this out.
UPDATE (7/30/13):
My Delegate class now looks like this:
Source:
TagListDelegate::TagListDelegate(QStyledItemDelegate *parent) :
TagListDelegate(parent){
}
void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const{
QStyledItemDelegate::paint(painter, option, index);
}
Header declaration:
class TagListDelegate : public QStyledItemDelegate
{
public:
TagListDelegate(QStyledItemDelegate* parent);
void paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const;
};
UPDATE (7/31/13)
Here is what my classes look like now:
header:
class TagListDelegate : public QStyledItemDelegate
{
public:
TagListDelegate(QObject* parent);
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
void paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const;
};
source:
TagListDelegate::TagListDelegate(QObject *parent)
: TagListDelegate(parent){
}
QSize TagListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSize ret = QStyledItemDelegate::sizeHint(option, index);
return ret;
}
void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const{
QStyledItemDelegate::paint(painter, option, index);
}
You're not subclassing QStyledItemDelegate in your code. You're subclassing QWidget.
Change
class TagListDelegate : public QWidget
to:
class TagListDelegate : public QStyledItemDelegate
And don't forget to include the header:
#include <QStyledItemDelegate>

QTableView - Not Getting Selection Changed Signal

I am fairly new to QT, and am having trouble understanding how the QTableView selection changed signal is handled. I have setup a window with an openGL widget and a QTableView. I have a data model class that is correctly populating the tableview, so I added a public slot to that class:
class APartsTableModel : public QAbstractTableModel
{
public:
AVehicleModel *vehicle;
explicit APartsTableModel(QObject *parent = 0);
//MVC functions
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &paret) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
public slots:
void selectionChangedSlot(const QItemSelection &newSelection,
const QItemSelection &oldSelection);
};
When I am ready to show the window with the table view, I allocate/initialize it like this:
//create the display view
AStarModelView *displayWindow = new AStarModelView(this,
starModel->vehicle);
//create the datamodel for the table view
APartsTableModel *dataModel = new APartsTableModel(displayWindow);
dataModel->vehicle = starModel->vehicle;
//create selection model for table view
QItemSelectionModel *selModel = new QItemSelectionModel(dataModel);
displayWindow->materialsTable->setSelectionModel(selModel);
//setup model and signal
displayWindow->materialsTable->setModel(dataModel);
connect(selModel,
SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
dataModel,
SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &)));
//show the view
displayWindow->show();
When I set a breakpoint in the implementation of the slot function, I never hit it. I've also tried not allocating a new QItemSelectionModel, but that didn't work either. I'm really not sure what I'm doing wrong here.
When you call setModel() on the view, your locally allocated QItemSelectionModel is getting replaced by one created by the view. You shouldn't have to create your own selection model anyway. Just change your connect to
connect(displayWindow->materialsTable->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
dataModel,
SLOT(selectionChangedSlot(const QItemSelection&, const QItemSelection&)));
What's the first thing you should check in QT when signals/slots don't seem to be working correctly? That your class has the Q_OBJECT macro in it. Added this to the APartsTable class definition, and now I'm hitting the breakpoint.
When does Friday get here?
Just to pull the answer out of the discussion:
What's the first thing you should check in QT when signals/slots don't
seem to be working correctly? That your class has the Q_OBJECT macro
in it. Added this to the APartsTable class definition, and now I'm
hitting the breakpoint
.
virtual Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
must return Qt::ItemIsSelectable | otherFlags

How to create Symbian style list views in Qt

I've never done any item delegates in Qt before, and I think the documentation doesn't explain well about more complex delegates.
I need to create 2 styles of Symbian(^3) style lists
Type 1:
This is for common navigation lists, the icon and the lower label are optional.
Type 2:
This is for settings lists, where the pushbutton can be a toggle(on/off)-button or execute a context menu, etc.
How would I go on creating these sort of item delegates?
Best Regards,
Rat
I had to make something similar once. This is how I did it.
My delegate class declaration. As you can see it has a member: QLabel *label. You can add another label or a pushbutton, depending on your needs.
class MyItemDelegate : public QStyledItemDelegate
{
public:
explicit MyItemDelegate(QObject *parent = 0);
~MyItemDelegate();
protected:
void paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const;
private:
QLabel *label;
};
My paint() and sizeHint() methods.
QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(!index.isValid())
return QSize();
QVariant data = index.data(Qt::DisplayRole);
label->setText(data.toString());
label->resize(label->sizeHint());
QSize size(option.rect.width(), label->height());
return size;
}
void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(!index.isValid())
return;
QVariant data = index.data(Qt::DisplayRole);
// Not necessary to do it here, as it's been already done in sizeHint(), but anyway.
label->setText(data.toString());
painter->save();
QRect rect = option.rect;
// This will draw a label for you. You can draw a pushbutton the same way.
label->render(painter, QPoint(rect.topLeft().x(), rect.center().y() - label->height() / 2),
QRegion(label->rect()), QWidget::RenderFlags());
painter->restore();
}
Hope this is what you've been looking for. Good luck!
You have 2 options ,
1) QML - This in my opinion is the best way to go and easier to achieve what you are trying to do.
Link to Example
This shows you how to use a Delegate for a listview.
2)QItemDelegate - Subclass QItemDelegate then Assign a this delegate to a listview ,
Link to QItemDelegate

Resources