crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

zuze
  опции профиля:
сообщение 29.12.2012, 12:04
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


У меня проблема со стиранием нарисованной картинки в определённой области.
Я рисую прямо на окне:
1. Рисую фон прямоугольный
2. Рисую решётку (с помощью горизонтальных и вертикальной линии)
3. Также рисую картинку по данным из двухмерного массива
4. Также рисую линию

Мне надо только картинку удалить которую я нарисовал (пункт 3)

Я попробовал использовать

p->eraseRect();


Указав в скобках область в которой будет закрашивать, но закрасилось почти всё и фон и решётка и рисунок.

Как мне правильно удалить нарисованный рисунок, но чтобы остальное не удалилось?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
6 страниц V   1 2 3 > »   
Начать новую тему
Ответов (1 - 56)
mezmay
  опции профиля:
сообщение 29.12.2012, 14:40
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


void QPainter::save ()

void QPainter::restore ()

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 29.12.2012, 16:01
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(zuze @ 29.12.2012, 14:04) *
Мне надо только картинку удалить которую я нарисовал (пункт 3)
Если речь идёт об удалении "потом" (при следующем вызове события рисования), то могу предложить такой вариант:
1) Всю статику (то что не изменяет или изменяется редко) рисовать вне paintEvent на QImage (или QPixmap).
2) Рисовать "картинку по данным из двухмерного массива" тоже вне paintEvent на QImage (или QPixmap).
3) В paintEvent рисовать ранее созданный QImage со статикой
4) В этом же paintEvent рисовать ранее созданный QImage с "картинкой по данным из двухмерного массива"
5) при обновлении данных перерисовывать QImage с "картинкой по данным из двухмерного массива" (как в п.2)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 29.12.2012, 16:06
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze, я ничего не понял, про какую картинку речь ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 29.12.2012, 20:38
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 29.12.2012, 16:06) *
я ничего не понял, про какую картинку речь ?


Картинки рисуются ввиде заполнения числами модели RGB. Может можно тогда убрать фон прямоугольник и в место него выводить картинки, тогда можно наверно удалять картинку перед появлением новой картинки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 30.12.2012, 7:35
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze, не проще таблицу применить ? )
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 3.1.2013, 17:44
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я решил "3. Также рисую картинку по данным из двухмерного массива" рисовать в место "1. Рисую фон прямоугольный", так как хоть картинка и светлая, но портила вид "2. Рисую решётку (с помощью горизонтальных и вертикальной линии)". Тогда и метод eraseRect() можно воспользоваться.

Вот только пока не понимаю почему, но зрительно видна только последняя (третья) картинка, хотя я задаю вывод трёх картинок с интервалом 10 мс. Может это очень быстро и глаз не успевает заметить?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 6.1.2013, 20:48
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Сделал таймер на 3 минуты, но к сожалению отображается всё равно последний файл.

Как я это делаю:

1. В Конструкторе

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(MyClick()));
timer->start(3000);


2. Алгоритм MyClick()

2.1 Открытие файла
2.2 Очистка области
2.3 Два цикла для считывания значения из файла и занесения в двухмерный массив, а также рисования каждого значения двухмерного массива с помощью drawPoint
2.4 Зацикливание, то есть переход к следующему

3. В переопределение paintEvent я вызываю MyClick().

Я с помощью qDebug() проверил совпадает ли имена файлов и их порядковое значение, то есть
i = 1; fp = 1.dat
i = 2; fp = 2.dat
i = 3; fp = 3.dat

Также проверял каждый файл в отдельности, картинка разная рисуется.

Значит дело не в том, что я файлы не правильно считываю. В чём же ещё может быть проблема, что выводится, только картинка из последнего файла?

