Найти - Пользователи
Полная версия: PyQt4 Нужна помощь со Слотами.
Начало » GUI » PyQt4 Нужна помощь со Слотами.
1 2
Slon
Делаю GUI надстройку на скрипт и хочу реализовать такую схему:

Функционал:
При нажатии на кнопку(2) появляется окно в котором нужно указать расположение каталога. После выбора путь появляется в окне(1)


+——————–++——-+
+ ++ … +
+——————–++——-+
1 2
Во общем довольно фонарный алгоритм. Но так как я полный ламер в Qt реализовать у меня его не получается ((

Собственно нужна помощь в реализации. (Желательно ответы завязывать на Qt Designer)
pasaranax
Имхо, в данном случае кутэ дезигнер тока запутает, я вообще предпочитаю его использовать только если надо составить что-то вроде диалога настроек, с большим количеством мелких виджетов. Вот пример реализации того, что ты хочешь:
#!/usr/bin/env python2.6
# coding: utf-8
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.field = QLineEdit(self)
self.button = QPushButton(self)
layout = QHBoxLayout(self)
layout.addWidget(self.field)
layout.addWidget(self.button)

# ключевая часть начинается здесь
self.button.clicked.connect(self.selectFile)

def selectFile(self):
path = QFileDialog.getOpenFileName()
self.field.setText(path)
# и заканчивается здесь

if __name__ == '__main__':
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Slon
Спасибо, вроде то что надо. По ходу работы будут возникать еще вопросы, буду постить их сюда.



Объясни пожалуйста что не так:
В этом варианте работать отказывается, не могу понять где ошибка.

MyGui
from PyQt4 import QtCore, QtGui

class Ui_Form(object):
def setupUi(self, Widget):
Widget.setObjectName("Widget")
Widget.resize(259, 41)
self.horizontalLayout = QtGui.QHBoxLayout(Widget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.lineEdit = QtGui.QLineEdit(Widget)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.pushButton = QtGui.QPushButton(Widget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)

self.retranslateUi(Widget)
QtCore.QMetaObject.connectSlotsByName(Widget)

def retranslateUi(self, Widget):
Widget.setWindowTitle(QtGui.QApplication.translate("Widget", "Widget", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Widget", "...", None, QtGui.QApplication.UnicodeUTF8))
Main
import sys
from MyGui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class UIclass(QWidget, Ui_Form):
def __init__(self, parent=None):
QWidget.__init__(self,parent)
self.setupUi(self)

#self.pushButton.clicked.connect(self.selectFile)
self.connect(self.pushButton, SIGNAL("clicked()"), SLOT('self.selectFile'))

def selectFile(self):
path = QFileDialog.getOpenFileName()
self.lineEdit.setText(path)

app = QApplication(sys.argv)
w = UIclass()
w.show()
app.exec_()
pasaranax
1. У тебя либо с отступами косяк (selectFile получился внутри __init__, и вообще трехпробельные отступы), либо ты в selectFile зря указал параметр self. Если второе, то selectFile должен находиться выше, чем ты создаешь соединение.
2. Если ты хочешь использовать олдскульный способ соединения слотов-сигналов, то сначала надо функцию объявить, как слот с помощью декоратора, а потом все же правильно их соединить
        self.connect(self.pushButton, SIGNAL("clicked()"), self, SLOT("selectFile()"))

@pyqtSlot()
def selectFile(self):
path = QFileDialog.getOpenFileName()
self.lineEdit.setText(path)
3. либо так
self.connect(self.pushButton, SIGNAL("clicked()"), self.selectFile)
http://www.riverbankcomputing.com/static/Docs/PyQt4/pyqt4ref.html - читай 6 и 7 разделы
Slon
Еще вопрос:

При нажатии кнопки, вызывается os.system('cmd'), можно ли то, что там будет происходить далее, показывать в каком нибудь виджете?
pasaranax
Используй subprocess.Popen(“cmd”, stdin=myStdin, stdout=myStdout) и сделай классы myStdin и myStdout, полиморфные стандартным sys.stdin и sys.stdout, которые будут выводить и принимать ввод из виджетов. Вроде так, сам я такого не делал :)
gmorgunov
Зачем так сложно, можно напрямую использовать sys.stdin в subprocess. Есть main.py, в которой textEdit и кнопка Start_new_process.
Есть программа widget.py, которая запускается процессом из main.py. Что-то набираете в textEdit main.py, нажимаете кнопку Start_new_process - это отображается в textEdit widget.py. Из комментариев, думаю, станет более понятно. Только поставьте свой полный путь к программе (“/home/mike/slot_py/widget.py”).
main.py
 # coding: utf-8
import sys, subprocess
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class MainWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self,parent)
self.button = QPushButton("Start_new_process")
self.textEdit=QTextEdit()

layout = QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.textEdit)
self.setLayout(layout)

self.connect(self.button, SIGNAL("clicked()"), SLOT('new_process()'))

@pyqtSignature('') # новое, вместо QtCore.pyqtSlot(),
def new_process(self): # принимает аргументом строку
print 'in SLOT'
text=self.textEdit.toPlainText().toUtf8()

# запускаем процесс, stdin запущенного процесса - subprocess.PIPE
p=subprocess.Popen("/home/mike/slot_py/widget.py", shell=True, stdin=subprocess.PIPE)
# записываем text в stdin запущенного процесса
p.communicate(text)

if __name__=='__main__':
app = QApplication(sys.argv)
w =MainWidget()
w.show()
sys.exit(app.exec_())
widget.py
# coding: utf-8
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self,parent)
self.textEdit = QTextEdit()

text=sys.stdin.read() # читаем станд. ввод
text=unicode(text, "utf-8") # преобразуем utf-8 в unicode
self.textEdit.setText(QString(text)) # text ---> self.textEdit

layout = QVBoxLayout()
layout.addWidget(self.textEdit)
self.setLayout(layout)

if __name__=='__main__':
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Slon
Мне пока не совсем понятно как работать с subpracess'om. Но я почти уверен что не получиться у меня сделать этот вывод =(

Объясню чего я вообще делаю: Я для тренировки своял скрипт и потом довоял интерфейс для dd.exe for Win. Тот функционал что я на первом этапе планировал, я сделал. Но получить вывод от этой программы у меня не получается ни так (dd.exe –help > c:\temp.txt) ни через субпроцессы:
p=subprocess.Popen("dd --list", shell=True, stdout=subprocess.PIPE)
rez = p.communicate()
print (rez)

>>>(b'', None)
Просто если получить вывод от параметра (–progress (он выводит количество скопированных мб)), то нехитрым способом можно бы было сделать прогресбар.
gmorgunov
У меня Linux, все выводится:
Python 2.6 (r26:66714, Dec  3 2008, 06:05:48) 
[GCC 4.3.2 [gcc-4_3-branch revision 141291]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, subprocess
>>> p=subprocess.Popen("dd --help", shell=True, stdout=subprocess.PIPE)
>>> result=p.communicate()
>>> print result[0]
Использование: dd [ОПЕРАНД]...
или: dd КЛЮЧ
Копирует файл, преобразует и форматирует в зависимости от операндов.
...
pasaranax
Slon, а ты берешь в расчет то, что при перенаправлении вывода в файл (“dd.exe –help > c:\temp.txt”) у тебя ничего не будет выводиться в консоль?
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