© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB

Qt/C++ - Урок 029. Изображение в базе данных в Qt – Сохранение и Восстановление

BLOB, QPixmap, Qt, SQL, SQLite, база данных, изображение

Изображение в базе данных может быть сохранено в формате BLOB (англ. Binary Large Object - двоичный большой объект), то есть в формате массива двоичных данных. Формат BLOB также подходит для сохранения аудио и видео данных в базах данных.

Рассмотрим сохранение и восстановление изображения из базы данных на примере следующего приложения, в котором скриншот с экрана компьютера будет сохраняться в базе данных и выводиться в специальный QLabel , когда соответствующая запись будет выбрана в QTableView , который будет отображать все записи об изображения, хранящихся в базе данных.

Таким образом имеем таблицу в базе данных со следующими полями:

  • id (INTEGER) - id записи;
  • Name (VARCHAR(255)) - название хранящегося в базе данных файла;
  • Pic (BLOB) - поле для хранения изображений в базе данных.

Если не вдаваться подробно в урок, то самая ценная информация по данной теме в конце файла mainwindow.cpp в следующих методах:

  • MainWindow::on_screenButton_clicked()
  • MainWindow::slotCurrentPic(QModelIndex index)

Структура проекта

  • PicDataBase .pro - профайл проекта;
  • database.h - заголовочный файл бессменного класса обёртки для работы с базой данных;
  • database.cpp - файл исходных кодов класса-обёртки для работы с базой данных;
  • mainwindow.h - заголовочный файл основного окна приложения;
  • mainwindow.cpp -файл исходных кодов основного окна приложения;
  • mainwindow.ui - форма главного окна приложения;
  • main.cpp - основной файл исходных кодов приложения.

mainwindow.ui

В дизайнере  набрасываем следующую форму окна приложения.

PicDataBase.pro

В профайле приложения в обязательном порядке подключаем модуль sql для работы с базами данных.

main.cpp

Файл создан по умолчанию и не подвергается изменениям.

database.h

Для работы с базой данных использую уже привычный класс-обёртку DataBase .

ВНИМАНИЕ!!! - файл базы данных создается в папке C:/example , поэтому или поправьте метод DataBase::connectToDataBase() или создайте папку example на диске C .

#ifndef DATABASE_H
#define DATABASE_H

#include <QObject>
#include <QSql>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QFile>
#include <QDate>
#include <QDebug>

/* Директивы имен таблицы, полей таблицы и базы данных */
#define DATABASE_HOSTNAME   "ScreenDataBase"
#define DATABASE_NAME       "Screen.db"

#define TABLE                   "ScreenTable"       // Название таблицы
#define TABLE_NAME              "Name"              // Вторая колонка
#define TABLE_PIC               "Pic"               // Третья колонка

// Первая колонка содержит Autoincrement ID

class DataBase : public QObject
{
    Q_OBJECT
public:
    explicit DataBase(QObject *parent = 0);
    ~DataBase();
    /* Методы для непосредственной работы с классом
     * Подключение к базе данных и вставка записей в таблицу
     * */
    void connectToDataBase();

private:
    // Сам объект базы данных, с которым будет производиться работа
    QSqlDatabase    db;

private:
    /* Внутренние методы для работы с базой данных
     * */
    bool openDataBase();        // Открытие базы данных
    bool restoreDataBase();     // Восстановление базы данных
    void closeDataBase();       // Закрытие базы данных
    bool createTable();         // Создание таблицы в базе данных

public slots:
    bool insertIntoTable(const QVariantList &data);      // Добавление записей в таблицу
    bool insertIntoTable(const QString &name, const QByteArray &pic);
};

#endif // DATABASE_H

database.cpp

#include "database.h"

DataBase::DataBase(QObject *parent) : QObject(parent)
{

}

DataBase::~DataBase()
{

}

/* Методы для подключения к базе данных
 * */
void DataBase::connectToDataBase()
{
    /* Перед подключением к базе данных производим проверку на её существование.
     * В зависимости от результата производим открытие базы данных или её восстановление
     * */
    if(!QFile("C:/example/" DATABASE_NAME).exists()){
        this->restoreDataBase();
    } else {
        this->openDataBase();
    }
}

