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

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Указатели  (Прочитано 7523 раз)
deefox
Гость
« : Август 10, 2016, 11:09 »

Доброго времени суток.

Столкнулся с такой ситуацией. Есть главное окно MainWindow, от него выделена память на поток приема информации asio, а от потока приема еще один поток обработки информации(конкретнее отрисовка пикселей в QImage)

Еще от главного окна выделил новый класс для работы с QGrapgicsView. Суть вопроса в том, что я создал массив QImage [16] и хочу передать адрес напрямую в поток обработки, для того чтобы при отрисовки, он сразу или через некоторое время отрисовывал на экран. Создавал в MainWindow и в каждом классе делал указатели, но либо ошибки, либо крашится при запуске. подскажите как лучше сделать.

сейчас картина такая


Код:
for (int i = 0; i < 16; i++){
        viewmap->img[i] = &img[i];
        asio->imagethread->image[i] = &img[i];
    }

Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Август 10, 2016, 11:17 »

Никаких указателей, GUI должен обновляться по таймеру.
В этом обработчике таймера сделайте защищенный доступ к вашим картинкам.
Читаете данные и пакуете на GUI.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #2 : Август 10, 2016, 11:26 »

Никаких указателей, GUI должен обновляться по таймеру.
В этом обработчике таймера сделайте защищенный доступ к вашим картинкам.
Читаете данные и пакуете на GUI.


у QGraphicsView есть методы по обновлению, его использую для стыка компоновки и редактирования изображения. Не исключаю, что нужно будет и по таймеру отрисовывать. Но все делать в гуи не получится, окно повиснет просто.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Август 10, 2016, 11:29 »

А "всё" и не надо, только апдейт гуя раз 5 в секунду (чаще все равно обычно нет смысла).
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #4 : Август 10, 2016, 11:33 »

А "всё" и не надо, только апдейт гуя раз 5 в секунду (чаще все равно обычно нет смысла).


то есть вы предлагаете, не использовать отдельно класс при работе с виджетом QGraphicView, создать в гуи и единственное что,  нужно будет передать указатель в поток обработки ?

Код:
for (int i = 0; i < 16; i++){
        asio->imagethread->image[i] = &img[i];
    }

и работать непосредственно в MainWindow?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Август 10, 2016, 12:09 »

В MainWindow ничего не надо делать.
В вашем наследнике QGraphicView надо запустить таймер, а в обработчик timeout вставить код, который будет читать данные из asio->imagethread и отображать их на сцене.
Естественно, читаемые данные в imagethread должны быть защищены мьютексом.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 10, 2016, 12:18 »

С таким "емким" названием темы "суть вопроса" не ясна  Улыбающийся. Но в любом случае указатели здесь не помогают, а вредят. Здесь выгоднее прокатиться на имплисит шаре и обойтись без всяких защит. Допустим Вы получили картинку в нитке чтения - ну и пошлите ее по значению сигналом в главную, напр
Код
C++ (Qt)
void SignalSetImage( QImage img );
Главная нитка обновит UI, может спокойно удалять/менять полученный img. То же самое для посылающей. За счет шары копирование состоится только при изменении
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Август 10, 2016, 12:24 »

Допустим Вы получили картинку в нитке чтения - ну и пошлите ее по значению сигналом в главную

Так нельзя делать, от слова "вообще".
Во-первых, частота обновления картинок в нитке может быть очень высокой - в итоге поток гуя "забьется" сигналами и не справится с обработкой, в итоге зависнет наглухо.
Во-вторых, в этом случае нет никакой гарантии, что посылаемый объект не будет изменён во время "простоя" в очереди на обработку. Придётся перед отправкой сигнала делать img.detach(), т.е. deep copy, что опять же ударит по производительности.
Поэтому единственный нормальный вариант - позволить гую самому решать, когда ему обновляться. А это тока через таймер.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Август 10, 2016, 12:44 »

