Evgenii Legotckoi
Evgenii LegotckoiНаурыз 30, 2017, 1:47 Т.Қ.

Qt/C++ - 061-сабақ. Файл менеджерінен апарып тастау арқылы қолданбаға кескіндерді қосу

Файл менеджерінен суреттерді біздің қолданбаның өзіне апарып тастау үшін Сүйреп апару әдісін қолдануға мүмкіндік беретін шағын қолданбаны жазайық. Осы арқылы қолданбада кескінді қарау терезесі және біздің қолданбамызда орналастырған барлық кескіндердің тізімі болады. Бұл жағдайда тізімдегі суретті басқан кезде біз басқан сурет негізгі қарау аймағында орналасады. Бұл тізімде әрбір элемент үшін мәтінсіз алдын ала қарау кескіні жасалады. Мұндай алдын ала қарау 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);
}

Қолданбаларды сүйреп апару жобасы

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Юрий
  • Қаң. 20, 2021, 1:34 Т.Қ.

// Вместо отрисовки иконки и текста будем отрисовывать только одно изображение
// с небольшими отступами в 5 пикселей
QPixmap pix(m_model->data(index).toString());

А можно сразу передовать Qpixmap?

Evgenii Legotckoi
  • Шілде 2, 2021, 7:45 Т.Ж.

Нет, нужно сконвертировать информацию в удобоваримый mime type

Ruslan Polupan
  • Там. 11, 2022, 3:37 Т.Ж.

Доброго времени суток.
А если нужно и изображение и текст?
Что-то потерялся немного....

// Вместо отрисовки иконки и текста будем отрисовывать только одно изображение
// с небольшими отступами в 5 пикселей
QPixmap pix(m_model->data(index).toString());

Evgenii Legotckoi
  • Там. 24, 2022, 7:32 Т.Ж.

Добрый день. Посмотрите описание методов drawText у QPainter, он позволит и текст нарисовать

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
OI
  • Ora Iro
  • Жел. 24, 2024, 6:38 Т.Ж.

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:40ұпай,
  • Бағалау ұпайлары-8
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
Соңғы пікірлер
ИМ
Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectМаусым 4, 2022, 3:49 Т.Ж.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз