crossplatform.ru

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

6 страниц V  « < 3 4 5 6 >  
Ответить в данную темуНачать новую тему
> Торможения таймера при рисовании, Python
zuze
  опции профиля:
сообщение 15.4.2013, 14:25
Сообщение #41


Участник
**

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

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




Репутация:   0  


Цитата(lanz @ 15.4.2013, 13:55) *
Выложите проект, попробую потыркать.


# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
import numpy
import math  # Для pi, sin, cos
import os    # Для работы с файлами
import struct
import time

dir = os.path.join(os.getcwd(), "file") # Выбор текущей директории с файлами
phi = 0.0

im = QtGui.QImage(720, 492, QtGui.QImage.Format_ARGB32)

class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)

        self.connect(self.ui.radioButton_2, QtCore.SIGNAL("clicked()"), self.MyClickRect)

        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        self.timer.setInterval(5000)
        self.timer.start()

    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton_2.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)
            self.MyDraw()

    def MyClickRect(self):
        self.update()

    def MyRadianToGradus(self, phiedit):
        gradus = phiedit * 360/(2*math.pi)
        return gradus

    def MyGradusToRadian(self, phiedit):
        radian = phiedit * 2*math.pi / (360)
        return radian

    def MyTimer(self):
        global dir
        global phi
        global im
        global fp

        if self.ui.checkBox_4.isChecked():
            os.chdir(dir)
            try:
                fp = open("1.dat", "rb")
            except IOError:
                print "Cannot open file read!"

            fp.seek(0, 2)
            size = fp.tell()
            fp.seek(size - (492*720), 0)

            a = numpy.fromfile(fp, dtype=numpy.uint8)
            a = numpy.flipud(a.reshape((492, 720), order='F'))
            data = a.tostring()
            im = QtGui.QImage(data, 492, 720, QtGui.QImage.Format_ARGB32)

            self.update()

        if self.ui.radioButton_2.isChecked():
            if int((self.MyRadianToGradus(phi)+0.5)*720)/360 < 720:
                phi += self.MyGradusToRadian(6.0) # Поворот и смещение линии в полярных и пямоугольных координатах
            else:
                phi = self.MyGradusToRadian(6.0)

    def MyDraw(self):
        global im

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)
        Tochka.drawImage(0, 0, im, 0, 0, int((2*self.MyRadianToGradus(phi))+0.5), 492)

        Tochka.end()

        self.update()

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)

    window = ld()
    window.show()

    sys.exit(app.exec_())


К сожалению я немогу дать Вам файл. Можно использовать любую строку длинной 492 * 720, только тогда не нужен код:
fp.seek(0, 2)
size = fp.tell()
fp.seek(size - (492*720), 0)


Прикреплённый архив содержит ld.ui

Может дело в a.tostring(), которая вроде не всегда стабильно работает. Может какой другому можно подготовить данные из файла, что бы из загрузить затем в объект QImage?

Сообщение отредактировал zuze - 15.4.2013, 14:15
Прикрепленные файлы
Прикрепленный файл  ld.zip ( 604 байт ) Кол-во скачиваний: 123
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 15.4.2013, 16:43
Сообщение #42


Старейший участник
****

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

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




Репутация:   8  


1. Не нужно вызывать update в методе paintEvent это плодит ненужные циклы отрисовки.
2. Если используете Indexed8, то нужно определить таблицу цветов,
Цитата
If format is an indexed color format, the image color table is initially empty and must be sufficiently expanded with setColorCount() or setColorTable() before the image is used.

3. Если используете ARGB32, то байт должно быть в 4 раза больше (красная, зеленая, синияя и альфа - компоненты) т.е. размер файла должен быть 492*720*4.
4. data должен быть валиден в течении всего времени жизни картинки. (т.е. не должен быть локальной переменной)
Цитата
The buffer must remain valid throughout the life of the QImage. The image does not delete the buffer at destruction.

Это происходит потому что вызывается конструктор с неконстантным первым uchar*.
5. Эти преобразования бесполезны.
a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((492, 720), order='F'))
data = a.tostring()

То же самое будет если сделать
data = fp.read()

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 8:44
Сообщение #43


Участник
**

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

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




Репутация:   0  


Я сделал так:
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
import math
import os
import struct

dir = os.path.join(os.getcwd(), "file")
phi = 0.0

im = QtGui.QImage(720, 492, QtGui.QImage.Format_ARGB32)

