LINUX.ORG.RU

PyQT Threads


0

0

Нужно по кнопочке запускать thread который будет что-то делать и по результатам его работы будут обновляться QLabel's, QTextEdit, QProgressBar, etc... Вобщем-то у меня она сейчас работает, но как-то очень криво. Ругается на QFont: It is not safe to use text and fonts outside the GUI thread, хотя их не трогаю, при перетаскивании окашка прогресс бар перерисовываться перестаёт... Вообщем: Можно примерчик работы?

P.S Python 2.5, Qt 4.2.2

anonymous

Ответ на: комментарий от ero-sennin

И ещё. Каким образом это сделать (class Display), если интерфейс сделан в QT Disigner, а подгружается он потом с помощью uic.loadUi()?

anonymous
()
Ответ на: комментарий от anonymous

> А стандартный thread использовать низя?

Подозреваю, что будут разные проблемы. Попробуй, расскажешь. :)

ero-sennin ★★
()
Ответ на: комментарий от anonymous

> И ещё. Каким образом это сделать (class Display), если интерфейс сделан в QT Disigner, а подгружается он потом с помощью uic.loadUi()?

Рисуешь в Дезигнере класс DisplayBase, потом наследуешь от него свой класс Display и переопределяешь в нём метод customEvent.

ero-sennin ★★
()
Ответ на: комментарий от ero-sennin

Как раз ранее я использовал стандартный thread. Работало, но криво. Насчёт переопределения. Вылетает с ошибкой: QThread: Destroyed while thread is still running QObject::killTimers: timers cannot be stopped from another thread

Thread вызывается по нажатию кнопки (функция on_..._pressed), переодически в нём вызывается LogEvent, который добавляет в TextEdit строчку, после того как всё сделано ( в самом конце run) стоит QtGui.QApplication.postEvent(self.event_receiver, UpdateEvent()), за которым следит функция главного класса customEvent.