/* Методы восстановления базы данных
 * */
bool DataBase::restoreDataBase()
{
    // Если база данных открылась ...
    if(this->openDataBase()){
        // Производим восстановление базы данных
        return (this->createTable()) ? true : false;
    } else {
        qDebug() << "Не удалось восстановить базу данных";
        return false;
    }
    return false;
}

/* Метод для открытия базы данных
 * */
bool DataBase::openDataBase()
{
    /* База данных открывается по заданному пути
     * и имени базы данных, если она существует
     * */
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setHostName(DATABASE_HOSTNAME);
    db.setDatabaseName("C:/example/" DATABASE_NAME);
    if(db.open()){
        return true;
    } else {
        return false;
    }
}

/* Методы закрытия базы данных
 * */
void DataBase::closeDataBase()
{
    db.close();
}

/* Метод для создания таблицы в базе данных
 * */
bool DataBase::createTable()
{
    /* В данном случае используется формирование сырого SQL-запроса
     * с последующим его выполнением.
     * */
    QSqlQuery query;
    if(!query.exec( "CREATE TABLE " TABLE " ("
                            "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                            TABLE_NAME     " VARCHAR(255)    NOT NULL,"
                            TABLE_PIC      " BLOB            NOT NULL"
                        " )"
                    )){
        qDebug() << "DataBase: error of create " << TABLE;
        qDebug() << query.lastError().text();
        return false;
    } else {
        return true;
    }
    return false;
}

/* Метод для вставки записи в базу данных
 * */
bool DataBase::insertIntoTable(const QVariantList &data)
{
    /* Запрос SQL формируется из QVariantList,
     * в который передаются данные для вставки в таблицу.
     * */
    QSqlQuery query;
    /* В начале SQL запрос формируется с ключами,
     * которые потом связываются методом bindValue
     * для подстановки данных из QVariantList
     * */
    query.prepare("INSERT INTO " TABLE " ( " TABLE_NAME ", "
                                             TABLE_PIC " ) "
                  "VALUES (:Name, :Pic)");
    query.bindValue(":Name",        data[0].toString());
    query.bindValue(":Pic",         data[1].toByteArray());

    // После чего выполняется запросом методом exec()
    if(!query.exec()){
        qDebug() << "error insert into " << TABLE;
        qDebug() << query.lastError().text();
        return false;
    } else {
        return true;
    }
    return false;
}

/* Второй метод для вставки записи в базу данных
 * */
bool DataBase::insertIntoTable(const QString &name, const QByteArray &pic)
{
    QVariantList data;
    data.append(name);
    data.append(pic);

    if(insertIntoTable(data))
        return true;
    else
        return false;
}

mainwindow.h

Помимо привычных объектов DataBase и QSqlTableModel , а также методов настройки модели и представления, которые использовались в предыдущих статьях по QSqlRelationalTableModel и QSqlQueryModel , в данном файле присутствуют слоты для обработки нажатия по кнопке и клику по записи в таблице.

Первый слот выполняет создание скриншота экрана и добавление его в базу данных, а второй слот восстанавливает изображение из базы данных, беря его из объекта QSqlTableModel в QTableView и помещая его в QLabel в главном окне приложения.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSqlTableModel>
#include <QModelIndex>

#include "database.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    // Слот для записи скриншота в базу данных
    void on_screenButton_clicked();
    // Слот для получения изображения из базы данных
    void slotCurrentPic(QModelIndex index);

private:
    Ui::MainWindow *ui;
    /* В проекте используются объекты для взаимодействия с информацией в базе данных
     * и моделью представления таблицы базы данных
     * */
    DataBase        *db;
    QSqlTableModel  *model;

private:
    /* Также присутствуют два метода, которые формируют модель
     * и внешний вид TableView
     * */
    void setupModel(const QString &tableName, const QStringList &headers);
    void createUI();
};

#endif // MAINWINDOW_H

mainwindow.cpp

