44121
pyqtで表示する画像やサウンドを一つのファイルにまとめたいです。そこでそれらをpickle化しようと思い、次のようなコードを書いてみました。

```

    import pickle
    from PyQt5 import  QtWidgets,QtMultimedia
    from PyQt5.QtWidgets import *
    
    img=QPixmap("画像.png")
    img2=QPixmap("画像2.jpg")
    list_image=[img,img2]
    save_file=open("image_list.dat","wb")
    pickle.dump(list_image,save_file)
    save_file.close()
    
    sound=QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile("サウンド.wav"))
    sound2=QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile("サウンド2.wav"))
    sound_list=[sound,sound2]
    save_file2=open("sound_list.dat","wb")
    pickle.dump(sound_list,save_file2)
    save_file2.close()
    
```

しかし、これを実行すると

```

    TypeError: can't pickle QMediaContent objects
    
```

や

```

    TypeError: can't pickle QPixmap objects
    
```

と出力されます。QPixmapやQMediaはpickleに対応していないようです。これらの情報を一つのファイルにまとめるにはどうすればよいのでしょうか。pickle以外に対応しているものはあるのでしょうか。それともpickleでもうまくやれば十分カバーできるのでしょうか。
CC BY-SA 4.0
2018-05-21T04:42:02.680
44119
2018-10-07T07:11:13.683
26529
question
python pyqt
QPixmapやQMediaの画像やサウンドをpickleのように一つにまとめたい
**QPixmapオブジェクトを保存する方法について**  
既に解決されたようですが、既存の[pyqt](/questions/tagged/pyqt "'pyqt'
のタグが付いた質問を表示")を使った方法を残しておきます。  
[pyqt](/questions/tagged/pyqt "'pyqt'
のタグが付いた質問を表示")では、以下の方法によって、簡単にセーブとロードを行うことが出来ます。

```

    file = QtCore.QFile(anyfile)
    file.open(QtCore.QIODevice.ReadWrite)
    out = QtCore.QDataStream()
    image = QtGui.QPixmap()#An object you costomized.Please not use empty pixmap!
    image = image.toImage()
    out << image#C++でよくつかわれる記号
    
```

次に、取り出すときです。

```

    file = QtCore.QFile(the same file)
    file.open(QtCore.QIODevice.ReadOnly)
    out = QtCore.QDataStream()
    image = QtGui.QPixmap()#Please prepare empty pixmap object
    image = image.toImage()
    out >> image#C++でよくつかわれる記号 記号が逆になっています。
    
```

**waveファイルの保存について**  
次に、[wave](/questions/tagged/wave "'wave' のタグが付いた質問を表示")ファイルについてです。

質問者様は、`scipy.io.wave`で実装されたようですが、私は[python](/questions/tagged/python "'python'
のタグが付いた質問を表示")標準の[wave](/questions/tagged/wave "'wave'
のタグが付いた質問を表示")で実装してみました。既にご存知かもと思いますが、[wave](/questions/tagged/wave "'wave'
のタグが付いた質問を表示")ファイルやほかの音声データファイルには、最初にたくさんの識別情報が含まれています。

```

    import wave
    wave_data = wave.open("any_file.wav","rb")
    wave_read_data = wave_data.getfp().read()
    wave_data_nchannels = wave_data.getnchannels()
    wave_data_sampwidth = wave_data.getsampwidth()
    wave_data_framerate = wave_data.getframerate()
    wave_data_nframes = wave_data.getnframes()
    wave_data_comptype = wave_data.getcomptype()
    wave_data_compname = wave_data.getcompname()
    wave_byte_data = QtCore.QByteArray(wave_read_data)
    
    out.writeInt8(self.wave_data_nchannels)
    out.writeInt8(self.wave_data_sampwidth)
    out.writeInt64(self.wave_data_framerate)
    out.writeInt64(self.wave_data_nframes)
    out.writeQString(self.wave_data_comptype)
    out.writeQString(self.wave_data_compname)
    wave_data_byte = QtCore.QByteArray(self.wave_byte_data)
    out << wave_data_byte
    
```

それらを、先ほどと同じ要領で、`QDataStream`に格納します。

これらを取り出す時には同じ要領でとりだします。

```

    wave_data_nchannels = out.readInt8()
    wave_data_sampwidth = out.readInt8()
    wave_data_framerate = out.readInt64()
    wave_data_nframes = out.readInt64()
    wave_data_comptype = out.readQString()
    wave_data_compname = out.readQString()
    wave_byte_data = QtCore.QByteArray()
    out >> wave_byte_data
    
```

この後、空のwaveファイルに入れ込みます。

```

    p = wave.open("temporary.wav","wb")#一時的なwavファイルを作成する。     
    p.setnchannels(wave_data_nchannels)   
    p.setsampwidth(wave_data_sampwidth)
    p.setframerate(wave_data_framerate)
    p.setnframes(wave_data_nframes)
    p.setcomptype(wave_data_comptype)
    p.writeframes(wave_byte_data.data())
    #音を発生させる。            
    QtGui.QSound().play(p)
    p.close()
    
```

このように、扱うモジュールによっては、`QDataStream`がとる型や順番も異なります。  
`scipy.io.wave`ファイルは、少し制限があるような書き込みがされていましたので、  
もしこちらをご検討いただければ嬉しいです。

自己解決された方法でも問題ないとは思いますが、このやり方でも、実体としての`wav`拡張子ファイルや、`png`,`JPEG`,`gif`,`svg`等の`image`ファイル自体がバイナリ化され、常にどこでも取り出し行う事ができるようになります。[qt](/questions/tagged/qt
"'qt' のタグが付いた質問を表示")をお使いであれば、この方法もご検討ください。`temporary
file`は、音を再生するための、使いまわしのファイルです。

`QImage`や、`QByteArray`、`QColor`,`QPoint`,`QSize`,`QRect`等、`Qt`独自の型で定義されているオブジェクトであり、[python](/questions/tagged/python
"'python' のタグが付いた質問を表示")の通常のデータに直すのが、面倒なデータは、そのままバイナリ化できるようになっているです。

逆に、`int`型や`str`型を、`<<`とか`>>`でデータに格納しようとすると、怒られますので,ちゃんとした`writeInt8~64`と`readInt8~64`メソッドを利用するようにしてください。
CC BY-SA 4.0
2018-05-21T06:08:09.473
44121
2018-10-07T07:11:13.683
2018-10-07T07:11:13.683
24284
24284
44119
answer