Russian Qt Forum
Март 29, 2024, 03:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1] 2 3 ... 32
1  Qt / Многопоточное программирование, процессы / Re: Программно нарисовать тень в QImage : Сентябрь 02, 2020, 15:06
Добрый день!
Подскажите, как можно программно нарисовать тень на картинках в отдельных потоках?
Есть 10к изображений, которые нужно обработать. Сейчас использую QThread + QGraphicsDropShadowEffect, но QGraphicsScene, которая нужна для отрисовки тени через QGraphicsDropShadowEffect - не thread-safety, поэтому иногда крашит приложение.
Может быть есть еще какие-нибудь варианты?
Если не хочется изобретать велосипед, то идёшь в исходники, и берёшь от туда код, отвечающий за отбрасывание тени:

Код
C++ (Qt)
void QPixmapDropShadowFilter::draw(QPainter *p,
                                  const QPointF &pos,
                                  const QPixmap &px,
                                  const QRectF &src) const
{
   Q_D(const QPixmapDropShadowFilter);
 
   if (px.isNull())
       return;
 
   QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied);
   tmp.setDevicePixelRatio(px.devicePixelRatioF());
   tmp.fill(0);
   QPainter tmpPainter(&tmp);
   tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
   tmpPainter.drawPixmap(d->offset, px);
   tmpPainter.end();
 
   // blur the alpha channel
   QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
   blurred.setDevicePixelRatio(px.devicePixelRatioF());
   blurred.fill(0);
   QPainter blurPainter(&blurred);
   qt_blurImage(&blurPainter, tmp, d->radius, false, true);
   blurPainter.end();
 
   tmp = blurred;
 
   // blacken the image...
   tmpPainter.begin(&tmp);
   tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
   tmpPainter.fillRect(tmp.rect(), d->color);
   tmpPainter.end();
 
   // draw the blurred drop shadow...
   p->drawImage(pos, tmp);
 
   // Draw the actual pixmap...
   p->drawPixmap(pos, px, src);
}
 
Вместо QPixmap используешь QImage, ибо QPixmap умеет только в GUI потоке работать.
2  Qt / Вопросы новичков / Re: ПРОСТО ПО-МО-ГИ-ТЕ! Qt Linux usb-cdc : Май 11, 2018, 08:47
Обычно все эти usb-com конверторы в линуксах как ttyUSBx определяются.
3  Qt / Общие вопросы / Re: QProcess и консольное приложение : Апрель 22, 2018, 09:17
Код
C++ (Qt)
#include <QMainWindow>
#include <QApplication>
#include <QProcess>
#include <qDebug>
 
// https://sourceforge.net/projects/sox/ - ссылка где скачал Sox - Sound eXchange
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QMainWindow w;
 
       QProcess process;
       QStringList strList;
       process.start("D://FolderSox//sox-14-4-2//sox", strList);
       process.waitForReadyRead(-1);
       QString strWrite = "track01.wav track02.wav Sometrack03.wav";
       process.write(strWrite.toLatin1());
       process.waitForBytesWritten();
       process.waitForReadyRead();
       qDebug() << "Text " << process.readAll() <<endl;
 
//    QProcess process; // Так тоже не работает
//    QStringList strList;
//        strList << "track01.wav";
//        strList << "track02.wav";
//        strList << "Sometrack03.wav";
//    process.start("D://FolderSox//sox-14-4-2//sox.exe", strList);
//    qDebug() << "Text2 " << process.exitCode() <<endl;
 
   w.show();
 
   return a.exec();
}
 

Помогите пожалуйста. Через консоль пробовал все работает.
А где твои wav файлы находятся? Попробуй указать полные пути до них.
4  Qt / Общие вопросы / Re: QProcess и консольное приложение : Март 22, 2018, 14:28
Может кто-то помочь? Почему не работает? Консольная программа (sox) должна объединить два трека, через cmd вручную проверял - работает, однако написанный код не работает.
Код
C++ (Qt)
void MainWindow::on_pushButton_begin_clicked()
{
QProcess process;
QStringList strListKey;
strListKey << "track01.wav track02.wav result.wav";
 
process.start(QDir::currentPath() + "/SoX-Sound_eXchange/sox.exe", strListKey);
process.waitForFinished(-1);
}
Мне кажется дело может быть в этом:
Код
C++ (Qt)
strListKey << "track01.wav track02.wav result.wav";
 