Вся главная работа с базой данных и изображением производится в следующих методах:

  • MainWindow::on_screenButton_clicked()
  • MainWindow::slotCurrentPic(QModelIndex index)
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QApplication>
#include <QBuffer>
#include <QScreen>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    db = new DataBase();
    db->connectToDataBase();

    this->setupModel(TABLE,
                     QStringList() << trUtf8("id")
                                   << trUtf8("Имя изображения")
                                   << trUtf8("изображение")
                     );

    this->createUI();
}

MainWindow::~MainWindow()
{
    delete ui;
}

/* Метод для инициализации модеи представления данных
 * */
void MainWindow::setupModel(const QString &tableName, const QStringList &headers)
{
    /* Производим инициализацию модели представления данных
     * с установкой имени таблицы в базе данных, по которому
     * будет производится обращение в таблице
     * */
    model = new QSqlTableModel(this);
    model->setTable(tableName);

    /* Устанавливаем названия колонок в таблице с сортировкой данных
     * */
    for(int i = 0, j = 0; i < model->columnCount(); i++, j++){
        model->setHeaderData(i,Qt::Horizontal,headers[j]);
    }
}

void MainWindow::createUI()
{
    ui->tableView->setModel(model);     // Устанавливаем модель на TableView
    ui->tableView->setColumnHidden(0, true);    // Скрываем колонку с id записей
    ui->tableView->setColumnHidden(2, true);    // Скрываем колонку с изображением
    // Разрешаем выделение строк
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    // Устанавливаем режим выделения лишь одной строки в таблице
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    // Устанавливаем размер колонок по содержимому
    ui->tableView->resizeColumnsToContents();
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);  // Запрещаем редактирование
    ui->tableView->horizontalHeader()->setStretchLastSection(true);     // Растягиваем последнюю колонку по всему tableView

    /* Подключаем сигнал об изменении выбора текущей строки в таблицу
     * к СЛОТу для установки изображения в picLabel
     * */
    connect(ui->tableView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
            this, SLOT(slotCurrentPic(QModelIndex)));

    model->select(); // Делаем выборку данных из таблицы
}

void MainWindow::on_screenButton_clicked()
{
    /* Делаем скриншот экрана и сохраняем его в объект QByteArray,
     * для этого ...
     * */
    QScreen *screen = QApplication::primaryScreen();    // Берём объект экрана
    QPixmap inPixmap = screen->grabWindow( 0 );         // Сохраняем его в изображение объекта QPixmap
    QByteArray inByteArray;                             // Создаём объект QByteArray для сохранения изображения
    QBuffer inBuffer( &inByteArray );                   // Сохранение изображения производим через буффер
    inBuffer.open( QIODevice::WriteOnly );              // Открываем буффер
    inPixmap.save( &inBuffer, "PNG" );                  // Записываем inPixmap в inByteArray

    // Записываем скриншот в базу данных
    db->insertIntoTable(QDateTime::currentDateTime().toString("dd.MM.yyyy_hh:mm:ss.png"), inByteArray);

    // Делаем выборку таблицы из Базы Данных
    model->select();
}

void MainWindow::slotCurrentPic(QModelIndex index)
{
    QPixmap outPixmap = QPixmap(); // Создаём QPixmap, который будет помещаться в picLabel
    /* Забираем данные об изображении из таблицы в качестве QByteArray
     * и помещаем их в QPixmap
     * */
    outPixmap.loadFromData(model->data(model->index(index.row(), 2)).toByteArray());
    // Устанавливаем изображение в picLabel
    ui->picLabel->setPixmap(outPixmap.scaled(400,300));
}

Итог

В результате получаем приложение, которое позволяет сохранять скриншоты экрана в базе данных и восстанавливать данное изображение, отображая его в QLabel окна приложения. Также комментарии по работе приложения Вы можете услышать в видеоуроке.

Видеоурок

Комментарии

20 мая 2017 г. 21:46

Здравствуйте, при сборке выдаёт две такие ошибки C:\untitled1\mainwindow.cpp:99: ошибка: C2039: picLabel: ­Ґ пў«пҐвбп з«Ґ­®¬ "Ui::MainWindow" C:\untitled1\mainwindow.cpp:99: ошибка: C2227: ўла ¦Ґ­ЁҐ б«Ґў  ®в "->setPixmap" ¤®«¦­® гЄ §лў вм ­  вЁЇ Є« бб , бвагЄвгал Ё«Ё ®ЎкҐ¤Ё­Ґ­Ёп «ЁЎ® ­  г­ЁўҐаб «м­л© вЁЇ Как это исправить, помогите пожалуйста

