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, он позволит и текст нарисовать

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Г

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

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

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

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 6:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 4:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 25, 2024, 1 Т.Ж.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 5:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

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