2014-11-10 3 views
2

제 생각에 Pyside에서는 QString이 삭제되었습니다. 파이썬 문자열을 QLineEdit에 쓸 수 있으며, QLineEdit을 읽을 때 유니 코드 문자열 (문자 당 16 비트)으로 반환됩니다.Pyside : QProcess.write (u'Test ')는 0L을 반환합니다

내 Gui 프로세스에서이 문자열을 QProcess를 사용하여 시작된 하위 프로세스에 쓰려고하면 작동하지 않고 0L 만 반환합니다 (아래 참조). str() 함수를 사용하여 유니 코드 문자열을 파이썬 문자열로 변경하면 self.my_process.write(str(u'test'))은 이제 4L을 반환합니다. 이 행동은 나에게 맞는 것 같지 않습니다.

누군가 QProcess.write()이 유니 코드 문자열에서 작동하지 않는 이유를 설명 할 수 있습니까?

(Pdb) PySide.QtCore.QString() 
*** AttributeError: 'module' object has no attribute 'QString' 
(Pdb) self.myprocess.write(u'test') 
0L 
(Pdb) self.myprocess.write(str(u'test')) 
4L 
(Pdb) 

답변

3

PySide 그것은 항상과 동등한 파이썬 유형에서 암시 적 변환을했다 등 QString, QStringList, QVariant, 같은 클래스를 제공 적이있다 - 그 PyQt는 용어로,이다, 그것은 단지 v2 API (PSEP 101를 참조 구현 상세 사항은).

그러나 유니 코드 문자열을 쓰려고 할 때 QProcess의 동작은 PyQt4와 비교하여 PySide에서 다소 손상된 것으로 보입니다. 여기 PyQt4에서 간단한 테스트가있다 :

Python 2.7.8 (default, Sep 24 2014, 18:26:21) 
[GCC 4.9.1 20140903 (prerelease)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from PyQt4 import QtCore 
>>> QtCore.PYQT_VERSION_STR 
'4.11.2' 
>>> p = QtCore.QProcess() 
>>> p.start('cat'); p.waitForStarted() 
True 
>>> p.write(u'fóó'); p.waitForReadyRead() 
3L 
True 
>>> p.readAll() 
PyQt4.QtCore.QByteArray('f\xf3\xf3') 

은 그래서 PyQt는 암시 QProcess.write()에 전달하기 전에 '라틴어-1'로 유니 코드 문자열을 인코딩 할 것으로 보인다 (물론 기대하는 중 const char * 또는 QByteArray). 그래서

Python 2.7.8 (default, Sep 24 2014, 18:26:21) 
[GCC 4.9.1 20140903 (prerelease)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from PySide import QtCore, __version__ 
>>> __version__ 
'1.2.2' 
>>> p = QtCore.QProcess() 
>>> p.start('cat'); p.waitForStarted() 
True 
>>> p.write(u'fóó'); p.waitForReadyRead() 
0L 
^C 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyboardInterrupt 

:

>>> p.write(u'fóó'.encode('utf-8')); p.waitForReadyRead() 
5L 
True 
>>> p.readAll() 
PyQt4.QtCore.QByteArray('f\xc3\xb3\xc3\xb3') 

은 이제 PySide와 어떻게되는지 보자 : 다른 인코딩을 원하는 경우, 명시 적으로 수행해야합니다 암시 인코딩, 대신을 제기하는 과정은 블록 오류 (버그 인 것 같습니다). 그러나 명시 적 인코딩으로 다시 시도하면 예상대로 작동합니다.

>>> p.start('cat'); p.waitForStarted() 
True 
>>> p.write(u'fóó'.encode('utf-8')); p.waitForReadyRead() 
5L 
True 
>>> p.readAll() 
PySide.QtCore.QByteArray('fóó') 
+0

고맙습니다. 좋은 설명; Pyside에있는 Qt의 거의 모든 것이 유니 코드이기 때문에 QProcess.write()가 다른 형식으로 인코딩 할 필요없이 유니 코드 문자열을 처리했을 것이라고 생각했을 것입니다. 나는 Pyside가 QProcess를 사용할 때 깨진 것 같아서 당신의 의견에 동의한다고 생각합니다. 현재 파이썬 일 때 자식 프로세스에 디버거를 연결하는 방법을 알지 못했습니다. QProcess가 차단되는 시점을 이해하는 데 도움이됩니다. dbus-python이 프로세스간에 의사 소통하는 더 좋은 방법이 될지 궁금합니다. –

+0

@bit_pusher. 어떤 시점에서, 유니 코드 객체는 항상 쓰기 전에 바이트로 인코딩되어야합니다. 직접 작성하는 방법은 없습니다. 유일한 문제는 인코딩이 암시 적으로 완료되었는지 여부입니다. 개인적으로, 나는 항상 이것을 피하고 올바른 인코딩을 사용하도록 설정했는지 확인해야합니다. 명시 적 (explicit)은 암묵적 (implicit)보다 낫습니다 (특히 인코딩의 경우). – ekhumoro

+0

왜 나는 유니 코드가 직접적으로 쓰여질 수 없는지 이해하지 못한다. 이해하기에 그들은 "바이트로 인코딩된다". 필자의 이해는 대부분의 유닉스와 파이썬에서 대부분의 언어의 각 문자에 대한 바이트를 정확하게 지정하는 UTF-8 유니 코드를 사용하며, 이것이 사실이면 UTF-8 바이트를 보내야합니다. 나는 또한 UTF-8이 상당히 안정적으로 탐지 될 수 있다고 생각한다. 실패한 조작 (이 경우 QProcess.write())에서 약간의 피드백을 주어야합니까? QProcess에서 이진 스트림이 아닌 텍스트 스트림이 사용되는 것으로 의심됩니다.이 문제에 대한 설명서를 직접 읽어 주시겠습니까? –