надо так:
Код
C++ (Qt)
strListKey << "track01.wav" << "track02.wav" << "result.wav";
 
5  Qt / Общие вопросы / Re: Как правильно записать wchar_t в бинарный файл? : Март 06, 2018, 15:00
Код:
const int iFileSize = SysStringLen( pngDATA );

Я не совсем в теме, но корректно ли длину png файла функцией SysStringLen считать?

6  Qt / Общие вопросы / Re: Падение при попытке загрузить QPixmap : Январь 27, 2018, 23:47
Transform::reloadPreview в гуишном потоке выполняется?
7  Qt / Qt-инструментарий / Re: Как убрать теневую сборку? : Декабрь 29, 2017, 11:54
мне она мешает. смысла, для себя, в ней не вижу.

интересно, а какой смысл замусоривания сборочными данными исходный код в одном каталоге ?

А зачем мусорить объектными файлами в каталоге с исходниками?

Добавляем в pro файл следующие строки, отключаем теневую сборку и радуемся:
Код:
CONFIG(debug, debug|release):{OBJECTS_DIR = $$PWD/../build/appname/debug/obj}
else:{OBJECTS_DIR = $$PWD/../build/appname/release/obj}
RCC_DIR = $$PWD/../build/appname/rcc
UI_DIR = $$PWD/../build/appname/ui
MOC_DIR = $$PWD/../build/appname/moc
DESTDIR = $$PWD/../app
8  Qt / Вопросы новичков / Re: Скорость обращения к данным : Декабрь 14, 2017, 12:34
QList быстрее не будет, так как всё равно надо по каждому элементу проходиться. Тут уже какой-либо индексации не обойтись.
9  Qt / Многопоточное программирование, процессы / Re: Как завершить поток таймера? : Декабрь 12, 2017, 17:36
последующий вызов QThread::wait() гарантирует как минимум еще одну итерацию event loop потока
wait ничего не гарантирует, даже более он сам блокирует поток в котором запущен до завершения ожидаемой нитки. В это время eventloop не крутиться.
то есть связка последовательных вызовов QThread::quit + QThread::wait не гарантирует итерации eventLoop'а? Как тогда корректно завершить поток с удалением всех его children'ов?
10  Qt / Многопоточное программирование, процессы / Re: Как завершить поток таймера? : Декабрь 12, 2017, 17:02
Здесь смущает только место использования

Код
C++ (Qt)
mWorker->deleteLater();
 

Если поток уже завершен, то event loop уже остановлена и некому выполнять deleteLater).
А так, использование Worker в разных вариациях предпочтительнее. Наследование от потока тоже корректно, здесь на вкус и цвет, кому как удобнее.
Поток останавливается ниже в деструкторе. Вызов QThread::quit и последующий вызов QThread::wait() гарантирует как минимум еще одну итерацию event loop потока, которая в свою очередь обеспечит удаление все запланированных к удалению объектов, привязанных к данному потоку.
11  Qt / Многопоточное программирование, процессы / Re: Как завершить поток таймера? : Декабрь 12, 2017, 16:20
По мне дык наследование от QThread и переопределение в нем метода run() не очень хорошая практика. Использую механизм "воркеров", как то всё прозрачней получается, и проще следить за временем жизни объектов. Вот синтетический пример:

Код
C++ (Qt)
#include <QCoreApplication>
#include <QThread>
#include <QTimer>
#include <QDebug>
 
class Worker : public QObject {
   Q_OBJECT
public:
   Worker(QObject *parent = 0) : QObject(parent), mTimer(0) {}
   ~Worker() { qDebug() << Q_FUNC_INFO; }
 
   Q_INVOKABLE void start() {
       // для того, что бы создать таймер в контексте потока, в который перемещён
       // воркер, используем QMetaObject::invokeMethod
       if (QThread::currentThread() != thread()) {
           QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
           return;
       }
       mTimer = new QTimer(this);
       connect(mTimer, &QTimer::timeout,
               this, &Worker::onTimeout);
       mTimer->start(1000);
   }
 
signals:
   void timeout();
 
private:
   void onTimeout() {
       qDebug() << "worker" << QThread::currentThreadId();
       emit timeout();
   }
 
private:
   QTimer *mTimer;
 
};
 