Во-вторых, в этом случае нет никакой гарантии, что посылаемый объект не будет изменён во время "простоя" в очереди на обработку. Придётся перед отправкой сигнала делать img.detach(), т.е. deep copy, что опять же ударит по производительности.
Давайте подробнее. Имедж послан по значению и пока где-то сохранен (QueuedConnection). Да, хранимая копия пока ссылается на те же данные пикселей что и исходный имедж. Теперь посыпающая нитка замещает имедж другим. Ну тогда-то шара и сработает, сама сделает detach, хранимая копия останется со старыми данными, оригинал получит новые, все будет исполнено атомарно. Так что гарантия есть. 

Поэтому единственный нормальный вариант - позволить гую самому решать, когда ему обновляться. А это тока через таймер.
На здоровье, обновление по таймеру не противоречит посылке картинок сигналами
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #9 : Август 10, 2016, 12:51 »

поток приема информации asio

а чего не нативный qthread ?
Записан
deefox
Гость
« Ответ #10 : Август 10, 2016, 14:10 »

поток приема информации asio

а чего не нативный qthread ?


Я его использую, просто boost asio udp крутится в этом потоке, а так обычный QThread.

Просто хочется сделать проще, без копирования, и прочего, получил, отрисовал в определнныйх полотнах QImagе, и выдал на экран.

Цитировать
В MainWindow ничего не надо делать.
В вашем наследнике QGraphicView надо запустить таймер, а в обработчик timeout вставить код, который будет читать данные из asio->imagethread и отображать их на сцене.
Естественно, читаемые данные в imagethread должны быть защищены мьютексом.

Наследник от QGraphicView, а не от MainWindow, и как ему читать данные, не имея указателя? желательно не используя сигналы, а на прямую?

Это и была суть вопроса, извините, наверно невнятно все описал.
« Последнее редактирование: Август 10, 2016, 14:19 от deefox » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #11 : Август 10, 2016, 14:15 »

Да, хранимая копия пока ссылается на те же данные пикселей что и исходный имедж. Теперь посыпающая нитка замещает имедж другим. Ну тогда-то шара и сработает, сама сделает detach, хранимая копия останется со старыми данными, оригинал получит новые, все будет исполнено атомарно. Так что гарантия есть. 

Тут нет никакой гарантии. Сами на подобное натыкались.
Оригинальные пиксели легко могут быть изменены через поинтер, полученный через QImage::scanLine (как чаще всего и делается), при этом никакой detach() не вызовется.
Только ручками, только хардкор Улыбающийся
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Август 10, 2016, 14:20 »

Тут нет никакой гарантии. Сами на подобное натыкались.

Оригинальные пиксели легко могут быть изменены через поинтер, полученный через QImage::scanLine (как чаще всего и делается), при этом никакой detach() не вызовется.
Да ну перестаньте. Улыбающийся

Код
C++ (Qt)
uchar *QImage::scanLine(int i)
{
   if (!d)
       return 0;
 
   detach();
 
   // In case detach() ran out of memory
   if (!d)
       return 0;
 
   return d->data + i * d->bytes_per_line;
}
 
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #13 : Август 10, 2016, 14:31 »

uchar* linePtr = img.scanLine(0); // тут detach, понятно

linePtr[0] = 0xff;

emit ImageChanged(img); // ушел сигнал...

linePtr[0] = 0xaa; // а тут поменяли - detach в пролете

emit ImageChanged(img); // снова ушел сигнал, но теперь кто есть кто - вопрос...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #14 : Август 10, 2016, 14:32 »

uchar* linePtr = img.scanLine(0); // тут detach, понятно

linePtr[0] = 0xff;

emit ImageChanged(img); // ушел сигнал...

linePtr[0] = 0xaa; // а тут поменяли - detach в пролете

emit ImageChanged(img); // снова ушел сигнал, но теперь кто есть кто - вопрос...


Вам не кажется, что за такое нужно переводить в разносчики кофе. Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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