class ld(QtGui.QDialog):
    def __init__(self, parent=None):
        super(ld, self).__init__(parent)
        self.ui = uic.loadUi("ld.ui", self)

        self.connect(self.ui.radioButton_2, QtCore.SIGNAL("clicked()"), self.MyClickRect)

        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.MyTimer)
        self.timer.setInterval(5000)
        self.timer.start()

    def paintEvent(self, QPaintEvent):
        if self.ui.radioButton_2.isChecked():
            painterRect = QtGui.QPainter(self)
            painterRect.setBrush(QtGui.QColor('black'))
            painterRect.drawRect(50, 50, 720, 492)
            self.MyDraw()

    def MyClickRect(self):
        self.update()

    def MyTimer(self):
        global im
        global dir
        global phi
        global fp

        if self.ui.checkBox_4.isChecked():
            os.chdir(dir)
            try:
                fp = open("07_30_29.28C", "rb")
            except IOError:
                print "Cannot open file read!"

            fp.seek(0, 2)
            size = fp.tell()
            fp.seek(size - (492*720), 0)

            data = fp.read()

            im = QtGui.QImage(data, 720, 492, QtGui.QImage.Format_ARGB32)

            self.update()

        if self.ui.radioButton_2.isChecked():
            if int((math.degrees(phi)+0.5)*720)/360 < 720:
                phi += math.radians(6.0)
            else:
                phi = math.radians(6.0)

    def MyDraw(self):
        global im

        Tochka = QtGui.QPainter()
        Tochka.begin(self)

        Tochka.translate(50, 50)
        Tochka.drawImage(0, 0, im, 0, 0, int((2*math.degrees(phi))+0.5), 492)

        Tochka.end()

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)

    window = locatordialog()
    window.show()

    sys.exit(app.exec_())


В этом коде случилось следующие:
1. update в методе paintEvent.
2. В место собственных функций преобразование из радиан в градусы и обратно использовал стандартные.
3. Преобразование строки заменил на такое data = fp.read()

Я незнаю как сделать im локально, так как я im использую в MyTimer(), но также я im использую в MyDraw(). Подскажите пожалуйста, как это сделать?

Цитата(lanz @ 15.4.2013, 16:43) *
Эти преобразования бесполезны.

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((492, 720), order='F'))
data = a.tostring()


Не знаю на сколько они безполезны, но если в циклах заполняем im сзначениями из a, то всё прекрасно, картинка рисуется, но медленно. Вот я немного удивлён, что эти преобразования бесполезны.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 9:46
Сообщение #44


Старейший участник
****

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

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




Репутация:   8  


Цитата
Я незнаю как сделать im локально, так как я im использую в MyTimer(), но также я im использую в MyDraw(). Подскажите пожалуйста, как это сделать?

Не надо делать im локальным, надо сделать data глобальным/членом класса. data должна существовать после того как управление выйде из MyTimer поскольку коструктор QImage сохраняет только указатель на дату.

Цитата
Вот я немного удивлён, что эти преобразования бесполезны.

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


Участник
**

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

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




Репутация:   0  


Цитата(lanz @ 16.4.2013, 9:46) *
Не надо делать im локальным, надо сделать data глобальным/членом класса. data должна существовать после того как управление выйде из MyTimer поскольку коструктор QImage сохраняет только указатель на дату.


Сделал в конструкторе класса, так:

self.data = []


Сделал в MyTimer

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((720, 492), order='F'))
self.data = a.tostring()

im = QtGui.QImage(self.data, 720, 492, QtGui.QImage.Format_ARGB32)


И всё равно, таже ошибка?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 10:23
Сообщение #46


Старейший участник
****

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

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




Репутация:   8  


Конечно. Загружаете 720*492 байт, а картинке говорите что их 720*492*4 (Format_ARGB32)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 10:36
Сообщение #47


Участник
**

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

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




Репутация:   0  


Цитата(lanz @ 16.4.2013, 10:23) *
Конечно. Загружаете 720*492 байт, а картинке говорите что их 720*492*4 (Format_ARGB32)


А как картинке задать, что бы брала только 720*492? Я думал достаточно указать QtGui.QImage.Format_ARGB, но такого формата нету.

Сообщение отредактировал zuze - 16.4.2013, 11:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 11:29
Сообщение #48


Старейший участник
****

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

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




Репутация:   8  


Можно использовать Format_Indexed8, только нужно обязательно задать таблицу цветов.
http://qt-project.org/doc/qt-4.8/qimage.html#setColorTable
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zuze
  опции профиля:
сообщение 16.4.2013, 12:21
Сообщение #49


Участник
**

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

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




Репутация:   0  


Цитата(lanz @ 16.4.2013, 11:29) *
Можно использовать Format_Indexed8, только нужно обязательно задать таблицу цветов.


Сделал так:

a = numpy.fromfile(fp, dtype=numpy.uint8)
a = numpy.flipud(a.reshape((720, 492), order='F'))
self.data = a.tostring()

im = QtGui.QImage(self.data, 720, 492, QtGui.QImage.Format_Indexed8)
QtGui.QImage.setColorTable(QtGui.qRgba(255, 0, 0, 255))


Всё равно, тажа ошибка.

Сообщение отредактировал zuze - 16.4.2013, 12:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 16.4.2013, 12:48
Сообщение #50


Старейший участник
****

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

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




Репутация:   8  


setColorTable нужно вызывать у конкретного экземпляра QImage, кроме того туда нужно передать вектор цветов, а не один цвет.

Сообщение отредактировал lanz - 16.4.2013, 12:49
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 22.11.2024, 22:40