Поначалу она вылетала сразу по нажатию кнопки. Добавил time.sleep(0.1) в конце on_ _pressed, перестала. Но как только доходит до UpdateEvent() всё равно вылет. :(

что я делаю не так?

anonymous
()
Ответ на: комментарий от ero-sennin

Показывать весь код стыдно. ^_^. Вырезал лишнее.

class LogEvent(QtCore.QEvent):
    def __init__(self, data):
        QtCore.QEvent.__init__(self, QtCore.QEvent.User)
        self.data = data
		
class UpdateEvent(QtCore.QEvent):
	def __init__(self):
		QtCore.QEvent.__init__(self, QtCore.QEvent.User)

class QTextLog(QtGui.QTextEdit):
    def customEvent(self, event):
        if isinstance (event, LogEvent):
            self.append(event.data)

class TreeCover(QtCore.QThread):
	def __init__(self, event_receiver, path):
		QtCore.QThread.__init__(self)
		self.event_receiver = event_receiver
		self.path=path
		self.irun=True
		
	def run(self):
		if self.irun==True:
			self.tree(self.path)
			self.run=False
			QtGui.QApplication.postEvent(self.event_receiver, UpdateEvent())
			time.sleep(0.1)

class MyQT(QtGui.QWidget):
	def __init__(self, *args):
		global path
		QtGui.QWidget.__init__(self, *args)
		uic.loadUi("untitled.ui", self)
		self.Picture = QtGui.QPixmap("default.jpg")
		self.label_5.setPixmap(self.Picture)
		self.edit_path.setText(path)
		self.textlog=QTextLog()
		self.tabWidget.insertTab(2, self.textlog, "Лог")

	@QtCore.pyqtSignature("")
	def on_pushButton_3_clicked(self):
		global path, result
		path=self.edit_path.text().toUtf8()
		path=unicode(path, "utf8")
		tree = TreeCover(self.textlog, path)
		tree.start()
		time.sleep(0.1)

	def customEvent(self, event):
		if isinstance (event, UpdateEvent):
			self.test() #обновляет виджеты

app = QtGui.QApplication(sys.argv)
widget = MyQT()
widget.show()
app.exec_()

anonymous
()
Ответ на: комментарий от ero-sennin

Часть 1.

<ui version="4.0" > <class>Form</class> <widget class="QWidget" name="Form" > <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>601</width> <height>328</height> </rect> </property> <property name="windowTitle" > <string>Cyxapeff Cover Found</string> </property> <property name="windowIcon" > <iconset>default.jpg</iconset> </property> <widget class="QTabWidget" name="tabWidget" > <property name="windowModality" > <enum>Qt::NonModal</enum> </property> <property name="enabled" > <bool>true</bool> </property> <property name="geometry" > <rect> <x>0</x> <y>0</y> <width>601</width> <height>330</height> </rect> </property> <property name="sizePolicy" > <sizepolicy> <hsizetype>7</hsizetype> <vsizetype>7</vsizetype> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize" > <size> <width>581</width> <height>330</height> </size> </property> <property name="sizeIncrement" > <size> <width>0</width> <height>0</height> </size> </property> <property name="tabPosition" > <enum>QTabWidget::East</enum> </property> <property name="tabShape" > <enum>QTabWidget::Rounded</enum> </property> <property name="currentIndex" > <number>0</number> </property> <widget class="QWidget" name="tab" > <attribute name="title" > <string>Основное</string> </attribute> <widget class="QLabel" name="album" > <property name="geometry" > <rect> <x>110</x> <y>110</y> <width>221</width> <height>16</height> </rect> </property> <property name="text" > <string/> </property> </widget> <widget class="QLabel" name="artist" > <property name="geometry" > <rect> <x>110</x> <y>80</y> <width>211</width> <height>16</height> </rect> </property> <property name="text" > <string/> </property> </widget> <widget class="QLabel" name="dir" > <property name="geometry" > <rect> <x>110</x> <y>140</y> <width>211</width> <height>16</height> </rect> </property> <property name="text" > <string/> </property> </widget> <widget class="QLabel" name="label_3" > <property name="geometry" > <rect> <x>20</x> <y>10</y> <width>31</width> <height>16</height> </rect> </property> <property name="text" > <string>Папка</string> </property> </widget> <widget class="QLineEdit" name="edit_path" > <property name="geometry" > <rect> <x>60</x> <y>10</y> <width>341</width> <height>20</height> </rect> </property> </widget> <widget class="QPushButton" name="pushButton_3" > <property name="geometry" > <rect> <x>500</x> <y>10</y> <width>75</width> <height>23</height> </rect> </property> <property name="text" > <string>Искать</string> </property> </widget> <widget class="QPushButton" name="open_path" > <property name="geometry" > <rect> <x>410</x> <y>10</y> <width>75</width> <height>23</height> </rect> </property> <property name="text" > <string>Открыть</string> </property> </widget> <widget class="QLabel" name="label" > <property name="geometry" > <rect> <x>30</x> <y>40</y> <width>46</width> <height>14</height> </rect> </property> <property name="text" > <string>Артист:</string> </property> </widget>

anonymous
()
Ответ на: комментарий от anonymous

Часть 2. <widget class="QLabel" name="label_2" > <property name="geometry" > <rect> <x>30</x> <y>70</y> <width>46</width> <height>14</height> </rect> </property> <property name="text" > <string>Альбом</string> </property> </widget> <widget class="QLabel" name="label_4" > <property name="geometry" > <rect> <x>30</x> <y>100</y> <width>71</width> <height>16</height> </rect> </property> <property name="text" > <string>Дириктория</string> </property> </widget> <widget class="QPushButton" name="save" > <property name="geometry" > <rect> <x>20</x> <y>130</y> <width>291</width> <height>31</height> </rect> </property> <property name="text" > <string>Сохранить</string> </property> </widget> <widget class="QGroupBox" name="groupBox" > <property name="geometry" > <rect> <x>20</x> <y>170</y> <width>301</width> <height>91</height> </rect> </property> <property name="title" > <string>Настройки</string> </property> <widget class="QCheckBox" name="checkBox_2" > <property name="geometry" > <rect> <x>10</x> <y>40</y> <width>281</width> <height>19</height> </rect> </property> <property name="text" > <string>Автосохранение</string> </property> </widget> <widget class="QPushButton" name="pushButton" > <property name="geometry" > <rect> <x>210</x> <y>20</y> <width>75</width> <height>24</height> </rect> </property> <property name="text" > <string>Обновить</string> </property> </widget> <widget class="QCheckBox" name="proxy" > <property name="geometry" > <rect> <x>10</x> <y>20</y> <width>191</width> <height>19</height> </rect> </property> <property name="text" > <string>Использовать анонимные прокси</string> </property> </widget>

anonymous
()
Ответ на: комментарий от anonymous

Часть 3. <widget class="QCheckBox" name="timeout" > <property name="geometry" > <rect> <x>10</x> <y>60</y> <width>70</width> <height>19</height> </rect> </property> <property name="text" > <string>Таймаут</string> </property> </widget> </widget> <widget class="QProgressBar" name="wait_bar" > <property name="enabled" > <bool>true</bool> </property> <property name="geometry" > <rect> <x>160</x> <y>280</y> <width>271</width> <height>16</height> </rect> </property> <property name="value" > <number>0</number> </property> <property name="alignment" > <set>Qt::AlignHCenter</set> </property> <property name="textVisible" > <bool>true</bool> </property> <property name="orientation" > <enum>Qt::Horizontal</enum> </property> <property name="invertedAppearance" > <bool>false</bool> </property> <property name="textDirection" > <enum>QProgressBar::TopToBottom</enum> </property> <property name="format" > <string>Поиск обложек</string> </property> </widget> <widget class="QPushButton" name="pushButton_5" > <property name="geometry" > <rect> <x>30</x> <y>270</y> <width>75</width> <height>23</height> </rect> </property> <property name="text" > <string>Назад</string> </property> </widget> <widget class="QPushButton" name="pushButton_4" > <property name="geometry" > <rect> <x>490</x> <y>270</y> <width>75</width> <height>23</height> </rect> </property> <property name="text" > <string>Далее</string> </property> </widget> <widget class="QLabel" name="label_5" > <property name="geometry" > <rect> <x>350</x> <y>40</y> <width>221</width> <height>211</height> </rect> </property> <property name="text" > <string/> </property> </widget> </widget> <widget class="QWidget" name="tab_3" > <attribute name="title" > <string>О программе</string> </attribute> </widget> </widget> </widget> <resources/> <connections/> </ui>

anonymous
()
Ответ на: комментарий от anonymous

Ты создаёшь объект tree в методе on_pushButton_3_clicked, потом запускаешь новую нить (tree.start()), а потом метод on_pushButton_3_clicked завершается, и объект tree автоматически удаляется, хотя нить ещё работает. У меня вообще на этом месте сегфолт происходит.

ero-sennin ★★
()
Ответ на: комментарий от ero-sennin

Угумс... сделал self.tree, если я понял правельно, то теперь он удаляться не должен до самого выхода из программы. Больше не вылетает. А после UpdateEvent тупо виснет. То есть customEvent не выполняется.

anonymous
()
Ответ на: комментарий от ero-sennin

Я имею ввиду customEvent основного класса. Он принимает UpdateEvent. С QTextLog и LogEvent всё ок. текст пишется.

P.S спасибо, что тратишь время на меня :)

anonymous
()
Ответ на: комментарий от ero-sennin

Не понимаю. :(
Основной класс создаёт self.tree = TreeCover(self.textlog, path, self) и стартует его нитью.

TreeCover содержит конструктур def __init__(self, event_receiver, path, event_receiver2):
self.event_receiver2 = event_receiver2
А перед завершением вызывает
QtGui.QApplication.postEvent(self.event_receiver2, UpdateEvent())

А customEvent(self, event) в основном классе ждёт этого события!
if isinstance (event, UpdateEvent):
self.test()

В результате висим.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.