20 мая 2017 г. 21:53

И ещё не могли бы подсказать что нужно изменить в коде чтобы по нажатию на кнопку в БД загружался не скриншот, а выбранные и уже существующие изображения?
Заранее спасибо!

21 мая 2017 г. 3:54

Интерфейс приложения сделать через графический дизайнер так, как сделано в данной статье. Убедиться, что существует QLabel в интерфейсе, с таким же названием, как в этой статье.

Для Django рекомендую VDS-хостинг TIMEWEB

21 мая 2017 г. 3:57

Создать QPixmap из файла, указав путь к файлу.

QPixmap pixmap("/path/to/file.png");

Для Django рекомендую VDS-хостинг TIMEWEB

21 мая 2017 г. 10:46

Спасибо большое! Но если я правильно понял, то для каждого файла нужно будет описывать каждый раз путь? А можно сделать как-то так чтобы можно было выбирать их?

21 мая 2017 г. 16:34

Используйте QFileDialog класс. У него есть статические методы, которые позволяют открыть диалог, в котором можно выбрать либо один файл, либо несколько файлов.

Например, чтобы забрать имя одного файла:

QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                "/home",
                                                tr("Images (*.png *.xpm *.jpg)"));

Или нескольких файлов:

QStringList files = QFileDialog::getOpenFileNames(
                        this,
                        "Select one or more files to open",
                        "/home",
                        "Images (*.png *.xpm *.jpg)");

Ну и закидываете это всё в QPixmap, ну а дальше уже как по накатанной.

Для Django рекомендую VDS-хостинг TIMEWEB

21 мая 2017 г. 22:33
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "/home", tr("Images (*.png *.xpm *.jpg)")); 
QPixmap inixmap = fileName; // Сохраняем его в изображение объекта QPixmap; 
QByteArray inByteArray; // Создаём объект QByteArray для сохранения изображения QBuffer 
inBuffer( &inByteArray ); 
inBuffer.open( QIODevice::WriteOnly ); // Открываем буффер 
inixmap.save( &inBuffer, "*.png *.xpm *.jpg" ); 
db->insertIntoTable(QDateTime::currentDateTime().toString("DSC02442.png"), inByteArray); 
model->select();

Так не верно?

23 мая 2017 г. 6:19

Нет. не верно. Ошибка вот в этой строке:

QPixmap inixmap = fileName; // Сохраняем его в изображение объекта QPixmap; 

Выше я показывал, как что нужно путь передавать в качестве аргумента

QPixmap pixmap("/path/to/file.png");

То есть

QPixmap inixmap(fileName);

Для Django рекомендую VDS-хостинг TIMEWEB

21 января 2018 г. 19:29

Здравствуйте, также реализовывал приложение и понадобилось сохранить картинку. Но я брал напрямую через буфер

QPixmap pix(clipboard->pixmap());

            QBuffer inBuffer( &picture);
            inBuffer.open( QIODevice::WriteOnly );
            pix.save( &inBuffer, "PNG" );

Picture имеет тип QByteArray как и у Вас. При проверке наличии данных через консоль
qDebug() << "Здесь картинка из буфера:" << picture;
Содержимое отображается


Но при вставке данных в таблицу возникает ошибка

QSqlError("1", "Unable to execute statement", "unrecognized token: \"\u001A\"")


qDebug() << "That's pictire in binary code" <<picture;
str = "Insert into commands_" + profile_name +" (name, seq, pic) values (" + name + "," + content + ", " +picture+" );";
qDebug() << str;
if (query.exec(str))
{
qDebug() << "OK";
}

В таблице создано 1 поле для картинки qr = "CREATE TABLE commands_" +p[1] + " (name text NOT NULL, seq text NOT NULL, pic BLOB NOT NULL);";
21 января 2018 г. 19:31

также вот вывод  текста самого запроса

