다음은 데이터 집합 형식을 올바르게 읽는 방법을 보여주는 스크립트입니다.
그러나 현재 실제로 모든 데이터를 올바르게 읽을 수는 없습니다. 이는 QList<double>
및 QVector<QPointF>
템플릿 클래스로, PyQt는 직접 지원하지 않습니다. 코드에서이 타입을 읽는 데 필요한 누락 된 PyQt 메소드 대신 readQVariantList
을 사용했습니다.
UPDATE는 :
나는이 작업을 수행 할 수있는 방법이 없다는 author of PyQt confirmed을 PyQt는 메일 링리스트에서 임의의 템플릿 클래스 처리에 대해 질문합니다. 그래서 유일한 옵션은 C++에서 일종의 변환 도구를 작성하는 것입니다.
UPDATE2 :
그것은 내가 지금 해결 방법을 발견했기 때문에 나는, 너무 빨리 말 것. datastream format은 내가 생각했던 것보다 훨씬 간단하며 임의의 템플릿 클래스를 읽는 것이 간단한 알고리즘으로 줄일 수 있습니다. 기본적으로 길이를 uint32
으로 읽어 들인 다음 range
을 반복하고 포함 된 요소를 하나씩 읽습니다. list
:
from PyQt4 import QtCore, QtGui
FLAG_HASSOURCE = 0x0001
FLAG_HASROLE = 0x0002
FLAG_HASCOLOR = 0x0004
FLAG_HASID = 0x0008
FLAG_COMPRESS = 0x0010
FLAG_HASTHRESHOLDS = 0x0020
FLAG_HASUNITS = 0x0040
FLAG_HASCREATORIDS = 0x0080
FLAG_HASHIDDEN = 0x0100
FLAG_HASMETADATA = 0x0200
MAGIC_NUMBER = 0x46474247
FILE_VERSION = 1
DATASET_MARKER = 0x44415441
DATASET_MAGIC = 0x53455455
def read_data(path):
infile = QtCore.QFile(path)
if not infile.open(QtCore.QIODevice.ReadOnly):
raise IOError(infile.errorString())
stream = QtCore.QDataStream(infile)
magic = stream.readUInt32()
if magic != MAGIC_NUMBER:
raise IOError('invalid magic number')
version = stream.readUInt32()
if version != FILE_VERSION:
raise IOError('invalid file version')
marker = stream.readUInt32()
if marker != DATASET_MARKER:
raise IOError('invalid dataset marker')
count = stream.readInt32()
if count < 1:
raise IOError('invalid dataset count')
stream.setVersion(QtCore.QDataStream.Qt_4_7)
rows = []
while not stream.atEnd():
row = []
magic = stream.readUInt32()
if magic != DATASET_MAGIC:
raise IOError('invalid dataset magic number')
row.append(('Name', stream.readQString()))
flags = stream.readUInt32()
row.append(('Flags', flags))
if flags & FLAG_HASID:
row.append(('ID', stream.readQString()))
if flags & FLAG_HASCOLOR:
color = QtGui.QColor()
stream >> color
row.append(('Color', color))
if flags & FLAG_HASUNITS:
row.append(('Units', stream.readInt32()))
if flags & FLAG_HASCREATORIDS:
row.append(('Creators', stream.readQStringList()))
if flags & FLAG_HASHIDDEN:
row.append(('Hidden', stream.readBool()))
if flags & FLAG_HASTHRESHOLDS:
thresholds = []
length = stream.readUInt32()
for index in range(length):
thresholds.append(stream.readDouble())
row.append(('Thresholds', thresholds))
if flags & FLAG_HASSOURCE:
row.append(('Source', stream.readQString()))
if flags & FLAG_HASROLE:
row.append(('Role', stream.readInt32()))
points = []
length = stream.readUInt32()
for index in range(length):
point = QtCore.QPointF()
stream >> point
points.append(point)
row.append(('Points', points))
rows.append(row)
infile.close()
return rows
rows = read_data('datasets.bin')
for index, row in enumerate(rows):
print('Row %s:' % index)
for key, data in row:
if isinstance(data, list) and len(data):
print(' %s = [%s ... ] (%s items)' % (
key, repr(data[:3])[1:-1], len(data)))
else:
print(' %s = %s' % (key, data))
하는 것이, 예를 QDataStream를 사용하는 것이 가장 쉬운 방법이 될 것이다 :
다음스크립트의 수정 된 버전입니다 Qt 파이썬 바인딩? –
https://dl.dropboxusercontent.com/u/28824868/datasets.bin 누구나 테스트하려는 경우 데이터 세트 파일에 대한 링크입니다. –
@MichaelBawol. 나는 그 파일을 C++로 읽으려고했는데 첫 번째'Source' 엔트리에서 실패했다. 따라서 형식이 불완전하거나 잘못되었거나 파일이 손상되었습니다. 파일을 어디서 가져 왔니? 알려진 값을 가진 작은 장난감 예가 있습니까? – ekhumoro