Foros del Web » Programando para Internet » Python »

Evento PyQt4

Estas en el tema de Evento PyQt4 en el foro de Python en Foros del Web. Hola a todos! He comenzado a aprender un poco acerca de como realizar una GUI en python y para ello, he estado mirando algo de ...
  #1 (permalink)  
Antiguo 20/08/2010, 05:49
 
Fecha de Ingreso: junio-2010
Mensajes: 17
Antigüedad: 14 años, 5 meses
Puntos: 0
Mensaje Evento PyQt4

Hola a todos!

He comenzado a aprender un poco acerca de como realizar una GUI en python y para ello, he estado mirando algo de PyQt. Me he quedado atascado en este punto que no se realmente en que falla.
Mi intencion es añadir un boton para cerrar la aplicacion y que requiera de una confirmacion para ejecutar la accion. El código que he elaborado es el siguiente:

Código Python:
Ver original
  1. import sys
  2. from PyQt4 import QtGui, QtCore
  3.  
  4. class VentanaPrincipal(QtGui.QWidget):
  5.     def __init__(self, parent=None):
  6.         QtGui.QWidget.__init__(self, parent)
  7.  
  8. #Colocacion de la ventana en pantalla y cambio de icono de la aplicacion.
  9.         self.setGeometry(250, 200, 800, 600)
  10.         self.setWindowTitle(
  11.         'prueba')
  12.         self.setWindowIcon(QtGui.QIcon(
  13.         'C:/dibujo.GIF'))
  14.  
  15. #Definicion de botón QUIT para salir de la aplicación.
  16.         quit = QtGui.QPushButton('Salir', self)
  17.         quit.setGeometry(730, 555, 60, 35)
  18.         self.connect(quit, QtCore.SIGNAL('clicked()'),QtGui.qApp, QtCore.SLOT('quit()'))
  19.  
  20.  
  21.  
  22. #Definición de un evento para la salida del programa
  23.     def closeEvent(self, event):
  24.             reply = QtGui.QMessageBox.question(self, 'Confirmacion de cierre de aplicacion',"Desea cerrar la aplicacion?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
  25.             if reply == QtGui.QMessageBox.Yes:
  26.                 event.accept()
  27.             else:
  28.                 event.ignore()
  29.  
  30.  
  31. if __name__=="__main__":
  32.  
  33.     app = QtGui.QApplication(sys.argv)
  34.     window = VentanaPrincipal()
  35.     window.show()
  36.     sys.exit(app.exec_())

Con este código consigo que la confirmación se realice al pulsar la X de la esquina superior derecha, pero al pulsar el botón definido, se produce la salida del programa sin ningún tipo de confirmación (aparte de cerrarme el editor de código, por lo que seguramente ocurra algún error).

Alguien sabe dónde está el error?

Un saludo
  #2 (permalink)  
Antiguo 20/08/2010, 06:20
 
Fecha de Ingreso: junio-2010
Mensajes: 29
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

que error parece que todo hace lo que tu dices
  #3 (permalink)  
Antiguo 20/08/2010, 07:31
 
Fecha de Ingreso: junio-2010
Mensajes: 17
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

Cita:
Iniciado por llos Ver Mensaje
que error parece que todo hace lo que tu dices
Al menos en mi ordenador, al pulsar el botón Salir, no realiza la comprobacion que le he introducido.

Edito: Con el boton Salir no me refiero a la X de la esquina superior derecha, si no al boton que he creado para ello. Siento mi mala redaccion en el primer post, no quedo suficientemente explicado lo que me sucede.
  #4 (permalink)  
Antiguo 20/08/2010, 08:24
 
Fecha de Ingreso: junio-2010
Mensajes: 29
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

Cita:
Iniciado por fj87 Ver Mensaje
Al menos en mi ordenador, al pulsar el botón Salir, no realiza la comprobacion que le he introducido.

Edito: Con el boton Salir no me refiero a la X de la esquina superior derecha, si no al boton que he creado para ello. Siento mi mala redaccion en el primer post, no quedo suficientemente explicado lo que me sucede.
ok!! xdxd ya te pillo, el problema es que tu has modificado el closeEvent encambio cuando tu apretas la accion estas utilizando un quit, cerrar la ventana es diferente a quit(), te recomiento que en vez de hacer quit, ves a un metodo que te muestre el mensage. Si no sabes como dilo y e ayudo

Saludos!!
  #5 (permalink)  
Antiguo 20/08/2010, 09:13
 
Fecha de Ingreso: junio-2010
Mensajes: 17
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

Te agradeceria bastante si me ayudas a como hacerlo

Paralalemente a eso, estoy tratando de emplear un nuevo Slot para que un boton realice las funciones que yo considere oportunas. Para ello, realizo lo siguiente:

Código Python:
Ver original
  1. import sys
  2. import Ensayo as modulo_ensayo
  3. from PyQt4 import QtGui, QtCore
  4.  
  5. class VentanaPrincipal(QtGui.QMainWindow):
  6.     def __init__(self, parent=None):
  7.         QtGui.QMainWindow.__init__(self, parent)
  8.  
  9. #Colocacion de la ventana en pantalla y cambio de icono de la aplicacion.
  10.         self.setGeometry(250, 200, 800, 600)
  11.         self.setWindowTitle(
  12.         'prueba')
  13.         self.setWindowIcon(QtGui.QIcon("icono.gif"))
  14.         self.center()
  15.         self.statusBar().showMessage('Listo')
  16.  
  17.  
  18.  
  19.         bnuevoensayo= QtGui.QAction(QtGui.QIcon('Iconos\martillo.png'), 'Nuevo Ensayo', self)
  20.         bnuevoensayo.setShortcut('F9')
  21.         bnuevoensayo.setStatusTip('Nuevo Ensayo')
  22.         self.connect(bnuevoensayo, QtCore.SIGNAL('clicked()'), self.slot_ensayo())
  23.    
  24.        
  25. #Barra de Menu
  26.         menubar = self.menuBar()
  27.  
  28. #Menu Archivo
  29.         marchivo = menubar.addMenu('&Archivo')
  30.         marchivo.addAction(bnuevoensayo)
  31.  
  32.  
  33. #Menu Opciones
  34.         mopciones = menubar.addMenu('&Opciones')
  35.  
  36.  
  37. #Menu Ayuda
  38.         mayuda = menubar.addMenu('&Ayuda') #Ayuda
  39.  
  40.  
  41. #Barra de herramientas
  42.        
  43.         toolbar = self.addToolBar('prueba')
  44.         toolbar.addAction(bnuevoensayo)
  45.  
  46. #Funcion para centrar la ventana en la pantalla
  47.     def center(self):
  48.         screen = QtGui.QDesktopWidget().screenGeometry()
  49.         size =  self.geometry()
  50.         self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
  51.    
  52.     def slot_ensayo(self):
  53.         modulo_ensayo.Ensayo()
  54.  
  55. if __name__=="__main__":
  56.  
  57.     app = QtGui.QApplication(sys.argv)
  58.     window = VentanaPrincipal()
  59.     window.show()
  60.     sys.exit(app.exec_())

Import Ensayo, se refiere a un modulo creado por mi, que funciona perfectamente sin la GUI. Mi problema en este caso reside en que realiza la accion del boton antes de iniciar siquiera la ventana, saltando posteriormente un error en Pydev indicandome que el tercer argumento de self.connect no es el adecuado.

El modulo Ensayo posee en su interior una funcion simple que no recibe argumentos de ningun tipo y finaliza con un return.

Espero no resultarte pesado jejeje

Muchas gracias por la ayuda!
  #6 (permalink)  
Antiguo 20/08/2010, 10:14
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Evento PyQt4

El evento para cerrar es close(), no quit()
Por otro lado, es mejor asignar la señal a pressed() en vez de a clicked(), para que así se realice la acción si el botón se pulsa via teclado.

El problema con el módulo debe ser que algo se ejecuta cuando el módulo se carga, tendrás que modificar el módulo o cargarlo de forma más "controlada" en el momento apropiado. Es complicado aconsejar algo más sin ver el código real.


Saludos.
  #7 (permalink)  
Antiguo 20/08/2010, 10:31
 
Fecha de Ingreso: junio-2010
Mensajes: 29
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

Hey!!!

Tienes que imvestigar mas!! el ultimo problema que pusiste es pq el tercer argumento no puede ser una funcion, si no un nombre de funcion, a parte tampoco iria, ya que el evento no es clicked, si investigas un poco, una accion, no tiene ningun evento clicked , (no se si me explico dimelo y te lo explico mejor), el codigo resultante seria:

Código Python:
Ver original
  1. # -*- coding: utf-8 -*-
  2. import sys
  3. from PyQt4 import QtGui, QtCore
  4.  
  5. class VentanaPrincipal(QtGui.QMainWindow):
  6.     def __init__(self, parent=None):
  7.         QtGui.QMainWindow.__init__(self, parent)
  8.  
  9. #Colocacion de la ventana en pantalla y cambio de icono de la aplicacion.
  10.         self.setGeometry(250, 200, 800, 600)
  11.         self.setWindowTitle('prueba')
  12.         self.setWindowIcon(QtGui.QIcon("icono.gif"))
  13.         self.center()
  14.         self.statusBar().showMessage('Listo')
  15.  
  16.  
  17.  
  18.         bnuevoensayo= QtGui.QAction(QtGui.QIcon('Iconos\martillo.png'), 'Nuevo Ensayo', self)
  19.         bnuevoensayo.setShortcut('F9')
  20.         bnuevoensayo.setStatusTip('Nuevo Ensayo')
  21.         self.connect(bnuevoensayo, QtCore.SIGNAL('triggered()'), self.slot_ensayo)
  22.    
  23.        
  24. #Barra de Menu
  25.         menubar = self.menuBar()
  26.  
  27. #Menu Archivo
  28.         marchivo = menubar.addMenu('&Archivo')
  29.         marchivo.addAction(bnuevoensayo)
  30.  
  31.  
  32. #Menu Opciones
  33.         mopciones = menubar.addMenu('&Opciones')
  34.  
  35.  
  36. #Menu Ayuda
  37.         mayuda = menubar.addMenu('&Ayuda') #Ayuda
  38.  
  39.  
  40. #Barra de herramientas
  41.        
  42.         toolbar = self.addToolBar('prueba')
  43.         toolbar.addAction(bnuevoensayo)
  44.  
  45. #Funcion para centrar la ventana en la pantalla
  46.     def center(self):
  47.         screen = QtGui.QDesktopWidget().screenGeometry()
  48.         size =  self.geometry()
  49.         self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
  50.    
  51.     def slot_ensayo(self):
  52.         print "hola"
  53.  
  54. if __name__=="__main__":
  55.  
  56.     app = QtGui.QApplication(sys.argv)
  57.     window = VentanaPrincipal()
  58.     window.show()
  59.     sys.exit(app.exec_())


Despues para el otro probleme te sugiero esta solucion:

Código Python:
Ver original
  1. # -*- coding: utf-8 -*-
  2. import sys
  3. from PyQt4 import QtGui, QtCore
  4.  
  5. class VentanaPrincipal(QtGui.QWidget):
  6.     def __init__(self, parent=None):
  7.         QtGui.QWidget.__init__(self, parent)
  8.  
  9. #Colocacion de la ventana en pantalla y cambio de icono de la aplicacion.
  10.         self.setGeometry(250, 200, 800, 600)
  11.         self.setWindowTitle(
  12.         'prueba')
  13.         self.setWindowIcon(QtGui.QIcon(
  14.         'C:/dibujo.GIF'))
  15.  
  16. #Definicion de botón QUIT para salir de la aplicación.
  17.         quit = QtGui.QPushButton('Salir', self)
  18.         quit.setGeometry(730, 555, 60, 35)
  19.         self.connect(quit, QtCore.SIGNAL('clicked()'), self.cerrar)
  20.  
  21.  
  22.  
  23. #Definición de un evento para la salida del programa
  24.     def closeEvent(self, event):
  25.       event.ignore()
  26.       self.cerrar()
  27.     def cerrar(self):
  28.             reply = QtGui.QMessageBox.question(self, 'Confirmacion de cierre de aplicacion',"Desea cerrar la aplicacion?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
  29.             if reply == QtGui.QMessageBox.Yes: sys.exit()
  30.  
  31.  
  32. if __name__=="__main__":
  33.  
  34.     app = QtGui.QApplication(sys.argv)
  35.     window = VentanaPrincipal()
  36.     window.show()
  37.     sys.exit(app.exec_())


Si quieres mas ayuda, enviame un mp y te digo mi mail, y si quieres te ayudo en lo que estes haciendo. No encuentro a mucha gente interesada en PyQt4 XDXD

Saludos


Ups, acabo de leer lo del quit que ha dicho el, i si funciona es mejor a mi solucion, aunque piensa que no es necessario saberlo todo siempre, tienes que buscar una solucion con las herramientas que tienes.
  #8 (permalink)  
Antiguo 20/08/2010, 13:27
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Evento PyQt4

Cita:
Iniciado por llos Ver Mensaje
el tercer argumento no puede ser una funcion, si no un nombre de funcion
Aclarando: no puede ser una llamada a una función, sino el nombre de la misma.

Cuando contesté lo hice viendo solamente el primer mensaje con código, no el segundo. Me parece que el problema está en poner slot_ensayo() en vez de slot_ensayo (sin los () ), mucho más sencillo que lo que estaba pensando al escribir mi respuesta.


Saludos.
  #9 (permalink)  
Antiguo 20/08/2010, 14:11
 
Fecha de Ingreso: junio-2010
Mensajes: 29
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

todo y con eso, el objeto que esta conectando no tiene ningun evento clicked, por lo tanto nunca ira a esa funcion.

Saludos
  #10 (permalink)  
Antiguo 21/08/2010, 04:39
 
Fecha de Ingreso: junio-2010
Mensajes: 17
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Evento PyQt4

Muchas gracias a los dos por vuestras respuestas.
Realizando la modificación que me habéis comentado funciona sin problemas! Era lo que comentabáis, tiene que indicarse el nombre de la función, no la llamada a la propio función.

Ahora empezaré a realizar algo de manejo de varias ventanas a la vez.
Muchas gracias a los dos nuevamente!

llos, te envio un mp ahora. Nunca está de menos intercambiar información con alguien que pueda resultar beneficiosa para los dos (aunque no se si podré yo contarte a ti algo nuevo jejeje)

Un saludo!
  #11 (permalink)  
Antiguo 26/03/2011, 11:27
 
Fecha de Ingreso: marzo-2011
Mensajes: 1
Antigüedad: 13 años, 7 meses
Puntos: 0
Respuesta: Evento PyQt4

Estoy empezando con PyQt, y relacionado con el tema de este post, como puedo hacer para cerrar varias ventanas simultáneamente?

Acá tengo este codigo de un programa que estoy empezando y usa 2 clases que muestro pero quiero hacer que si se cierra una la otra también.

Código:
#!/usr/bin/python
# -*- coding: utf-8 -*-

# points.py

import sys, random
import math,time
from PyQt4 import QtGui, QtCore

Lx=400
Ly=400
xn=-3
xm=3
yn=xn #Escala cuadrada
ym=xm
#Se espera que con solo asegurar un fl todo se opere como flotante
EscalaX=(float(xm)-xn)/Lx 
EscalaY=(float(ym)-yn)/Ly 
Soluciones=[]
def Circulo (x0,y0,r):
	#Definir la paremetrizacion
	#Aprox cuantos px se ocupan para dibujar la circunferencia.
	n=(2*math.pi*r)/EscalaX
	#Aumentando el numero un 5%
	n=1.05*n
	#Se requiere un numero entero de pixeles
	n=int(n)
	#El circulo se parametriza facilmente usando polares
	#Se divide 2pi entre el numero de pasos que se requieren
	paso=(2*math.pi)/n
	#Se inicializa el parametro, contador y arreglo de soluciones
	t=0
	cont=0
	S=[]	
	#Generar las soluciones para el circulo parametrizado
	while cont<n:
		S.append([float(r*math.cos(t)+x0),float(r*math.sin(t)+y0)])
		t=t+paso
		cont=cont+1
	if S!=[]:
		return S
#Prueba de la matriz soluciones y de la funcion circulo
Soluciones=Soluciones+Circulo(1,1,2)
Soluciones=Soluciones+Circulo(0,0,1)
Soluciones=Soluciones+Circulo(0,0,0.5)
Soluciones=Soluciones+Circulo(0,0,1.5)
Soluciones=Soluciones+Circulo(0,0,2)
print (Soluciones)
#Generar la matriz de pixeles
L=len(Soluciones)
Pix=[]
i=0
while i<L:
	Pix.append([int((Soluciones[i][0]-xn)/EscalaX),Ly-int((Soluciones[i][1]-yn)/EscalaY)])
	i=i+1
#Generar la matriz de soluciones mapeadas
L=len(Soluciones)
SolMap=[]
i=0
while i<L:
	#SolMap.append([(1.0/(math.sqrt(Soluciones[i][0]*Soluciones[i][0]+Soluciones[i][1]*Soluciones[i][1])))*math.cos(-math.atan(float(Soluciones[i][1])/Soluciones[i][0])),(1.0/(math.sqrt(Soluciones[i][0]*Soluciones[i][0]+Soluciones[i][1]*Soluciones[i][1])))*math.sin(-math.atan(Soluciones[i][1]/Soluciones[i][0]))])
	SolMap.append([Soluciones[i][0],Soluciones[i][1]])
	i=i+1
#Generar la matriz de pixeles mapeados
L=len(SolMap)
PixMap=[]
i=0
while i<L:
	PixMap.append([int((SolMap[i][0]-xn)/EscalaX),Ly-int((SolMap[i][1]-yn)/EscalaY)])
	i=i+1

#Clase para el interfaz grafico usando PyQt4
class Grafica(QtGui.QWidget):
  
    def __init__(self):
        super(Grafica, self).__init__()

        self.setGeometry(150, 100, Lx, Ly)
        self.setWindowTitle('Grafica a Mapear')
	self.setStyleSheet("QWidget {background-color: #FFFFFF}")



    def paintEvent(self, e):
      
        qp = QtGui.QPainter()
        qp.begin(self)
        self.drawPoints(qp)
        qp.end()
        
    def drawPoints(self, qp):
        
        size = self.size()
	#Dibujar los ejes
	qp.setPen(QtGui.QColor(0, 0, 0))
	x=float(xn)	
	while x<xm:
		qp.drawPoint(int((x-xn)/EscalaX),int((0-yn)/EscalaY))
		x=x+EscalaX
	y=float(yn)	
	while y<ym:
		qp.drawPoint(int((0-xn)/EscalaX),int((y-yn)/EscalaY))
		y=y+EscalaY	
	#Dibujar la matriz de soluciones	
	qp.setPen(QtCore.Qt.red)	
	L=len(Pix)
	i=0
	while i<L:
		#Se dibujan los pixeles de la matriz de soluciones
		qp.drawPoint(Pix[i][0],Pix[i][1])		
		i=i+1



class Mapeo(QtGui.QWidget):
  
    def __init__(self):
        super(Mapeo, self).__init__()

        self.setGeometry(650, 100, Lx, Ly)
        self.setWindowTitle('Mapeo de la grafica')
	self.setStyleSheet("QWidget {background-color: #FFFFFF}")



    def paintEvent(self, e):
      
        qp = QtGui.QPainter()
        qp.begin(self)
        self.drawPoints(qp)
        qp.end()
        
    def drawPoints(self, qp):
        
        size = self.size()
	#Dibujar los ejes
	qp.setPen(QtGui.QColor(0, 0, 0))
	x=float(xn)	
	while x<xm:
		qp.drawPoint(int((x-xn)/EscalaX),int((0-yn)/EscalaY))
		x=x+EscalaX
	y=float(yn)	
	while y<ym:
		qp.drawPoint(int((0-xn)/EscalaX),int((y-yn)/EscalaY))
		y=y+EscalaY	

	#Dibujar la matriz mapeada
	L=len(PixMap)
	i=0
	qp.setPen(QtGui.QColor(0, 255, 50))
	while i<L:
		#Dibujando los pixeles
		qp.drawPoint(PixMap[i][0],PixMap[i][1])		
		i=i+1

print SolMap
print (len(Soluciones))
print (len(SolMap))
print (len(PixMap))

app = QtGui.QApplication(sys.argv)

graf = Grafica()
graf.show()

mapeo = Mapeo()
mapeo.show()

sys.exit(app.exec_())
  #12 (permalink)  
Antiguo 27/03/2011, 16:53
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Evento PyQt4

La forma más adecuada es mediante un módulo o clase "contenedor", haciendo algo como

ventana1 = ClaseDeMiVentana1()
ventana2 = ClaseDeMiVentana2()

luego podés asociar el evento cerrar de la ventana1 a cualquier función de tu módulo, y hacer lo mismo con el evento cerrar de ventana2. incluso podrías hacer que la función que responde al evento de cerrar ventana1 lance el evento de cerrar la ventana2.

Tu código tal y como está ahora está entreverado de más, sin entrar en sus detalles creo que tendrías que organizarlo mejor.


Saludos.

Etiquetas: pyqt
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:16.