class Test : public QObject
{
   Q_OBJECT
public:
   Test(QObject *parent = 0) :
       QObject(parent),
   mWorker(new Worker())
   {
   connect(mWorker, &Worker::timeout,
           this, &Test::onTimeout,
           Qt::QueuedConnection);
   }
   ~Test()
   {
       // планируем удаление воркера
       mWorker->deleteLater();
       if (mThread.isRunning()) {
           // рубим поток
           mThread.quit();
           // даём время уничтожится воркеру
           mThread.wait();
       }
       qDebug() << Q_FUNC_INFO;
   }
 
   void start() {
       // перемещаем воркер в отдельный поток
       mWorker->moveToThread(&mThread);
       // стратуем поток
       mThread.start();
       // и воркер
       mWorker->start();
       // планируем через 5 секунд выход из тестового приложения
       QTimer::singleShot(5000, this, &Test::onQuitTimeout);
   }
 
 
   void onTimeout() {
       qDebug() << "test" << QThread::currentThreadId();
   }
 
   void onQuitTimeout() {
       qApp->quit();
   }
 
private:
   QThread mThread;
   Worker *mWorker;
 
};
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   Test t;
   t.start();
 
   return a.exec();
}
 
#include "main.moc"
 
 
12  Qt / Вопросы новичков / Re: Параллельное заполнение одномерного массива : Декабрь 10, 2017, 03:37
  Доброго времени суток. Начинаю изучение параллельного программирования. Хотелось бы узнать как, к примеру, можно распараллелить заполнение одномерного массива, допустим случайными числами. При помощи QThread или QtConcurrent. Буду рад любому примеру.
Для поставленной задачи всё просто - делишь массив на кол-во блоков, равному количеству потоков, и в каждом потоке независимо заполняешь нужный блок. Примерно так:

Код
C++ (Qt)
#include <QCoreApplication>
 
#include <QDebug>
#include <QVector>
#include <QtConcurrent>
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QVector<int> vector;
   // Для примера массив 10 миллионов значений
   vector.resize(10000000);
   QList<QFuture<void>> results;
   for (int i = 0; i < 10; ++i) {
       // Получаем указатель на нужный блок
       int *data = vector.data() + i * 1000000;
       // запускаем в отдельных потоках заполнялку, указываем лямбде адрес начала блока и его длинну
       auto result = QtConcurrent::run([i](int *data, const size_t size) {
           for (int i = 0; i < size; ++i) {
               *(data++) = qrand();
           }
           // для отладки выводим на экран номер заполненного блока
           qDebug() << i;
       }, data, 1000000);
       // нужно для ожидания окончания заполнения массива
       results.append(result);
   }
 
   // ждем завершение заполнения массива
   for (auto &f : results) {
       f.waitForFinished();
   }
 
   qDebug() << "end";
 
   return 0;
}
 
 
13  Qt / Общие вопросы / Re: Отправка через QueuedConnection вектора умных указателей : Июнь 24, 2017, 21:32
То не собирается, выдаёт ошибки из qmetatype.h и qtypeinfo.h о том, что к этому франкенштейну и sizeof не применить, и тип его неполный.
Такое может быть из-за того, что тайпдеф до объявления Tester делается.
14  Qt / Вопросы новичков / Re: Закрыть редактирование QItemDelegate по событию : Февраль 21, 2017, 14:13
смотри в сторону сигнала void QAbstractItemDelegate::commitData(QWidget *editor)
15  Qt / Общие вопросы / Re: Выполнение функций с правами root : Декабрь 15, 2016, 18:43
Вот тут есть неплохое описание, как разрешить доступ к ресурсам не только для root'а.
Где?
Думал ссылку вставил, сорри. Исправляюсь, ибо как говориться - лучше поздно, чем никогда. Не очень коротко про udev
Страниц: [1] 2 3 ... 32

Страница сгенерирована за 0.284 секунд. Запросов: 23.