Development/Tutorials/Introduction to Goya usage: Difference between revisions
No edit summary |
|||
Line 38: | Line 38: | ||
#include <kicon.h> | #include <kicon.h> | ||
class MiDelegate | |||
: public Goya::Canvas | |||
: public | |||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MiDelegate(QAbstractItemView *itemView, QObject *parent = 0) | |||
: | : Canvas(itemView, parent) | ||
{ | { | ||
button = new Goya::PushButton(0); | button = new Goya::PushButton(0); | ||
Line 63: | Line 52: | ||
button->setIconSize(QSize(16, 16)); | button->setIconSize(QSize(16, 16)); | ||
button->setEatEvents(QEvent::MouseButtonPress); | button->setEatEvents(QEvent::MouseButtonPress); | ||
button->setEatEvents(QEvent::MouseButtonRelease); | button->setEatEvents(QEvent::MouseButtonRelease); | ||
button->setEatEvents(QEvent::MouseButtonDblClick); | button->setEatEvents(QEvent::MouseButtonDblClick); | ||
connect(button, SIGNAL(clicked(QModelIndex,const Goya::PushButton*)), | connect(button, SIGNAL(clicked(QModelIndex,const Goya::PushButton*)), | ||
this, SLOT(slotClicked(QModelIndex))); | this, SLOT(slotClicked(QModelIndex))); | ||
} | } | ||
virtual ~ | virtual ~MiDelegate() | ||
{ | { | ||
delete button; | delete button; | ||
} | } | ||
QList<Goya::Widget*> widgetsForIndex(const QModelIndex &index) const | |||
{ | { | ||
if (index.row() % 3) | |||
return QList<Goya::Widget*>(); | |||
return | |||
return QList<Goya::Widget*>() << button; | |||
} | } | ||
QPoint widgetPosition(Goya::Widget *widget, const QStyleOption *option, | QPoint widgetPosition(Goya::Widget *widget, const QStyleOption *option, | ||
const QModelIndex &index) const | const QModelIndex &index) const | ||
{ | { | ||
return QPoint(option->fontMetrics.height(), | |||
return QPoint(option->fontMetrics.height(), | |||
option->fontMetrics.height()); | option->fontMetrics.height()); | ||
} | } | ||
Line 162: | Line 95: | ||
} | } | ||
painter->drawText(option.fontMetrics.height() + option.rect.left(), | painter->drawText(option.fontMetrics.height() + option.rect.left(), | ||
option.fontMetrics.height() * 3 + | option.fontMetrics.height() * 3 + | ||
Canvas::sizeHint(option, index).height() + | Canvas::sizeHint(option, index).height() + | ||
option.rect.top(), | option.rect.top(), | ||
QString("This is the index in row number ") + | QString("This is the index in row number ") + | ||
Line 175: | Line 104: | ||
painter->restore(); | painter->restore(); | ||
Canvas::paint(painter, option, index); | Canvas::paint(painter, option, index); | ||
} | } | ||
Line 187: | Line 113: | ||
Q_UNUSED(index); | Q_UNUSED(index); | ||
QSize size = Canvas::sizeHint(option, index); | QSize size = Canvas::sizeHint(option, index); | ||
Line 195: | Line 119: | ||
return size; | return size; | ||
} | |||
private: | |||
Goya::PushButton *button; | |||
private Q_SLOTS: | |||
void slotClicked(const QModelIndex &index) | |||
{ | |||
KMessageBox::information(0, "More information clicked on row " + | |||
QString::number(index.row() + 1), | |||
"Button clicked"); | |||
} | } | ||
}; | }; | ||
Line 202: | Line 137: | ||
KAboutData aboutData("goyatest", | KAboutData aboutData("goyatest", | ||
0, | 0, | ||
ki18n("Goya | ki18n("Goya Test "), | ||
"1.0", | "1.0", | ||
ki18n("A test for the Goya | ki18n("A test for the Goya subsystem"), | ||
KAboutData::License_LGPL, | KAboutData::License_LGPL, | ||
ki18n("(c) Rafael Fernández López, | ki18n("(c) Rafael Fernández López, 2007"), | ||
ki18n("A test for the Goya | ki18n("A test for the Goya subsystem"), | ||
"http://www.ereslibre.es", | "http://www.ereslibre.es", | ||
" | "ereslibre@kde.org"); | ||
KCmdLineArgs::init(argc, argv, &aboutData); | KCmdLineArgs::init(argc, argv, &aboutData); | ||
Line 221: | Line 156: | ||
QListView *listView = new QListView(); | QListView *listView = new QListView(); | ||
listView->setSelectionMode(QAbstractItemView::ExtendedSelection); | |||
QStringListModel *model = new QStringListModel(); | |||
MiDelegate *delegate = new MiDelegate(listView); | |||
QListView *listView2 = new QListView(); | |||
listView2->setSelectionMode(QAbstractItemView::ExtendedSelection); | |||
QStringListModel *model2 = new QStringListModel(); | |||
MiDelegate *delegate2 = new MiDelegate(listView2); | |||
model->insertColumn(0); | model->insertColumn(0); | ||
Line 229: | Line 170: | ||
model->insertRow(i); | model->insertRow(i); | ||
model->setData(model->index(i, 0), QString::number(i)); | model->setData(model->index(i, 0), QString::number(i)); | ||
} | |||
model2->insertColumn(0); | |||
for (int i = 0; i < 10; ++i) | |||
{ | |||
model2->insertRow(i); | |||
model2->setData(model2->index(i, 0), QString::number(i)); | |||
} | } | ||
Line 235: | Line 183: | ||
listView->setVerticalScrollMode(QListView::ScrollPerPixel); | listView->setVerticalScrollMode(QListView::ScrollPerPixel); | ||
listView2->setModel(model2); | |||
listView2->setItemDelegate(delegate2); | |||
listView2->setVerticalScrollMode(QListView::ScrollPerPixel); | |||
layout->addWidget(new QPushButton("Above Button")); | |||
layout->addWidget(listView); | layout->addWidget(listView); | ||
layout->addWidget(listView2); | |||
layout->addWidget(new QPushButton("Below Button")); | |||
widget->show(); | widget->show(); | ||
Line 241: | Line 196: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
#include "main.moc" | |||
</code> | </code> |
Revision as of 14:16, 14 February 2008
Tutorial Series | Goya Framework |
Previous | C++, Qt, Model/View Qt Framework, KDE4 development environment |
What's Next | A slightly more complex example |
Further Reading | n/a |
Abstract
We are developing some component of our application using Model/View (check prerequisites). At some point on our development, we discover that we actually want to add widgets to our delegate, but the Model/View framework does not provide a powerful and integrated way of doing so. Here is where Goya comes to help out for this task.
We could say Goya is a layer between the view and your delegate that draws widgets with the needed options and that seem to behave as if they were real widgets, but they are fake widgets after all.
Goya is so nice mainly because it integrates pretty well with the Model/View design, and uses the Qt powerful signals and slots. Goya widgets will emit signals when something have happened to them, so you will be able to connect those signals to your app slots, and do fancy stuff without complex stuff.
A Simple Example
This example consists on a single window that will contain a list view. There will be pushbuttons only in the odd rows.
// Basic Goya includes
- include <goya/goya.h>
- include <goya/pushbutton.h>
// Basic Qt includes
- include <QPainter>
- include <QBoxLayout>
- include <QListView>
- include <QStringListModel>
// Basic KDE includes
- include <kapplication.h>
- include <kaboutdata.h>
- include <kmessagebox.h>
- include <kcmdlineargs.h>
- include <klocalizedstring.h>
- include <kicon.h>
class MiDelegate
: public Goya::Canvas
{
Q_OBJECT
public:
MiDelegate(QAbstractItemView *itemView, QObject *parent = 0)
: Canvas(itemView, parent)
{
button = new Goya::PushButton(0);
button->setText("More Information");
button->setIcon(KIcon("help-about"));
button->setIconSize(QSize(16, 16));
button->setEatEvents(QEvent::MouseButtonPress);
button->setEatEvents(QEvent::MouseButtonRelease);
button->setEatEvents(QEvent::MouseButtonDblClick);
connect(button, SIGNAL(clicked(QModelIndex,const Goya::PushButton*)),
this, SLOT(slotClicked(QModelIndex)));
}
virtual ~MiDelegate()
{
delete button;
}
QList<Goya::Widget*> widgetsForIndex(const QModelIndex &index) const
{
if (index.row() % 3)
return QList<Goya::Widget*>();
return QList<Goya::Widget*>() << button;
}
QPoint widgetPosition(Goya::Widget *widget, const QStyleOption *option,
const QModelIndex &index) const
{
return QPoint(option->fontMetrics.height(),
option->fontMetrics.height());
}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (option.state & QStyle::State_Selected)
{
painter->fillRect(option.rect, option.palette.highlight());
}
painter->save();
if (option.state & QStyle::State_Selected)
{
painter->setPen(QPen(option.palette.highlightedText().color()));
}
painter->drawText(option.fontMetrics.height() + option.rect.left(),
option.fontMetrics.height() * 3 +
Canvas::sizeHint(option, index).height() +
option.rect.top(),
QString("This is the index in row number ") +
QString::number(index.row() + 1));
painter->restore();
Canvas::paint(painter, option, index);
}
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
QSize size = Canvas::sizeHint(option, index);
size.setWidth(size.width() + option.fontMetrics.height() * 4);
size.setHeight(size.height() + option.fontMetrics.height() * 4);
return size;
}
private:
Goya::PushButton *button;
private Q_SLOTS:
void slotClicked(const QModelIndex &index)
{
KMessageBox::information(0, "More information clicked on row " +
QString::number(index.row() + 1),
"Button clicked");
}
};
int main(int argc, char **argv)
{
KAboutData aboutData("goyatest",
0,
ki18n("Goya Test "),
"1.0",
ki18n("A test for the Goya subsystem"),
KAboutData::License_LGPL,
ki18n("(c) Rafael Fernández López, 2007"),
ki18n("A test for the Goya subsystem"),
"http://www.ereslibre.es",
"[email protected]");
KCmdLineArgs::init(argc, argv, &aboutData);
KApplication app;
QWidget *widget = new QWidget();
QVBoxLayout *layout = new QVBoxLayout;
widget->setLayout(layout);
widget->resize(800, 600);
QListView *listView = new QListView();
listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
QStringListModel *model = new QStringListModel();
MiDelegate *delegate = new MiDelegate(listView);
QListView *listView2 = new QListView();
listView2->setSelectionMode(QAbstractItemView::ExtendedSelection);
QStringListModel *model2 = new QStringListModel();
MiDelegate *delegate2 = new MiDelegate(listView2);
model->insertColumn(0);
for (int i = 0; i < 1000; ++i)
{
model->insertRow(i);
model->setData(model->index(i, 0), QString::number(i));
}
model2->insertColumn(0);
for (int i = 0; i < 10; ++i)
{
model2->insertRow(i);
model2->setData(model2->index(i, 0), QString::number(i));
}
listView->setModel(model);
listView->setItemDelegate(delegate);
listView->setVerticalScrollMode(QListView::ScrollPerPixel);
listView2->setModel(model2);
listView2->setItemDelegate(delegate2);
listView2->setVerticalScrollMode(QListView::ScrollPerPixel);
layout->addWidget(new QPushButton("Above Button"));
layout->addWidget(listView);
layout->addWidget(listView2);
layout->addWidget(new QPushButton("Below Button"));
widget->show();
return app.exec();
}
- include "main.moc"