"Insert into commands_one (name, seq, pic) values ('bnbvn','\n1. bvnb\n2. bvnb', �PNG\r\n\u001A\n );"

21 января 2018 г. 19:32

Перед этим приложение работало отлично, ошибка связана именно с добавлением данного поля

21 января 2018 г. 20:42

Добрый день!
Подготовьте изображение к вставке в базу данных через bind, как сделано в методе insertIntoTable, в данном примере.
Больше похоже на то, что вылетает неожиданный символа при попытке вставки в базу данных, bind может нивелировать эту проблему.

Для Django рекомендую VDS-хостинг TIMEWEB

22 февраля 2018 г. 16:42

Hi, could you please show how to delete file from image Blob?  also if the same image exist in Blob then don't over write..

22 февраля 2018 г. 22:22

Hello.

You can use QSqlQuery for delete record with blob image. But you need know id of this record.

For example
bool DataBase::removeRecord(const int id)
{
    QSqlQuery query;
    query.prepare("DELETE FROM " TABLE " WHERE id= :ID ;");
    query.bindValue(":ID", id);
    if(!query.exec()){
        qDebug() << "error delete row " << TABLE;
        qDebug() << query.lastError().text();
        return false;
    } else {
        return true;
    }
    return false;
}
For check of existing row you can use select sql request in QSqlQuery

Для Django рекомендую VDS-хостинг TIMEWEB

26 февраля 2018 г. 0:55

thanks, but Id should be the same the one as i select the image in tree view.

26 февраля 2018 г. 7:13

Yes. But, if you use QSqlTableModel for TreeView, that you have id of image, I think. Or You should create hidden column with Id of image.

Для Django рекомендую VDS-хостинг TIMEWEB

26 февраля 2018 г. 9:42

Thanks, It would be really kool, if you fix the code, i am trying but as i am new i dont understand.

my problem is:  i want to delete the selected image from tree view.  and second problem is, i want to add an image, if that image is already exists. it should not shows into data base also not appear into tree view .. here are the files https://drive.google.com/file/d/1z7GG48GYkk4A3lsDKF9P6OqxHQ5ye_Fb/view
26 февраля 2018 г. 10:08

I will see to these sources, but i have a little free time during the week usually. I will not promise anything.

Для Django рекомендую VDS-хостинг TIMEWEB

26 февраля 2018 г. 12:09

Thanks, i will be very glad :)  no problem take your time.

2 марта 2018 г. 13:29

Hello Evileg if you could please make it in this weekend, i would be very glad :)

3 марта 2018 г. 11:45

You have model for Picture List and you use id in first column. It means, you can use this model for getting ID of this picture.

model->data(model->index(selectedRow, 0)).toInt();
You need just to get this selectedRow , when you click in the table, this table can to invoke signal clicked(const QModelIndex & index ). You can get row from index. Via index.row()

Для Django рекомендую VDS-хостинг TIMEWEB

5 марта 2018 г. 12:02

Thanks for the help, but i still dont get that. i tried to complie it but i got errors. i want to share you my project file once again. here is my Email: soz7557@thi.de due to  privacy if you please send me msg i will send you the files on email. Thanks

5 марта 2018 г. 14:39

Here i upload my code : https://stackoverflow.com/questions/49112880/qtableview-delete-selected-file-from-sql-database

5 марта 2018 г. 20:55

1) You need create variable for storing of ID in MainWindow

int m_selectedId {0};
2) store this variable
void MainWindow::slotCurrentPic(QModelIndex index)
{
    m_selectedId = model->data(model->index(index.row(), 0)).toInt();
}

3) Delete ID
void MainWindow::on_Delete_Button_clicked(QModelIndex index)
{
    db->removeRecord(id);
}

And please, ask your next questions on the forum

Для Django рекомендую VDS-хостинг TIMEWEB

6 марта 2018 г. 8:56

Thanks but Now i have an error again id is not decleared parameter

7 марта 2018 г. 9:58

My question is now, i am able to delete the images, but my Table view is not updating untill if dont do other function in my Gui