void p::MyClick()
{
    struct _finddata_t f;
    long int hFile;
    chdir("file");
    hFile = _findfirst("*.dat", &f);
    int KolAllFile = hFile;
 
    while (KolAllFile != -1)
    {
            QPainter *Tochka = new QPainter(this);
            int rc;
            long int size;
            FILE *fp = fopen(f.name, "rb");
 
            if (fp == NULL)
               qDebug() << "Cannot open file read!";
 
            Tochka->eraseRect(50, 50, 720, 492);
            for (int j = 0; j < 720; j++)
            {
                for (int i = 0; i < 492; i++)
                {
                    rc = getc(fp);
                    buffer[i][j] = rc;
                    Tochka->setPen(QColor(buffer[i][j], buffer[i][j], buffer[i][j], 127)); // Задание цвета
                    Tochka->drawPoint(50+j, 542-i);    // Рисуем точку
                }
            }
            delete Tochka;
            fclose(fp);
        }
        KolAllFile = _findnext(hFile, &f);
    }
}


Так как я делаю

delete Tochka;


то отображается последняя картинка, но убирание этой строчки кода ситуацию не меняет, вроде это происходит потому, что я рисую всё подряд за один раз.
Мог бы кто-нибудь рассказать, что значит сделать не за раз?

Сообщение отредактировал zuze - 6.1.2013, 21:34
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 7.1.2013, 18:00
Сообщение #9


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze, тебе несколько человек сказали: рисуй в обработчике paintEvent

а ты рисуешь в обработчике таймера

время - это сдвиг фазы. В обработчике рисования выводишь картинку для текущей фазы. После этого скорость показа будет зависеть только от тактования
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 8.1.2013, 16:26
Сообщение #10


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Алексей1153, я понял надо было сделать так:

1. В Конструкторе

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(MyTimer()));
timer->start(3000);


2. Описание MyTimer()

void l::MyTimer()
{
    this->update();
}


3. Функция MyClick() осталась прежней.

4. В методе paintEvent() вписываю MyClick();

Всё равно появляется только последний файл. Почему?

Сообщение отредактировал zuze - 8.1.2013, 16:27
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 9.1.2013, 8:50
Сообщение #11


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


так ты фазу не смотришь, бацаешь всё в цикле while (KolAllFile != -1)

кстати, необязательно делать паинтер на куче
QPainter *Tochka = new QPainter(this);

можешь на стеке
QPainter Tochka(this);

так как в каждой итерации цикла это будет новая переменная. И цикла, вообще говоря, не будет, когда станешь фазу учитывать - рисование произойдёт один раз
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 11.1.2013, 9:20
Сообщение #12


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я пытался сделать так

int rc;                    // В public у класса  
long int size;          // В public у класса 
char namefile[12]; // В public у класса 

// Может это и не красиво, но я объявил эти переменные глобально
int buffer[492][720];
char NameFiles[670][12];
int frame = 0;

void l::MyDraw()
{
    timerRLP = new QTimer(this);
    connect(timerRLP, SIGNAL(timeout()), this, SLOT(MyTimeTick()));
    timerRLP->start(3000);

    QPainter Tochka;
    Tochka.begin(this);
    Tochka.eraseRect(QRect(50, 50, 720, 492));
    for (int j = 0; j < 720; j++)
    {
        for (int i = 0; i < 492; i++)
        {
            Tochka.setPen(QColor(buffer[i][j], buffer[i][j], buffer[i][j], 127)); // Задание цвета
            Tochka.drawPoint(50+j, 542-i);    // Рисуем точку
        }
    }
    Tochka.end();
}
// Массив имён файлов
void l::MyNameFile()
{
    struct _finddata_t f;
    long int hFile;
    int i = 0;
    chdir("file");
    hFile = _findfirst("*.dat", &f);
    int KolAllFile = hFile;

    while (KolAllFile != -1)
    {
        FILE *fp = fopen(f.name, "rb");
        if (fp == NULL)
           qDebug() << "Cannot open file read!";

        strcpy(NameFiles[i], f.name);
        i++;
        fclose(fp);
        KolAllFile = _findnext(hFile, &f);
    }
    _findclose(hFile);
}

