Model view controller : QDesignerCustomWidgetInterface « Qt « C++

Home
C++
1.Bitset
2.Class
3.Console
4.Data Structure
5.Data Type
6.Deque
7.Development
8.File
9.Function
10.Generic
11.Language
12.List
13.Map Multimap
14.Overload
15.Pointer
16.Qt
17.Queue Stack
18.Set Multiset
19.STL Algorithms Binary search
20.STL Algorithms Heap
21.STL Algorithms Helper
22.STL Algorithms Iterator
23.STL Algorithms Merge
24.STL Algorithms Min Max
25.STL Algorithms Modifying sequence operations
26.STL Algorithms Non modifying sequence operations
27.STL Algorithms Sorting
28.STL Basics
29.String
30.Valarray
31.Vector
C / ANSI-C
C Tutorial
C++ Tutorial
Visual C++ .NET
C++ » Qt » QDesignerCustomWidgetInterfaceScreenshots 
Model view controller
  

/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef VIEW_H
#define VIEW_H

#include <QAbstractItemView>
#include <QItemSelection>
#include <QItemSelectionModel>
#include <QModelIndex>
#include <QRect>
#include <QSize>
#include <QWidget>

class LinearView : public QAbstractItemView
{
    Q_OBJECT
public:
    LinearView(QWidget *parent = 0);

    QRect itemViewportRect(const QModelIndex &indexconst;
    void ensureVisible(const QModelIndex &index);
    QModelIndex itemAt(int x, int yconst;

protected slots:
    /*void dataChanged(const QModelIndex &topLeft, const QModelIndex
    &bottomRight);*/
    void rowsInserted(const QModelIndex &parent, int start, int end);
    void rowsRemoved(const QModelIndex &parent, int start, int end);
    /*void selectionChanged(const QItemSelection &deselected, const QItemSelection &selected);
    void verticalScrollbarAction(int action);
    void horizontalScrollbarAction(int action);*/

protected:
    void setSelection(const QRect&, QItemSelectionModel::SelectionFlags command);
    QRect selectionViewportRect(const QItemSelection &selectionconst;
    QRect itemRect(const QModelIndex &itemconst;
    bool isIndexHidden(const QModelIndex &indexconst;
    int horizontalOffset() const;
    int verticalOffset() const;
    QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,
                           Qt::KeyboardModifiers modifiers);

    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
    QSize sizeHint() const;

private:
    int rows(const QModelIndex &index = QModelIndex()) const;
    void updateGeometries();
};

#endif







/*!
    view.cpp

    Provides a view to represent a one-dimensional sequence of integers
    obtained from a list model as a series of rows.
*/

#include <QAbstractItemModel>
#include <QBrush>
#include <QItemSelection>
#include <QPainter>
#include <QPaintEvent>
#include <QPen>
#include <QPoint>
#include <QResizeEvent>
#include <QScrollBar>
#include <QSizePolicy>

#include "view.h"

LinearView::LinearView(QWidget *parent)
    : QAbstractItemView(parent)
{
    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
}

/*!
    Returns the position of the item in viewport coordinates.
*/

QRect LinearView::itemViewportRect(const QModelIndex &indexconst
{
    QRect rect = itemRect(index);
    QRect result(rect.left() - horizontalScrollBar()->value(),
                 rect.top() - verticalScrollBar()->value(),
                 rect.width(), viewport()->height());

    return result;
}

/*!
    Returns the rectangle of the item at position \a index in the
    model. The rectangle is in contents coordinates.
*/

QRect LinearView::itemRect(const QModelIndex &indexconst
{
    if (!index.isValid())
        return QRect();
    else
        return QRect(index.row()011);
}


void LinearView::ensureVisible(const QModelIndex &index)
{
    QRect area = viewport()->rect();
    QRect rect = itemViewportRect(index);

    if (rect.left() < area.left())
        horizontalScrollBar()->setValue(
            horizontalScrollBar()->value() - rect.left());
    else if (rect.right() > area.right())
        horizontalScrollBar()->setValue(
            horizontalScrollBar()->value() + rect.left() - area.width());
}

/*!
    Returns the item that covers the coordinate given in the view.
*/

QModelIndex LinearView::itemAt(int x, int /* y */const
{
    int row = x + horizontalScrollBar()->value();

    return model()->index(row, 0, QModelIndex());
}

//void LinearView::dataChanged(const QModelIndex &/* topLeft */,
//    const QModelIndex &/* bottomRight */)
//{
//    updateGeometries();
//    if (isVisible())
//        repaint();
//}

void LinearView::rowsInserted(const QModelIndex &/* parent */int /* start */,
    int /* end */)
{
    updateGeometries();
    if (isVisible())
        repaint();
}

void LinearView::rowsRemoved(const QModelIndex &/* parent */int /* start */,
    int /* end */)
{
    updateGeometries();
    if (isVisible())
        repaint();
}
/*
void LinearView::verticalScrollbarAction(int action)
{
}

void LinearView::horizontalScrollbarAction(int action)
{
}
*/

/*!
    Select the items in the model that lie within the rectangle specified by
    \a rect, using the selection \a command.
*/

void LinearView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
{
    QModelIndex leftIndex = itemAt(rect.left()0);
    QModelIndex rightIndex = itemAt(rect.right()0);

    QItemSelection selection(leftIndex, rightIndex);

    selectionModel()->select(selection, command);
}

QModelIndex LinearView::moveCursor(QAbstractItemView::CursorAction cursorAction,
                                   Qt::KeyboardModifiers)
{
    QModelIndex current = currentIndex();

    switch (cursorAction) {
    case MoveLeft:{
        if (current.row() 0)
            return model()->index(current.row() 10, QModelIndex());
        else
            return model()->index(00, QModelIndex());
        break;}
    case MoveRight:{
        if (current.row() < rows(current1)
            return model()->index(current.row() 10, QModelIndex());
        else
            return model()->index(rows(current10,QModelIndex());
        break;}
    case MoveUp:
        return current;
    case MoveDown:
        return current;
    case MovePageUp:
        return current;
    case MovePageDown:
        return current;
    case MoveHome:
        return model()->index(00, QModelIndex());
    case MoveEnd:
        return model()->index(rows(current10, QModelIndex());
    default:
        return current;
    }
}

int LinearView::horizontalOffset() const
{
    return horizontalScrollBar()->value();
}

int LinearView::verticalOffset() const
{
    return verticalScrollBar()->value();
}

/*!
    Returns a rectangle corresponding to the selection in viewport cooridinates.
*/

QRect LinearView::selectionViewportRect(const QItemSelection &selectionconst
{
    int ranges = selection.count();

    if (ranges == 0)
        return QRect();

    // Note that we use the top and bottom functions of the selection range
    // since the data is stored in rows.

    int firstRow = selection.at(0).top();
    int lastRow = selection.at(0).top();

    for (int i = 0; i < ranges; ++i) {
        firstRow = qMin(firstRow, selection.at(i).top());
        lastRow = qMax(lastRow, selection.at(i).bottom());
    }

    QModelIndex firstItem = model()->index(qMin(firstRow, lastRow)0,
        QModelIndex());
    QModelIndex lastItem = model()->index(qMax(firstRow, lastRow)0,
        QModelIndex());

    QRect firstRect = itemViewportRect(firstItem);
    QRect lastRect = itemViewportRect(lastItem);

    return QRect(firstRect.left(), firstRect.top(),
        lastRect.right() - firstRect.left(), firstRect.height());
}

void LinearView::paintEvent(QPaintEvent *event)
{
    QPainter painter(viewport());

    QRect updateRect = event->rect();
    QBrush background(Qt::black);
    QPen foreground(Qt::white);

    painter.fillRect(updateRect, background);
    painter.setPen(foreground);

    QModelIndex firstItem = itemAt(updateRect.left(), updateRect.top());
    if (!firstItem.isValid())
        firstItem = model()->index(00, QModelIndex());

    QModelIndex lastItem = itemAt(updateRect.right(), updateRect.bottom());
    if (!lastItem.isValid())
        lastItem = model()->index(rows() 10, QModelIndex());

    int x = updateRect.left();
    //int top = updateRect.top();
    //int bottom = updateRect.bottom();

    int row = firstItem.row();
    QModelIndex index = model()->index(row, 0, QModelIndex());
    int value = model()->data(index, Qt::DisplayRole).toInt();
    int midPoint = viewport()->height()/2;
    int y2 = midPoint - int(value * midPoint/255.0);

    while (row <= lastItem.row()) {

        QModelIndex index = model()->index(row, 0, QModelIndex());
        int value = model()->data(index, Qt::DisplayRole).toInt();

        int y1 = y2;
        y2 = midPoint - int(value * midPoint/255.0);

        painter.drawLine(x-1, y1, x, y2);
        ++row; ++x;
    }
}

void LinearView::resizeEvent(QResizeEvent * /* event */)
{
    updateGeometries();
}

void LinearView::updateGeometries()
{
    if (viewport()->width() < rows()) {
        horizontalScrollBar()->setPageStep(viewport()->width());
        horizontalScrollBar()->setRange(0, rows() - viewport()->width() 1);
    }
}

QSize LinearView::sizeHint() const
{
    return QSize(rows()200);
}

int LinearView::rows(const QModelIndex &indexconst
{
    return model()->rowCount(model()->parent(index));
}

bool LinearView::isIndexHidden(const QModelIndex &indexconst
{
    return false;
}






#ifndef MODEL_H
#define MODEL_H

#include <QAbstractListModel>
#include <QObject>
#include <qvector.h>

class LinearModel : public QAbstractListModel
{
    Q_OBJECT
public:
    LinearModel(QObject *parent = 0)
        : QAbstractListModel(parent) {}

    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    QModelIndex index(int row, int column = 0const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int roleconst;

    Qt::ItemFlags flags(const QModelIndex &indexconst;
    bool setData(const QModelIndex &index, const QVariant &value,
                 int role = Qt::EditRole);

    bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
    bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());

private:
    QVector<int> values;
};

#endif







/*
  model.cpp

  A simple model that uses a QVector as its data source.
*/

#include "model.h"

/*!
    Returns the number of items in the string list as the number of rows
    in the model.
*/

int LinearModel::rowCount(const QModelIndex &parentconst
{
    Q_USING(parent);

    return values.count();
}

/*
    Returns an appropriate value for the requested data.
    If the view requests an invalid index, an invalid variant is returned.
    If a header is requested then we just return the column or row number,
    depending on the orientation of the header.
    Any valid index that corresponds to a string in the list causes that
    string to be returned.
*/

/*!
    Returns a model index for other component to use when referencing the
    item specified by the given row, column, and type. The parent index
    is ignored.
*/

QModelIndex LinearModel::index(int row, int column, const QModelIndex &parentconst
{
    if (parent == QModelIndex() && row >= && row < rowCount()
        && column == 0)
        return createIndex(row, column, 0);
    else
        return QModelIndex();
}

QVariant LinearModel::data(const QModelIndex &index, int roleconst
{
    Q_UNUSED(role);

    if (!index.isValid())
        return QVariant();

    return values.at(index.row());
}

/*!
    Returns Qt::ItemIsEditable so that all items in the vector can be edited.
*/

Qt::ItemFlags LinearModel::flags(const QModelIndex &indexconst
{
    // all items in the model are editable
    return QAbstractListModel::flags(index| Qt::ItemIsEditable;
}

/*!
    Changes an item in the string list, but only if the following conditions
    are met:

    * The index supplied is valid.
    * The index corresponds to an item to be shown in a view.
    * The role associated with editing text is specified.

    The dataChanged() signal is emitted if the item is changed.
*/

bool LinearModel::setData(const QModelIndex &index,
                          const QVariant &value, int role)
{
    if (!index.isValid() || role != Qt::EditRole)
        return false;
    values.replace(index.row(), value.toInt());
    emit dataChanged(index, index);
    return true;
}

/*!
    Inserts a number of rows into the model at the specified position.
*/

bool LinearModel::insertRows(int position, int rows, const QModelIndex &parent)
{
    beginInsertRows(parent, position, position + rows - 1);

    values.insert(position, rows, 0);

    endInsertRows();
    return true;
}

/*!
    Removes a number of rows from the model at the specified position.
*/

bool LinearModel::removeRows(int position, int rows, const QModelIndex &parent)
{
    beginRemoveRows(QModelIndex(), position, position+rows-1);

    values.remove(position, rows);

    endRemoveRows();
    return true;
}










#ifndef WINDOW_H
#define WINDOW_H

#include <QMainWindow>
#include <QString>
#include <QWidget>

#include "model.h"
#include "view.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow::MainWindow(QWidget *parent = 0);

public slots:
    void selectOpenFile();

private:
    void setupModelView();
    void openFile(const QString &fileName);

    LinearModel *model;
    LinearView *view;
};

#endif







#include <QAction>
#include <QDataStream>
#include <QMenu>
#include <QMenuBar>
#include <QFile>
#include <QFileDialog>
#include <QListView>

#include "window.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle("Model/View example");

    setupModelView();

    QAction *openAction = new QAction(tr("&Open")this);
    QAction *quitAction = new QAction(tr("E&xit")this);
    QMenu *fileMenu = new QMenu(tr("&File")this);
    fileMenu->addAction(openAction);
    fileMenu->addAction(quitAction);
    menuBar()->addMenu(fileMenu);

    connect(openAction, SIGNAL(triggered()), this, SLOT(selectOpenFile()));
    connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));

    setCentralWidget(view);
}

void MainWindow::setupModelView()
{
    model = new LinearModel(this);
    view = new LinearView(this);
    view->setModel(model);
}

void MainWindow::selectOpenFile()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        tr("Select a file to open")"", tr("Sound files (*.wav)"));
    
    if (!fileName.isEmpty())
        openFile(fileName);
}

void MainWindow::openFile(const QString &fileName)
{
    QFile file(fileName);
    int length = file.size();

    if (file.open(QFile::ReadOnly)) {
        model->removeRows(0, model->rowCount());

        int rows = (length - 0x2c)/2;
        model->insertRows(0, rows);

        // Perform some dodgy tricks to extract the data from the file.
        QDataStream stream(&file);
        stream.setByteOrder(QDataStream::LittleEndian);

        Q_INT16 left;
        Q_INT16 right;

        for (int row = 0; row < rows; ++row) {
            QModelIndex index = model->index(row);

            stream >> left >> right;
            model->setData(index, int(left / 256));
        }
    }
}






/*
    main.cpp

    An example of a main window application that used a subclassed model
    and view to display data from sound files.
*/

#include <QApplication>

#include "model.h"
#include "view.h"
#include "window.h"

/*!
    The main function for the linear model example. This creates and
    populates a model with long integers then displays the contents of the
    model using a QListView widget.
*/

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MainWindow *window = new MainWindow;

    window->show();
    return app.exec();
}

   
    
  
Related examples in the same category
1.extends QDesignerCustomWidgetInterface
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.