Файл менеджерінен суреттерді біздің қолданбаның өзіне апарып тастау үшін Сүйреп апару әдісін қолдануға мүмкіндік беретін шағын қолданбаны жазайық. Осы арқылы қолданбада кескінді қарау терезесі және біздің қолданбамызда орналастырған барлық кескіндердің тізімі болады. Бұл жағдайда тізімдегі суретті басқан кезде біз басқан сурет негізгі қарау аймағында орналасады. Бұл тізімде әрбір элемент үшін мәтінсіз алдын ала қарау кескіні жасалады. Мұндай алдын ала қарау QStyledDelegate. ішінен мұраланған делегат арқылы жасалады.
Қолданба келесідей болады:
Жоба құрылымы
- DropEvent.pro - жоба профилі;
- main.cpp - негізгі функциясы бар файл;
- widget.h - қолданба терезесінің тақырып файлы;
- widget.cpp - қолданбаның бастапқы код файлы;
- imagedelegate.h - тізім элементі делегатының тақырып файлы;
- Imagedelegate.cpp - тізім элементінің делегатының бастапқы код файлы.
Бұл жобадағы делегат кескіндердің астындағы мәтінді жою үшін қажет. Мәселе мынада: QListView және QStandardItemModel кескінді алдын ала қарауды көрсету үшін пайдаланылады, олардың мәтінсіз белгішелерді көрсету функциясы жоқ. Бірақ тізім элементінің көрінісін көрсетуді толығымен қайта анықтай отырып, делегаттың көмегімен мәтінді жоюға болады.
Мен DropEvent.pro және main.cpp файлдарының бастапқы кодын бермеймін, себебі жобаны жасау кезінде әдепкі бойынша жасалған бағдарлама коды бар.
виджет.h
Қолданба терезесінің тақырып файлында біз Drag және Drop оқиғаларының әдістерін қайта анықтаймыз, сонымен қатар интерфейс пен кескіндер үшін деректер үлгісін қалыптастыру үшін нысандарды қосамыз.
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPalette> #include <QDragEnterEvent> #include <QMimeData> #include <QDropEvent> #include <QScrollArea> #include <QLabel> #include <QListView> #include <QGridLayout> #include <QStandardItemModel> class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); // Метод события перетаскивания virtual void dragEnterEvent(QDragEnterEvent* event) override; // Метод события отпускания объекта с данными virtual void dropEvent(QDropEvent *event) override; private slots: // Слот для обработки кликов по элементам списка void onImagesListViewClicked(const QModelIndex& index); private: QScrollArea* m_scrollArea; // Область скроллинга изображения QLabel* m_imageLabel; // Лейбл для отображения картинок QListView* m_imagesListView; // Список с изображениями QGridLayout* m_gridLayout; // Сетка для интерфейса QStandardItemModel* m_imagesModel; // Модель данных с изображениями }; #endif // WIDGET_H
widget.cpp
QStandardItemModel кескіндері бар тізімді қалыптастыру үшін пайдаланылады, ал QListView үлгі элементтерін көрсету үшін пайдаланылады. Тізімдегі элементтерді теңшеу үшін Өкіл пайдаланылады, себебі тек сыртқы көріністі көрсетуді қайта анықтау арқылы мәтінді жоюға болады. Айтпақшы, бұл мәтінде QPixmap жасау және суретті негізгі көріністе де, алдын ала қарау түрінде де көрсету үшін пайдаланылатын кескін файлына жол бар. Деректер үлгісінен файл жолын алу үшін data(), әдісін пайдалану керек және QModellndex және enum Qt::DisplayRole өту керек, ол әдепкі аргумент болып табылады. аргументтер.
#include "widget.h" #include "ui_widget.h" #include <QStandardItem> #include "imagedelegate.h" Widget::Widget(QWidget *parent) : QWidget(parent) { setAcceptDrops(true); // разрешаем события отпускания объектов данных setMinimumWidth(640); setMinimumHeight(480); /// Настраиваем интерфейс m_gridLayout = new QGridLayout(this); m_imagesListView = new QListView(this); // Создадим модель данных для списка изображений m_imagesModel = new QStandardItemModel(m_imagesListView); m_imagesListView->setModel(m_imagesModel); // Установим модель во вьюшку для превью изображений m_imagesListView->setFixedWidth(200); // Без делегата не удастся избавиться от текста в элементе списка и настроить отображение превью m_imagesListView->setItemDelegate(new ImageDelegate(m_imagesModel, m_imagesListView)); // Настраиваем область скроллинга для текущего изображения m_scrollArea = new QScrollArea(this); m_scrollArea->setBackgroundRole(QPalette::Dark); m_imageLabel = new QLabel(this); m_scrollArea->setWidget(m_imageLabel); m_gridLayout->addWidget(m_scrollArea, 0, 0); m_gridLayout->addWidget(m_imagesListView, 0, 1); connect(m_imagesListView, &QListView::clicked, this, &Widget::onImagesListViewClicked); } Widget::~Widget() { } void Widget::dragEnterEvent(QDragEnterEvent *event) { // Обязательно необходимо допустить событие переноса данных в область окна приложения event->accept(); } void Widget::dropEvent(QDropEvent *event) { // Когда отпускаем файл в область приложения, // то забираем путь к файлу из MIME данных QString filePath = event->mimeData()->urls()[0].toLocalFile(); // Создаём изображение QPixmap pixmap(filePath); // Помещаем его в область скроллинга через QLabel m_imageLabel->setPixmap(pixmap); m_imageLabel->resize(pixmap.size()); // Добавляем элемент в список m_imagesModel->appendRow(new QStandardItem(QIcon(pixmap), filePath)); } void Widget::onImagesListViewClicked(const QModelIndex &index) { // Когда кликаем по элементу в списке, то забираем путь к файлу QPixmap pixmap(m_imagesModel->data(index).toString()); // И устанавливаем файл в область основного просмотра m_imageLabel->setPixmap(pixmap); m_imageLabel->resize(pixmap.size()); }
imagedelegate.h
Міне, делегаттың өзі, оның міндеті тізімдегі элементті көрсету. Кескін файлына жолды алу үшін мен деректер үлгісіне көрсеткішті бердім және бояу әдісіндегі QModelIndex арқылы кескінге жолды аламын.
Тағы бір маңызды сәт - тізімдегі элемент өлшемін реттейтін sizeHint(). әдісін пайдалану. Егер сіз ондағы өлшемді түзетуді жасамасаңыз, онда элемент өлшемі биіктігі бойынша әдеттегі мәтін жолына тең болады. Алдын ала қарау мүлдем қорқынышты болады.
#ifndef IMAGEDELEGATE_H #define IMAGEDELEGATE_H #include <QStyledItemDelegate> #include <QPainter> #include <QStyleOptionViewItem> #include <QModelIndex> #include <QStandardItemModel> #include <QPixmap> #include <QDebug> class ImageDelegate : public QStyledItemDelegate { public: explicit ImageDelegate(QStandardItemModel *model, QObject *parent = nullptr); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; QStandardItemModel* m_model; }; #endif // IMAGEDELEGATE_H
Imagedelegate.cpp
Тағы бір маңызды сәт QStyleOptionViewItem ішінен QRect пайдалану болып табылады. Шындығында, онда элементтің биіктігі мен енін ғана емес, сонымен қатар оның тізімдегі x және y орнын да қамтиды. Егер сіз бұл координаттарды есепке алмасаңыз, онда барлық элементтер бір жерде сызылатынын көруге болады. Мысалы, тізімнің жоғарғы сол жақ бұрышында сурет салу кезінде x = 0 және y = 0 мәнін орнатсаңыз.
#include "imagedelegate.h" ImageDelegate::ImageDelegate(QStandardItemModel *model, QObject *parent) : QStyledItemDelegate(parent), m_model(model) { } void ImageDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { // Вместо отрисовки иконки и текста будем отрисовывать только одно изображение // с небольшими отступами в 5 пикселей QPixmap pix(m_model->data(index).toString()); QRect optionRect = option.rect; painter->drawPixmap(optionRect.x() + 5, optionRect.y() + 5, optionRect.width() - 10, optionRect.height() - 10 , pix); } QSize ImageDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { // Корректируем размеры области отображения объекта в списке QSize result = QStyledItemDelegate::sizeHint(option, index); result.setHeight(140); result.setWidth(140); return QSize(140, 140); }
А можно сразу передовать Qpixmap?
Нет, нужно сконвертировать информацию в удобоваримый mime type
Доброго времени суток.
А если нужно и изображение и текст?
Что-то потерялся немного....
// Вместо отрисовки иконки и текста будем отрисовывать только одно изображение
// с небольшими отступами в 5 пикселей
QPixmap pix(m_model->data(index).toString());
Добрый день. Посмотрите описание методов drawText у QPainter, он позволит и текст нарисовать