Russian Qt Forum
Апрель 18, 2024, 05:26
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Вопросы новичков
>
Стандартные потоки C++ в Qt
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Стандартные потоки C++ в Qt (Прочитано 6131 раз)
SydoQQ
Гость
Стандартные потоки C++ в Qt
«
:
Апрель 26, 2017, 12:02 »
Доброго времени суток!
Столкнулся с одной проблемой, при использовании стандартных потоков в Qt, использую версию 5.7. Нашел строку, из-за которой происходит крах программы, это строка 49. При комментировании ее, естественно программа работает на ура. И самый интересный момент, если в функию
Код:
LineItem->setPos(0,returnLinePosition());
всегда передавать константу, например вот так
Код:
LineItem->setPos(0,0);
, или
Код:
int n=100; LineItem->setPos(0,n);
, то программа тоже работает на ура. Испробовал много чего, но не могу понять, почему так происходит, надаеюсь кто то поможет мне решить данную проблему. Пробывал использовать таймер, но результат получается не такой, как хотелась бы.
Вот полный код .cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//setWindowFlags(Qt::FramelessWindowHint);
Scene=new QGraphicsScene(this);
View=new QGraphicsView(Scene);
setGeometry(300,100,400,600);
View->setParent(this);
setMaximumSize(width(),height());
View->setFixedSize(width(),height());
View->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
View->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
LineItem=Scene->addRect(QRect(-(width()/2)+1,0,width()-2,0),QPen(Qt::blue,2));
H=height();
LinePosition=600;
backGroundGradient=new QLinearGradient(QPoint(0,H),QPoint(0,0));
for(int i=0;i<3;i++)
{
FC[i]=0;
SC[i]=0;
LC[i]=0;
}
std::thread BackGroundTH{&MainWindow::on_BACKgroundChange,this};
BackGroundTH.detach();
std::thread MoveLineTH{&MainWindow::Line_Move,this};
MoveLineTH.detach();
// timer=new QTimer(this);
// connect(timer,SIGNAL(timeout()),this,SLOT(Line_Move()));
// timer->start(100);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::newPosition_line()
{
linePositionMutex.lock();
LineItem->setPos(0,returnLinePosition());
linePositionMutex.unlock();
}
void MainWindow::Line_Move()
{
//timer->stop();
int newPosition=0;
int C=1;
linePositionMutex.lock();
int n=1+qrand()%100;
for(int i=0;i<n;i++)
{
newPosition+=qrand()%(H*2);
}
linePositionMutex.unlock();
newPosition/=n;
if(LinePosition<newPosition)
C=1;
else
C=-1;
for(int i=0;i<fabs(LinePosition-newPosition);i++)
{
LinePosition+=C*1;
linePositionMutex.lock();
QThread::msleep(10);
linePositionMutex.unlock();
newPosition_line();
}
//timer->start(100);
Line_Move();
}
int MainWindow::returnLinePosition()
{
return LinePosition-(H-1);
}
void MainWindow::on_backgroundColor_change()
{
backGroundMutex.lock();
Scene->setBackgroundBrush(returnGradient());
backGroundMutex.unlock();
}
void MainWindow::on_BACKgroundChange()
{
int masF[3]={0,0,0};
int masS[3]={0,0,0};
int C=1;
srand(QTime::currentTime().toString("s").toInt());
backGroundMutex.lock();
for(int i=0;i<3;i++)
{
masF[i]=rand()%255;
masS[i]=rand()%255;
}
backGroundMutex.unlock();
for(int i=0;i<3;i++)
{
if(FC[i]<masF[i])
C=1;
else
C=-1;
for(int j=0;j<fabs(FC[i]-masF[i]);j++)
{
backGroundMutex.lock();
QThread::usleep(100000);
backGroundMutex.unlock();
FC[i]+=C*1;
backGroundGradient->setColorAt(0,QColor(SC[0],SC[1],SC[2]));
backGroundGradient->setColorAt(0.9,QColor(FC[0],FC[1],FC[2]));
on_backgroundColor_change();
}
}
for(int i=0;i<3;i++)
{
if(SC[i]<masS[i])
C=1;
else
C=-1;
for(int j=0;j<fabs(SC[i]-masS[i]);j++)
{
backGroundMutex.lock();
QThread::usleep(100000);
backGroundMutex.unlock();
SC[i]+=C*1;
backGroundGradient->setColorAt(0,QColor(SC[0],SC[1],SC[2]));
backGroundGradient->setColorAt(0.9,QColor(FC[0],FC[1],FC[2]));
on_backgroundColor_change();
}
}
on_BACKgroundChange();
}
QGradient MainWindow::returnGradient()
{
return *backGroundGradient;
}
.h файла
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <thread>
#include <mutex>
#include <QThread>
#include <QTime>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void newPosition_line();
void Line_Move();
int returnLinePosition();
void on_backgroundColor_change();
void on_BACKgroundChange();
QGradient returnGradient();
public slots:
//void Line_Move();
signals:
private:
Ui::MainWindow *ui;
QGraphicsScene *Scene;
QGraphicsView *View;
QGraphicsItem *LineItem;
int LinePosition;
int H;
int FC[3];
int SC[3];
int LC[3];
QGradient *backGroundGradient;
std::mutex backGroundMutex;
std::mutex linePositionMutex;
//QTimer *timer;
};
#endif // MAINWINDOW_H
Сообщения которое пишет отладчик
Код:
QObject::startTimer: Timers cannot be started from another thread
И я вижу что проблема с таймером, но я не понимаю откуда она возникает.
Записан
Пантер
Administrator
Джедай : наставник для всех
Offline
Сообщений: 5876
Жаждущий знаний
Re: Стандартные потоки C++ в Qt
«
Ответ #1 :
Апрель 26, 2017, 12:13 »
Ты неправильно работаешь с потоками.
1. Используй QThread
2. С GUI можно работать напрямую только из основного потока, другие потоки должны использовать сигнал/слоты.
Записан
1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
SydoQQ
Гость
Re: Стандартные потоки C++ в Qt
«
Ответ #2 :
Апрель 26, 2017, 15:28 »
Цитата: Пантер от Апрель 26, 2017, 12:13
Ты неправильно работаешь с потоками.
1. Используй QThread
2. С GUI можно работать напрямую только из основного потока, другие потоки должны использовать сигнал/слоты.
Тогда возникает вопрос, почему QGraphicsScene работает нормально, хотя тоже изменяется в потоке. И я пробывал использовать QThread, однако у меня происходило зацикливание и крах программ, может я не правильно его использовал, но я прочитал достаточно статей, и на хабре и у шлея. Не могли бы вы скинуть рабочий пример?!
Записан
gil9red
Administrator
Джедай : наставник для всех
Offline
Сообщений: 1805
Re: Стандартные потоки C++ в Qt
«
Ответ #3 :
Апрель 26, 2017, 22:20 »
QGraphicsScene это модель с данными, сама она не рисует в GUI, этим QGraphicsView занимается
Записан
https://github.com/gil9red
https://ru.stackoverflow.com/users/201445/gil9red
SydoQQ
Гость
Re: Стандартные потоки C++ в Qt
«
Ответ #4 :
Апрель 27, 2017, 06:45 »
Цитата: gil9red от Апрель 26, 2017, 22:20
QGraphicsScene это модель с данными, сама она не рисует в GUI, этим QGraphicsView занимается
Тогда не могли бы вы подсказать, в каком мне направлении копать, что бы все работало нормально?!
«
Последнее редактирование: Апрель 27, 2017, 09:10 от SydoQQ
»
Записан
gil9red
Administrator
Джедай : наставник для всех
Offline
Сообщений: 1805
Re: Стандартные потоки C++ в Qt
«
Ответ #5 :
Апрель 27, 2017, 09:08 »
Я просто ответил на вопрос
Цитировать
Тогда возникает вопрос, почему QGraphicsScene работает нормально, хотя тоже изменяется в потоке.
Записан
https://github.com/gil9red
https://ru.stackoverflow.com/users/201445/gil9red
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Стандартные потоки C++ в Qt
«
Ответ #6 :
Апрель 27, 2017, 09:44 »
Цитата: SydoQQ от Апрель 26, 2017, 15:28
Тогда возникает вопрос, почему QGraphicsScene работает нормально, хотя тоже изменяется в потоке.
Как говорят
Цитировать
Тестирование может показать наличие багов, но не их отсутствие.
Т.е. если какая-то ветка у Вас работает - это совсем не значит что проблем нет
Если исходники больше странички текста или их хотя бы 2, то прочитать/осмыслить их на форуме трудно, проще игнорировать этот топик. Выкладывайте в виде zip архива с компилируемым примером внутри
Чего искать приключений со "стандартными потоками"? С QThread возможно ответят 10 человек т.к. знают и работают с этим, а с std::thread - ну может один. И что там хорошего в std::thread?
Код:
std::thread BackGroundTH{&MainWindow::on_BACKgroundChange,this};
BackGroundTH.detach();
std::thread MoveLineTH{&MainWindow::Line_Move,this};
MoveLineTH.detach();
Так Вы запустили нитки для одноразовой работы - и теперь должны сами возюкаться как организовать их ожидание. Зачем если QThread это делает по дефаулту ?
И в любом случае святая правда что хватать UI из НЕ главной нитки - НИЗЗЯ!
Цитата: SydoQQ от Апрель 27, 2017, 06:45
Тогда не могли бы вы подсказать, в каком мне направлении копать, что бы все работало нормально?!
Перейти на QThread и задействовать слот/сигнал
Записан
SydoQQ
Гость
Re: Стандартные потоки C++ в Qt
«
Ответ #7 :
Апрель 27, 2017, 16:40 »
Цитата: Igors от Апрель 27, 2017, 09:44
Цитата: SydoQQ от Апрель 26, 2017, 15:28
Тогда возникает вопрос, почему QGraphicsScene работает нормально, хотя тоже изменяется в потоке.
Как говорят
Цитировать
Тестирование может показать наличие багов, но не их отсутствие.
Т.е. если какая-то ветка у Вас работает - это совсем не значит что проблем нет
Если исходники больше странички текста или их хотя бы 2, то прочитать/осмыслить их на форуме трудно, проще игнорировать этот топик. Выкладывайте в виде zip архива с компилируемым примером внутри
Чего искать приключений со "стандартными потоками"? С QThread возможно ответят 10 человек т.к. знают и работают с этим, а с std::thread - ну может один. И что там хорошего в std::thread?
Код:
std::thread BackGroundTH{&MainWindow::on_BACKgroundChange,this};
BackGroundTH.detach();
std::thread MoveLineTH{&MainWindow::Line_Move,this};
MoveLineTH.detach();
Так Вы запустили нитки для одноразовой работы - и теперь должны сами возюкаться как организовать их ожидание. Зачем если QThread это делает по дефаулту ?
И в любом случае святая правда что хватать UI из НЕ главной нитки - НИЗЗЯ!
Цитата: SydoQQ от Апрель 27, 2017, 06:45
Тогда не могли бы вы подсказать, в каком мне направлении копать, что бы все работало нормально?!
Перейти на QThread и задействовать слот/сигнал
Пробывал сделать как вы рекомендовали, но я не как не могу добится бесконечного цикла с использованием QThread, то ли я не правильно что то делаю, то ли у меня создается новый поток, а главный просто виснет, это первое. А второе если использовать сигнал/слоты приложение то работает, но у него нету того быстродействия которое нужно, явно видно, что приложение подвисает. Как мне решить эту проблему без потери производительности?! Возможно есть еще какие то средства которые помогу решить эту задачу?!
«
Последнее редактирование: Апрель 27, 2017, 16:45 от SydoQQ
»
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Стандартные потоки C++ в Qt
«
Ответ #8 :
Апрель 28, 2017, 12:12 »
Цитированием не злоупотребляйте, отвечаете на последнюю строку - ее и цитируйте, или вообще ничего если и так ясно о чем речь. Давайте форум не захламлять
Цитата: SydoQQ от Апрель 27, 2017, 16:40
Пробывал сделать как вы рекомендовали, но я не как не могу добится бесконечного цикла с использованием QThread, то ли я не правильно что то делаю, то ли у меня создается новый поток, а главный просто виснет, это первое. А второе если использовать сигнал/слоты приложение то работает, но у него нету того быстродействия которое нужно, явно видно, что приложение подвисает. Как мне решить эту проблему без потери производительности?! Возможно есть еще какие то средства которые помогу решить эту задачу?!
Здесь однозначно: плохо пробОвали. Напр как там можно НЕ добиться бесконечного цикла - хз. Выкладывайте Ваши попытки с QThread (с учетом сказанного выше), думаю тогда Вам быстро помогут
Записан
SydoQQ
Гость
Re: Стандартные потоки C++ в Qt
«
Ответ #9 :
Май 02, 2017, 10:46 »
Всем спасибо, кто принимал участие в обсуждении этой темы. Добился требуемого результат с использованием контекста рисования, без потери производительности, кому будет интересен код, могу скинуть. Считаю что тема может быть закрыта.
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...