void l::MyTimeTick()
{
    // Эти три строчки были сделаны потому, что   NameFiles[0] лежит имя первого файла + все последующие, хотя до этого лежало, только имя первого файла
    //  NameFiles[1]  лежит имя второго файла + все последующие, хотя до этого лежало, только имя второго файла
    strcpy(namefile, "");
    strncpy(namefile, NameFiles[frame], 11);
    strcat(namefile, "C");

    FILE *fp = fopen(namefile, "rb");

    if (fp == NULL)
       qDebug() << "Cannot open file read!";

    for (int j = 0; j < 720; j++)
    {
        for (int i = 0; i < 492; i++)
        {
            rc = getc(fp);
            buffer[i][j] = rc;
        }
    }
    fclose(fp);
    if (frame < 670)
    {
        this->update();
        frame++;
    }
    else
    {
       frame = 0;
       this->update();
    }
}


В конструкторе

connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(MyNameFile()));


В paintEvent() я добавил

if (ui->checkBox_4->isChecked())
   MyDraw();


В результате рисуется вся область самым нижним цветом (у меня он серый) и через какое-то время зависает.
Выскакивает окно с тремя кнопками вторая кнопка "Закрыть", третья "Отладить".
Я нажимаю закрыть и появляется ошибка: Завершение с кодом -1073741819.

А должны выводится которые меняются в данном случае через три секунды. Что же я делаю не так?

Сообщение отредактировал zuze - 11.1.2013, 10:01
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 11.1.2013, 10:57
Сообщение #13


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Избавился от ошибки переместив

timerRLP = new QTimer(this);
connect(timerRLP, SIGNAL(timeout()), this, SLOT(MyTimeTick()));


В конструктор. Но результат рисуется такой же, вся область самым нижним цветом (у меня он серый).

Сообщение отредактировал zuze - 11.1.2013, 10:57
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.1.2013, 12:20
Сообщение #14


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


у тебя в голове каша ))

давай попробуем иначе:

1) создай новый проект и напиши программу, где есть один диалог. Когда по окну диалога щёлкают, пусть он закрасится одним цветом, когда ещё раз - другим. Пусть всего 3 цвета. Закрашивай в paintEvent (непосредственно там, без всяких перевызовов!)

2) дополнительно - почитай про std::vector, и замени свои глобальные массивы хотя бы им

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 14.1.2013, 19:11
Сообщение #15


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вопрос решён. Дело было в том, что я не учёл '\0' в именах файлов.
Писал так:

char NameFiles[670][12];


а надо было так:

char NameFiles[670][13];
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.1.2013, 22:03
Сообщение #16


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze, но ты же понимаешь, что так дела не делаются. Храни в одном из текстовых форматов лучше - столько проблем автоматом отпадут, ты бы только знал )

Я это всё давно прошёл
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 15.1.2013, 5:40
Сообщение #17


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Алексей1153, большое спасибо за помощь. К сожалению от вида файлов которые мне даны отказаться нельзя, так как даны мне для использования и ни кто переделывать их не будет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 15.1.2013, 6:02
Сообщение #18


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze, сделай конвертер и перегоняй в нужный вид. С ним и работай
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.1.2013, 9:31
Сообщение #19


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Почему я не могу стереть то, что рисовалось с помощью Qpainer?

if (ui->radioButton->isChecked())
{
   Qpainer p(this);
   if (!ui->CheckBox->isChecked())
   {
      p.setBrush(QBrush(Qt::black));
      p.drawRect(50, 50, 720, 492);
   }
   else
   {
      p.eraseRect(50, 50, 720, 492);
      MyDraw();
   }
}


Этот код описан в переопределении paintEvent().
Не выполняется

p.eraseRect(50, 50, 720, 492);
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 16.1.2013, 17:50
Сообщение #20


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


1) Qpainer - что за класс ?
2) доходит ли выполнение до этого места ? (p.eraseRect(50, 50, 720, 492)
3) и что делает MyDraw ?

Сообщение отредактировал Алексей1153 - 16.1.2013, 17:52
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.1.2013, 18:31
Сообщение #21


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 16.1.2013, 17:50) *
1) Qpainer - что за класс ?


Это я ошибся при наборе должно быть QPainter.

Цитата(Алексей1153 @ 16.1.2013, 17:50) *
2) доходит ли выполнение до этого места ? (p.eraseRect(50, 50, 720, 492)


Конечно, так как MyDraw(); выполняется, а если не доверять этой функции, то можно написать qDebug() << "test"; и это слово выводиться значит доходит.

Цитата(Алексей1153 @ 16.1.2013, 17:50) *
3) и что делает MyDraw ?


Рисует картинку по значениям из двухмерного массива.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 16.1.2013, 19:04
Сообщение #22


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze,

1) а энтот MyDraw у тебя точно только отсюда вызван ?
2) почему в эту функцию не передал p ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.1.2013, 19:17
Сообщение #23


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 16.1.2013, 19:04) *
1) а энтот MyDraw у тебя точно только отсюда вызван ?


Да, только здесь вызывается.

Цитата(Алексей1153 @ 16.1.2013, 19:04) *
2) почему в эту функцию не передал p ?


Так как там свой элемент класса QPainter.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 16.1.2013, 19:21
Сообщение #24


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


ну это точно ошибка, не должно быть двух паинтеров. Рисуется на одном же!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 17.1.2013, 7:33
Сообщение #25


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 16.1.2013, 19:21) *
ну это точно ошибка, не должно быть двух паинтеров. Рисуется на одном же!


А почему? Рисую область чёрную с помощью одного элемент класса QPainter, а картинки рисую с помощью другого элемент класса QPainter. Чёрная область отображается и картинки отображаются тоже, Только перед рисованием картинок чёрная область не стирается, как я понял не перерисовывается почему-то. Пробовал после стирание сразу update() делать не помогло.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.1.2013, 7:36
Сообщение #26


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


передай указатель в функцию и рисуй на нём, что тут спорить то )))

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 17.1.2013, 9:25
Сообщение #27


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 17.1.2013, 7:36) *
передай указатель в функцию и рисуй на нём, что тут спорить то )))


Сделал.
Теперь вызов функции такой:
MyDraw(&p);


А в нутри функции я всё равно не могу очистить перед рисованием картинки, делаю так:
t->eraseRect(50, 50, 720, 492);


Значит ни в этом дело. Что же ещё может быть?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.1.2013, 10:36
Сообщение #28


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


1) код MyDraw покажи. Что за t ?
2) что ты там очищаешь, я так и не могу понять, если честно. Рисуй картинку и всё ))

приложи уже проект, что ли
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 18.1.2013, 12:48
Сообщение #29


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я сделал так. Создал новый проект в котором одна вертикальная линия двигается через 3 секунды по своему таймеру. а другая линия двигается через 5 секунд по своему таймеру. Тут всё работало идеально. Тогда я закомментировал код в функции рисования и функции-слот таймера и вставил туда код рисования одной из этих двух линий (не важно какой). Всё прекрасно заработало. Так я понял, что подвисание таймера линии были из-за того что в функции-слот таймера были слишком много циклов или что было много циклов в функции-слот таймера и в функции рисования.

Если я могу убрать циклы из функции рисования через Qpixmap, то как убрать циклы при заполнении массива в функции-слоте?

Ниже код, где идёт цикличное заполнение массива.

for (int j = 0; j < 720; j++)
{
     for (int i = 0; i < 492; i++)
     {
         rc = getc(fp);
         buffer[i][j] = rc;
     }
}


Использованные переменные имеют типы:

int rc;
int buffer[492][720];
FILE *fp;
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.1.2013, 14:15
Сообщение #30


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


считай всё одним махом, а не по байтику

ещё можно проекцией файла воспользоваться:

QFile file("d:/1.bin");
if(!file.open(QFile::ReadOnly))return false;

uint8_t* pFileBeg=file.map(0,file.size());
if(!pFileBeg)return false;

file.close();

typedef int td_element;//тип элемента массива

uint32_t count=file.size()/sizeof(td_element);
std::vector<td_element> buffer
(
 ((td_element*)pFileBeg)
,((td_element*)pFileBeg) + count
);



не компилировал )

ещё - можно один раз загрузить из файла, зачем это каждый раз делать ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 21.1.2013, 9:06
Сообщение #31


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 18.1.2013, 14:15) *
ещё - можно один раз загрузить из файла, зачем это каждый раз делать ?


Так как у меня целая куча файлов, а не один и каждый должен через определённый промежуток времении появлятся.

Я попытался сделать так:

void l::MyClickButton()
{
        chdir("file");
        QFile fp("1.dat");
     
        if(!fp.open(QFile::ReadOnly))
          qDebug() << "Cannot open file read";
     
        char *str = fp.readAll().data();
        fp.close();
     
        for (int i = 0; i < 11; i++)
            qDebug() << (int)str[i];
}


Но на третье значение уже коряво выводиться. Я посмотрел оно равно EC, что соответствует русской букве 'М' и с другими русскими буквами ошибки. В результате помимо, что часть значений выводиться не правильно, так в место всего файла выводиться только 11 знаков. Как я понял метод "readAll().data()" не работает с кириллицей.
Что же делать, что бы весь файл у меня за раз считывался?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 21.1.2013, 10:12
Сообщение #32


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Как я понял "readAll().data()" выводит значения в дополнительном коде, а надо мне перевести в прямой код, тем более почему выводиться только 11 символов? Не смотрите, что у меня цикл до 11, так как я увиличевыал на сотню больше или вообще убирал цикл. Всё равно 11 символов.

Я думал перевод из дополнительного кода в прямой код, делается так:

В место

qDebug() << (int)str[i];


Написал так

qDebug() << ~((int)str[i]) + 1;


Это не помогло, правильные значения стали отрицательными, а у неправильных значений убрался только отрицательный знак.
Может "readAll().data()" значение не в дополнительном коде из файла берёт, тогда в каком коде?

Сообщение отредактировал zuze - 21.1.2013, 10:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 21.1.2013, 21:54
Сообщение #33


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze,

1) много файлов- кеш в помощь. Или маппинг
2) у тебя явно ошибка тут (по крайней мере очень не советую так делать):

char *str = fp.readAll().data();
fp.close();


тут ты делаешь вот что: объект QByteArray создаётся на стеке без имени, с него вытаскивается указатель на начало. А дальше - фиг знает, что будет

делай копию
QByteArray ba= fp.readAll().data();

3) методу глубоко пофиг, кириллица там или юникод. Он скопирует БАЙТЫ :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 22.1.2013, 8:21
Сообщение #34


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я сделал так, значения стали выводится в нужном количестве:

void l::MyClickButton()
{
    chdir("file");
    QFile fp("1.dat");

    if(!fp.open(QFile::ReadOnly))
      qDebug() << "Cannot open file read";

    char *temp = new char[492*720];
    fp.read(temp, (qint64)(492*720));
    fp.close();

    for (int i = 0; i < 11; i++)
        qDebug() << temp[i];

    delete [] temp;
}


Но вот значения когда я в место

for (int i = 0; i < 11; i++)
        qDebug() << temp[i];


Делаю

for (int i = 0; i < 11; i++)
        qDebug() << (int)temp[i];


или

for (int i = 0; i < 11; i++)
        qDebug() << static_cast<int>(temp[i]);


или

for (int i = 0; i < 11; i++)
        qDebug() << temp[i] - '0';


Значение EC, что соответствует русской букве 'М', выводиться как -20, а должно 236 и такие отрицательные значения, только появляются, когда появляется кириллица. Как это поправить?

Сообщение отредактировал zuze - 22.1.2013, 8:26
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.1.2013, 8:27
Сообщение #35


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


лучше так

std::string temp(492*720,0);
fp.read(&temp[0], temp.size());
fp.close();


причём, за счёт того, что это std::string, ноль на конце учтётся автоматом (он там всегда есть)

для юникода юзай std::wstring, только учитывай, что тут элемент - 2 байта

насчёт знака - ну так int знаковый. Сделай так


qDebug() << (uint32_t)temp[i];

Сообщение отредактировал Алексей1153 - 22.1.2013, 8:29
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 22.1.2013, 8:33
Сообщение #36


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 22.1.2013, 8:27) *
qDebug() << (uint32_t)temp[i];


Только я сделал

qDebug() << (uint8_t)temp[i];


А то выводилось в формате и десяти цифор.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 22.1.2013, 14:08
Сообщение #37


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


То что я сделал - это не помогло.
Я проверял так:
1. Рисую один файл. Торможения таймера линии есть.
2. Рисую область одним цветом. Торможения таймера линии стало меньше в три раза.
3. Рисую область используя метод DrawRect() при этом убираю циклы. Таймер линии нормально идёт.

Как я понял, что надо использовать потоки и их синхронизировать, правда не совсем понимаю, как это сделать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.1.2013, 16:56
Сообщение #38


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


давно тебе говорю уже - прицепи проект
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 22.1.2013, 18:12
Сообщение #39


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Алексей1153, а есть функция которая за раз рисует по значениям из двухмерного массива?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.1.2013, 18:58
Сообщение #40


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


конечно есть - drawImage
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 22.1.2013, 19:55
Сообщение #41


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 22.1.2013, 18:58) *
конечно есть - drawImage


Я так понял он принимает начальные координаты, а третий параметр это указатель типа QImage на файл. А можно в место указателя на QImage поставить двухмерный массив целый чисел, если да, то как это сделать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.1.2013, 20:07
Сообщение #42


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


можно прицепить QImage к QPainter и нарисовать на нём пикселы один раз. А потом при рисовании - выводить картинку разом

Сообщение отредактировал Алексей1153 - 22.1.2013, 20:07
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 22.1.2013, 20:17
Сообщение #43


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 22.1.2013, 20:07) *
нарисовать на нём пикселы один раз


Это всё равно требует циклы. А я специально хотел найти такую функцию стандартную, что бы ни куда не рисовать предварительно, а сразу чтобы она рисовала по данным из двухмерного массива за раз. Может что-нибудь такое есть?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.1.2013, 23:00
Сообщение #44


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


если данные у тебя были сохранены в формате, который понимает класс, то можно. Иначе - только вручную
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 23.1.2013, 7:54
Сообщение #45


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(zuze @ 29.12.2012, 12:04) *
если данные у тебя были сохранены в формате, который понимает класс, то можно. Иначе - только вручную


То есть мне как-то надо преобразовать тип int ** в QImage. Но вот как это сделать?

Сообщение отредактировал zuze - 23.1.2013, 7:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.1.2013, 8:35
Сообщение #46


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


например так

QImage im(x_size,y_size,QImage::Format_RGB32);

im.fill(qRgb(255,255,255));//заливаем белым

рисуем пикселы в нужных местах
for(......)
{ 
  im.setPixel...
}



ещё можно рисовать на QPixmap
QPixmap pixmap(x_size,y_size);
pixmap.fill(qRgb(255,255,255));//заливаем белым

//если нужно - можно сделать маску прозрачности
//pixmap.setMask(pixmap.createMaskFromColor(qRgb(255,255,255),Qt::MaskInColor));

//прикрепляем к экземпляру рисовалки
QPainter painter(&pixmap);

//рисуем на painter как обычно
...
...

//завершаем рисование
painter.end();
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 23.1.2013, 9:10
Сообщение #47


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Если использую QPixmap всё равно один раз надо его циклично задать, если QImage тоже самое. Не ужели тут единственный вариант это создание потока?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.1.2013, 9:41
Сообщение #48


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


а в чём проблема один раз долго создавать картинку, а потом миллион раз быстро её показывать ? ))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 23.1.2013, 10:25
Сообщение #49


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 23.1.2013, 9:41) *
а в чём проблема один раз долго создавать картинку, а потом миллион раз быстро её показывать ? ))


