I have a function that requires a thread, I'm using a QThread
to handle it, in this function there are some win32com
calls, but they are raising AttributeError
.
Why is that happening and can I fix it?
Here's some code:
class MyThread(QtCore.QThread):
def __init__(self):
super(MyThread, self).__init__()
def run(self):
FB2K = foobar()
while True:
CurrentVolume = float(FB2K.currentVolumeLevel().strip('dB'))
FB2K.setVolumeLevel(CurrentVolume - 0.1)
sleep(1)
class MainFrame(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton(self)
self.thread = MyThread()
self.button.clicked.connect(self.my_function)
def my_function(self):
self.thread.start()
If I run this script and click on the button it raises the AttributeError:
Traceback (most recent call last):
File "C:/My Python Programs/foobar_acess.py", line 18, in run
CurrentVolume = float(FB2K.currentVolumeLevel().strip('dB'))
File "C:\Python27\pyfoobar.py", line 50, in currentVolumeLevel
return str(playback.Settings.Volume) + "dB"
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 516, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.Settings
pyfoobar is a module that access foobar2000 it can set volume, catch song names and etc.
It's build around the win32com module, playback(the one raising the error) is:
playback = win32com.client.Dispatch("Foobar2000.Application.0.7")
The code under run() works fine if not run by QThread, but it freezer the UI because of the while loop.
Not sure why this fixed it. But here is how:
class MyThread(QtCore.QThread):
def __init__(self):
super(MyThread, self).__init__()
def run(self):
import win32com.client
import pythoncom
pythoncom.CoInitialize()
ProgID = "Foobar2000.Application.0.7"
foobar_COM_object = win32com.client.Dispatch(ProgID)
playback = foobar_COM_object.Playback
while True:
playback.Settings.Volume -= 0.1
sleep(1)
class MainFrame(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton(self)
self.thread = MyThread()
self.button.clicked.connect(self.my_function)
def my_function(self):
self.thread.start()