Найти - Пользователи
Полная версия: Несколько вопросов по PyQT4
Начало » GUI » Несколько вопросов по PyQT4
1 2
orgorg
Начал копать в сторону pyqt, прочитал небольшой обзор статей на русском(не очень много информации), и решил взять пример из статьи, и поставить на нем опыты :)
И так, код:
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
class AnyWidget(QtGui.QWidget):
def __init__(self,*args):
QtGui.QWidget.__init__(self,*args)
boxlay = QtGui.QHBoxLayout(self)
frame = QtGui.QFrame(self) # Фрейм
frame.setFrameShape(QtGui.QFrame.StyledPanel)
frame.setFrameShadow(QtGui.QFrame.Raised)

gridlay = QtGui.QGridLayout(frame) # Менеджер размещения элементов во фрейме

label = QtGui.QLabel(u"Метка",frame) # Текстовая метка.
gridlay.addWidget(label,0,0)

ln_edit = QtGui.QLineEdit(u"Винни Пух", frame) # Строковое поле ввода.
gridlay.addWidget(ln_edit,0,1)

radio_group = QtGui.QGroupBox(u"Выбор из двух", frame) # Рамка с надписью вокруг группы элементов.
radio_lay = QtGui.QVBoxLayout(radio_group) # Менеджер размещения элементов в рамке.
radio1 = QtGui.QRadioButton(u"Первый", radio_group) # Два зависимых
radio2 = QtGui.QRadioButton(u"Второй", radio_group) # переключателя
radio2.setChecked(True)
radio_lay.addWidget(radio1)
radio_lay.addWidget(radio2)
gridlay.addWidget(radio_group,1,0,3,1)

combo = QtGui.QComboBox(frame) # Поле ввода с раскрывающимся списком.
combo.addItem(u"Пятачок")
combo.setEditable(True)
gridlay.addWidget(combo,1,1)

spin = QtGui.QSpinBox(frame) # Целочисленное поле ввода с
spin.setValue(5) # кнопками инкремента/декремента.
gridlay.addWidget(spin,2,1)

check = QtGui.QCheckBox(u"Пометка", frame) # Независимый переключатель с
check.setCheckState(QtCore.Qt.Checked) # двумя состояниями.
gridlay.addWidget(check,3,1)

progress = QtGui.QProgressBar(frame) # индикатор прогресса
progress.setValue(70)
progress.setOrientation(QtCore.Qt.Horizontal)
gridlay.addWidget(progress,4,0,1,2)

btn_lay = QtGui.QHBoxLayout() # Менеджер размещения двух кнопок.
button1 = QtGui.QPushButton(u"Ок", frame)
button2 = QtGui.QPushButton(u"Отмена", frame)
btn_lay.addWidget(button1)
btn_lay.addWidget(button2)
gridlay.addLayout(btn_lay,5,0,1,2)
boxlay.addWidget(frame)
self.connect( button2, QtCore.SIGNAL("clicked()"),app, QtCore.SLOT("quit()") )
self.connect( button1, QtCore.SIGNAL("clicked()"),self,QtCore.SLOT("pew()"))
def pew(self):
spin.setValue(44)
if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
aw = AnyWidget()
aw.show()
sys.exit(app.exec_())
Конкретно, проблема вот в этой строчке:
 self.connect( button1, QtCore.SIGNAL("clicked()"),self,QtCore.SLOT("pew()"))