void MainWindow::on_Delete_Button_clicked()
{  

QMessageBox::StandardButton reply;
     reply = QMessageBox::question(this, "Delete", "Do you really want to delete?",
                                   QMessageBox::Yes|QMessageBox::No);
     if (reply == QMessageBox::Yes) {
       qDebug() << "Yes was clicked";
       QSqlRecord record;
           int i = ui->tableView->currentIndex().row(); 
           record = model->record(i);
           db->removeRecord(record.value("id").toInt(false));
           ui->tableView->reset();
        }
    else {
       qDebug() << "Yes was *not* clicked";

  }
}

 

7 марта 2018 г. 11:03

I think, you should to select one more your model.

model->select();

Для Django рекомендую VDS-хостинг TIMEWEB

20 марта 2018 г. 9:42

Hello EVILEG,  i am having new problem. with data base,  please help to solve this issue


Data Base error

QSqlDatabasePrivate::database: unable to open database: " out of memory Error opening database "

Path work directory: "AIC_tool_DB/"

QFSFileEngine::open: No file name specified

QSqlQuery::prepare: database not open

error insert info ScreenTable

"No query Unable to fetch row"

20 марта 2018 г. 21:00

Hello!

It can be anything. In fact, you missed rightly path to your database, I think.

Для Django рекомендую VDS-хостинг TIMEWEB

12 апреля 2018 г. 8:57

Hello Evileg,  i hope you are doing great.  i want to add a Search function in this data base.  i have a Lind Edit. and i want to write  22.01.2018_18:00 and it shows me that picture.   please help how will the code for that

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
24 сентября 2018 г. 17:42
edorofeeva

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

  • Результат 100баллов,
  • Очки рейтинга10
24 сентября 2018 г. 17:37
edorofeeva

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

  • Результат 66баллов,
  • Очки рейтинга-1
23 сентября 2018 г. 14:38
No Names

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

  • Результат 60баллов,
  • Очки рейтинга-1
Последние комментарии
24 сентября 2018 г. 15:09
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

А вот здесь у меня есть пример использования supervisor. https://evileg.com/ru/post/3/ Вся статья вам там не интересна, интересен только шаг с настройкой supervisor. Он получается ...
24 сентября 2018 г. 15:00
avovana

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Не могли бы дать ссылку на пример? Какое-то рабочее использование. Т.е. у меня есть Qt Gui App, которое я бы хотел запускать при старте системы и в случае, если оно грохнется. Если о чем Вы го...
24 сентября 2018 г. 14:55
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Если честно, то я не уверен, что это вообще можно реализовать через *.desktop файл. Я сделал предположение на основе того, что вы сказали про *.desktop и рестарт. Все варианты, котор...
24 сентября 2018 г. 14:47
avovana

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Просто сейчас правлю сам файл example.desktop. Пытаюсь понять какую пару key=value мне нужно дописать.
24 сентября 2018 г. 14:42
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

Ну я имел ввиду, что дописать в коде вот сюда то, о чём вы говорили про рестарт QString autorunContent("[Desktop Entry]\n" "Type=Application\n" ...
Сейчас обсуждают на форуме
24 сентября 2018 г. 16:47
Евгений_Канусовский@1981

Чтение файлов в python

Добрый вечер Евгений и форумчане! Столкнулся с проблемой чтения файлов в python: файлы с обычным текстом в формате las и txt читаются, например: ~Version information VERS.          ...
24 сентября 2018 г. 13:29
Евгений Легоцкой

Трансляция видео с помощью VLC по RTP

Добрый день! Я не сталкивался, но предположу, что нужно настроить Input Codec в VLC. В настройках есть секция Input Codec, возможно, что там установлено низкое разрешение. ...
21 сентября 2018 г. 8:25
Евгений Легоцкой

Прокси-модель, содержащая на 1 столбец больше, чем модель-источник.

Попробуйте ещё PySide 2 - это официально поддерживаемый пакет привязок Python к Qt, возможно, что там не будет таких проблем.
20 сентября 2018 г. 20:06
Евгений Легоцкой

Qt Installer Framework

Добрый день. Зачем собирать Qt Installer Framework-то из исходников? Я ещё понимаю Qt собирают из исходников статически (хотя тоже считаю по большей части бесполезной тратой времени),...
Присоединяйтесь к нам в социальных сетях