У меня не одна картинка, а около 1000 и я через определённое время меняю.

Я сделал так:

Глобальная переменная

QImage im(720, 492, QImage::Format_ARGB32);


Часть кода из функции-слот таймера

for (int j = 0; j < 720; j++)
{
     for (int i = 491; i >= 0; i--)
     {
          buffer[i][j] = getc(fp);
          im.setPixel(j, i, QColor(buffer[i][j], buffer[i][j], buffer[i][j], 255).rgba());
     }
}


А в paintEvent() рисую так:

Tochka.drawImage(50, 50, im);


Скорость линии падает, но не так сильно, то есть допустим без картинок линия оборот совершает за 3 секунды, а с картинками за 6 секунд. Это всё равно не правильно, но уже лучше. А мне надо, что бы с картинками и без них линия делала оборот за 3 секунды, что ещё можно придумать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.1.2013, 12:03
Сообщение #50


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


поставлю вопрос немного по-другому:

а в чём проблема один раз долго создавать 1000 картинок, а потом миллион раз быстро их показывать ?

к тому же - необязательно сразу это делать, можно по мере необходимости создавать картинку при первом доступе к ней

Глобальная переменная не канает. Делай мембер

std::map<QString,QImage*> m_pictures;


где QString -например, путь к файлу
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 23.1.2013, 15:08
Сообщение #51


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Может быть в место setPixel() из класса QImage использовать метод из класса QImageReader. Правда я пока не понял, как там загонять двухмерный массив и как его отображать. Если кто знает скажите?

Сообщение отредактировал zuze - 23.1.2013, 15:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.1.2013, 17:01
Сообщение #52


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


zuze, всё уже сказано.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 24.1.2013, 10:06
Сообщение #53


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


А если метод у класса "QImage", который был бы аналогом метода "setPixel", но что бы заполнялся за раз.
То есть что бы не так:

for (int j = 0; j < 720; j++)
{
     for (int i = 491; i >= 0; i--)
     {
          buffer[i][j] = getc(fp);
          im.setPixel(j, i, QColor(buffer[i][j], buffer[i][j], buffer[i][j], 255).rgba());
     }
}


А мне надо что бы можно без циклов выполнить "setPixel", но я не знаю как это сделать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 24.1.2013, 10:16
Сообщение #54


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


QImage fromData ( const uchar * data, int size, const char * format = 0 )
QImage fromData ( const QByteArray & data, const char * format = 0 )

но массивы сначала надо подготовить соответственно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 24.1.2013, 10:24
Сообщение #55


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 24.1.2013, 10:16) *
но массивы сначала надо подготовить соответственно


Это не подходит, так как надо двухмерный массив надо переделать в одномерный массив.
Но это не критично, критично то, что после этого "drawImage()" будет рисовать всё в одну линию, а это не правильно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 24.1.2013, 10:34
Сообщение #56


фрилансер
******

Группа: Участник
Сообщений: 2944
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


1) чем двух, трёх и N-мерный массив отличается от одномерного ?
2) переделать - очень быстрая операция
3) будет рисовать всё в одну линию - с чего вдруг ?

вот с указанием размеров картинки
QImage::QImage ( const uchar * data, int width, int height, int bytesPerLine, Format format )
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 25.1.2013, 11:04
Сообщение #57


Участник
**

Группа: Участник
Сообщений: 211
Регистрация: 4.11.2012
Пользователь №: 3589

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я решил задачу. Я решил проверить правильно ли я сделал таймер линии, так как за таймер картинок я был спокоен и оказалось, что таймер линии вообще не правильно был занят. Дело в том, что промежуток на которое должна перемещаться линия (был описан в paintEvent()) и время таймера была заданна не верно. Это произошло из-за того, что таймер линии был сделан давно. Всем большое спасибо за помощь!

Сообщение отредактировал zuze - 25.1.2013, 13:04
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

6 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 4.7.2025, 8:38