Соотвественно, сигнал-слот не работает. В чем моя ошибка? Передаю 3 аргументом self (ведь это его метод), но никакой реакции при нажатии на кнопку не наблюдаю. Спасибо!
pasaranax
button1.clicked.connect(self.pew)
gmorgunov
Привет.
Позвольте несколько замечаний:
1) Слот надо декорировать - http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#the-qtcore-pyqtslot-decorator.
2) spin должна быть “видна” в pew().
Вот так у меня в Linux работает(# - пометил исправления):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
class AnyWidget(QtGui.QWidget):
def __init__(self,*args):
QtGui.QWidget.__init__(self,*args)
boxlay = QtGui.QHBoxLayout(self)
frame = QtGui.QFrame(self) # Фрейм
frame.setFrameShape(QtGui.QFrame.StyledPanel)
frame.setFrameShadow(QtGui.QFrame.Raised)

gridlay = QtGui.QGridLayout(frame) # Менеджер размещения элементов во фрейме

label = QtGui.QLabel(u"Метка",frame) # Текстовая метка.
gridlay.addWidget(label,0,0)

ln_edit = QtGui.QLineEdit(u"Винни Пух", frame) # Строковое поле ввода.
gridlay.addWidget(ln_edit,0,1)

radio_group = QtGui.QGroupBox(u"Выбор из двух", frame) # Рамка с надписью вокруг группы элементов.
radio_lay = QtGui.QVBoxLayout(radio_group) # Менеджер размещения элементов в рамке.
radio1 = QtGui.QRadioButton(u"Первый", radio_group) # Два зависимых
radio2 = QtGui.QRadioButton(u"Второй", radio_group) # переключателя
radio2.setChecked(True)
radio_lay.addWidget(radio1)
radio_lay.addWidget(radio2)
gridlay.addWidget(radio_group,1,0,3,1)

combo = QtGui.QComboBox(frame) # Поле ввода с раскрывающимся списком.
combo.addItem(u"Пятачок")
combo.setEditable(True)
gridlay.addWidget(combo,1,1)

self.spin = QtGui.QSpinBox(frame) #####################################
self.spin.setValue(5) #####################################
gridlay.addWidget(self.spin,2,1) #####################################

check = QtGui.QCheckBox(u"Пометка", frame) # Независимый переключатель с
check.setCheckState(QtCore.Qt.Checked) # двумя состояниями.
gridlay.addWidget(check,3,1)

progress = QtGui.QProgressBar(frame) # индикатор прогресса
progress.setValue(70)
progress.setOrientation(QtCore.Qt.Horizontal)
gridlay.addWidget(progress,4,0,1,2)

btn_lay = QtGui.QHBoxLayout() # Менеджер размещения двух кнопок.
button1 = QtGui.QPushButton(u"Ок", frame)
button2 = QtGui.QPushButton(u"Отмена", frame)
btn_lay.addWidget(button1)
btn_lay.addWidget(button2)
gridlay.addLayout(btn_lay,5,0,1,2)
boxlay.addWidget(frame)
self.connect( button2, QtCore.SIGNAL("clicked()"),app, QtCore.SLOT("quit()") )
self.connect( button1, QtCore.SIGNAL("clicked()"),QtCore.SLOT("pew()"))

@QtCore.pyqtSlot("") ########################################
def pew(self): ########################################
self.spin.setValue(44) ########################################
if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
aw = AnyWidget()
aw.show()
sys.exit(app.exec_())
orgorg
Да, большое спасибо!
Но я так сказать, совместил оба способа, получилось немного не по мне, но думаю вполне читабельно в пределах ООП.
Каждый виджет(? кнопка, текстареа), я создаю через self.NameVar = Widget();
А коннкекты для соседних ф-ций осуществляю так
connect(varname,SLOT(…),self.pew())
orgorg
Начал смотреть в сторону потоков, и по привычке, перед тем как употреблять в своем софте, решил проверить новинку, и разобраться в работе(с потоками работа в первые, прошлый язык был без поддержки многопоточности).
Собственно, на основе примеров, и личных наблюдений создается код:
import Queue
import threading
import urllib,urllib2
import sys

THREAD = 10
class ClientThread(threading.Thread):

# Note that we do not override Thread's __init__ method.
# The Queue module makes this not necessary.

def run(self):
count = 0
# Have our thread serve "forever":
while True:
count=count+1
item = turn.get()
# Get a client out of the queue
# Check if we actually have an actual client in the client variable:
if turn.empty() == False:
page = self.get('http://'+item.strip())
if(page):
print 'Thread #:'+self.getName()+', item: '+item.strip()
else:
print 'Error in Connect: ' + item.strip()
turn.task_done()
else:
print 'Task done! Check-sites count: ' +str(count)

def get(self,page_address):
user_agent = 'Opera/9.25 (Windows NT 5.1; U; en)'
# Используем прокси +некоторые настройки
pageHandler = urllib2.build_opener(urllib2.HTTPHandler)
# Создаем запрос и загружаем страницу
requestData = urllib2.Request(page_address, None, {'User-Agent': user_agent})
try:
requestHandler = pageHandler.open(requestData,timeout=1000)
pageData = requestHandler.read().decode('utf-8')
requestHandler.close()
return(pageData)
except:
return(False)
# Create our Queue:
turn = Queue.Queue(0)

# Start two threads:
for x in xrange(THREAD):
ClientThread().start()
# Set up the server:

# Have the server serve "forever":
for newtask in open('./test.txt'):
turn.put(newtask)
Собственно, все бы хорошо, и основные ф-ции выполняются, но:
1) Если запустить приложение, то отработав все(??) сайты, софт зависает с последним потоком. Пытался писать в блоке else у проверки на empty() очереди, sys.exit(0), но скрипт пролетает мимо этой строчки, будто бы и нет ее. Возможно я упустил логику в приложении, и оно уходит в цикл?
2) Правильно ли я задаю таймаут ответа от срвера, в ф-ции инициализации дескриптора urllib, конкретно строка:
requestHandler = pageHandler.open(requestData,timeout=1000)
Интересно, где же я допустил ошибку\ошибки, прошу указать на них, или помочь советом. Ибо этого материала в книжке нет (Изучаем Python), а в офф-циальной документации все очень уж сухо для новичка.
Еще раз спасибо!

Забыл указать, что в test.txt лежат адреса сайтов-зеркал, которые необходимо проверять на доступность. НУ я думаю из кода это становится понятным.
orgorg
И еще один вопрос, в этот ряд.
Если к примеру, случилось некое события, во время выполнение работы потоков, как остановить их работу?
orgorg
Ну что, ребят, ни кто не подскажет?
truporez
threading.Event вам в помощь, с проверкой в самой нитке.
orgorg
Новая непонятка.
Есть гуишные интерфейс, пользователь вводит данные, жмет старт, и данные начинают обрабатываться в потоках(кол-во указывает пользователь). Во время обработки данных в потоках, в главное окно GUI (то есть - главные поток), будет выводится информация о результатах.
self.ui.textEdit.setPlainText('File: '+ target_file+' Code: '+str(page.status))
Qt Вываливает ошибку, “qobject cannot create children for a parent that is in a different thread”, из чего становится понятно, что из дочернего потока в главный поток херушки что дают передать. Как же быть? В интернете нашел примеры на С++, там решение кроется в переносе процесса в главный поток moveThread(threadName). Как с этим быть в питоне?
Андрей Светлов
Передать - дают. Через такую же Queue.Queue.
Манипулировать интерфейсом из рабочих потоков - нельзя. Даже если конкретная операция и “прокатывает”.
http://python.org/dev/peps/pep-3148/ сделан как раз для целей подобных вашей.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB