О таблицах в Qt мы уже говорили, когда рассматривали концепцию Модель-Представление в Qt и помещали QProgressBar в QTableView. Теперь убедимся, что добавлять изображения в Qt-таблицы еще проще.
Вот что у нас получится:
Создадим каркас приложения, состоящего из таблицы QTableWidget
и простой командной ссылки. Начинаем с заголовочного файла imagetableviewdemowidget.h
:
#ifndef IMAGETABLEVIEWDEMOWIDGET_H
#define IMAGETABLEVIEWDEMOWIDGET_H
#include <QWidget>
class QTableWidget;
class ImageTableViewDemoWidget : public QWidget {
Q_OBJECT
public:
ImageTableViewDemoWidget( QWidget* parent = 0 );
~ImageTableViewDemoWidget();
private slots:
void onLinkActivated( const QString& lnk );
private:
QTableWidget* m_table;
};
#endif // IMAGETABLEVIEWDEMOWIDGET_H
А теперь часть реализации imagetableviewdemowidget.cpp
:
#include "imagetableviewdemowidget.h"
#include <QTableWidget>
#include <QBoxLayout>
#include <QHeaderView>
#include <QLabel>
#include <QFileDialog>
static const QStringList COLUMN_LABELS = QStringList() << "Image Name" << "Image";
static const int IMAGE_VMARGIN = 10;
ImageTableViewDemoWidget::ImageTableViewDemoWidget( QWidget* parent )
: QWidget( parent ) {
QBoxLayout* layout = new QVBoxLayout;
layout->addWidget( m_table = new QTableWidget );
m_table->setColumnCount( COLUMN_LABELS.size() );
m_table->setHorizontalHeaderLabels( COLUMN_LABELS );
m_table->setFocusPolicy( Qt::NoFocus );
m_table->setSelectionBehavior( QAbstractItemView::SelectRows );
m_table->horizontalHeader()->setStretchLastSection( true );
QLabel* lbl = new QLabel( "<a href='#load'>Load Image…</a>" );
connect( lbl, SIGNAL( linkActivated( QString ) ), SLOT( onLinkActivated( QString ) ) );
lbl->setAlignment( Qt::AlignRight );
layout->addWidget( lbl );
setLayout( layout );
}
ImageTableViewDemoWidget::~ImageTableViewDemoWidget() {
}
void ImageTableViewDemoWidget::onLinkActivated( const QString& lnk ) {
// До этой функции скоро дойдем…
}
Наша таблица будет включать два столбца: имя файла и изображение. Добавление изображения будет происходить после нажатия на гиперссылку Load Image…
, размещенную под таблицей.
Переходим к основному блюду. Реализация оставленной нами функции:
Подробно о раздаче интернета с телефона на компьютер за минуту тут.
void ImageTableViewDemoWidget::onLinkActivated( const QString& lnk ) {
if( lnk == "#load" ) {
QString fileName = QFileDialog::getOpenFileName(
this,
"Load Image",
QString(),
"Images (*.jpg *.png *.bmp)"
);
QPixmap pix;
if( pix.load( fileName ) ) {
int row = m_table->rowCount();
m_table->insertRow( row );
QTableWidgetItem* item = new QTableWidgetItem( QFileInfo( fileName ).baseName() );
item->setFlags( item->flags() ^ Qt::ItemIsEditable );
m_table->setItem( row, 0, item );
item = new QTableWidgetItem;
item->setData( Qt::DecorationRole, pix );
item->setFlags( item->flags() ^ Qt::ItemIsEditable );
m_table->setItem( row, 1, item );
m_table->setRowHeight( row, pix.height() + IMAGE_VMARGIN );
}
} else {
// Unexpected
}
}
Вставка картинки происходит путем добавления элемента QTableWidgetItem
с ролью Qt::DecorationRole
. По умолчанию высота строки не подстраивается под размер изображения, поэтому приходится менять ее вручную. Обратите внимание, что для этого мы используем заготовленную константу IMAGE_VMARGIN
.
Если требуется использовать архитектуру Модель-Представление, то реализация отличается не намного. В этом случае достаточно организовать корректную обработку запроса данных Модели в перегруженной функции-члене data()
:
QVariant ImageModel::data( const QModelIndex& index, int role ) const {
if( index.isValid() && index.row() < rowCount() ) {
if( role == Qt::DecorationRole && index.column() == 1 ) {
// Возвращаем изображение для нужного ряда:
return getPixForRow( index.row() );
} else {
// …
}
}
return QVariant();
}
Замечание: Если изображение слишком большое, то оно может некорректно отображаться в ячейке таблицы. Поэтому в реальном приложении необходимо четко контролировать его размер. В таблицу лучше помещать уменьшенную копию исходной картинки - thumbnail. Достигнуть этого можно разными способами. Например, используя QTableWidgetItem
с иконкой QIcon
. В этом случае размер изображений контролируется централизовано на уровне всей таблицы.
Скачать исходники с примером использования изображений в таблицах Qt