pyQt不同窗体间的值传递(二)——使用信号槽机制

    使用QT编程的精髓就在于信号槽机制的灵活运用,信号和槽机制可以使互不相关的对象绑定在一起,实现对象之间的通信。
    QT通过信号槽来传递和相应消息,与windows下消息机制相比,消息机制是基于回调函数,而Qt中用信号和槽来代替函数指针,使程序更安全简洁。
    信号和槽之间的绑定可以是一对一的,一对多,多对一。即一个信号与一个槽连接,一个信号与多个槽相连,多个信号与一个槽相连,信号和信号直接相连。所有从QObject或其子类(例如QWidget类)派生的类都能够包含信号和槽。通过QObject的connection()函数来实现信号和槽的连接:
 
    
connect ( sender , SIGNAL ( signal ), receiver , SLOT ( slot ));
或者信号和信号的连接:
 
    
connect ( sender , SIGNAL ( signal ), receiver , SIGNAL ( signal ));
信号与槽之间的连接也可以被移除,使用disconnect函数:
 
    
disconnect ( sender , SIGNAL ( signal ), receiver , SLOT ( slot ));
    使用信号与槽需要注意的事项:
  1.    信号与槽机制与普通函数的调用一样,如果使用不当,在程序执行时也有可能产生死循环。所以在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。
  2.     如果一个信号与多个槽相连,当这个信号被发射时,与之相连的槽被激活的顺序是随机的。
  3.     宏定义不能用在signal 和slot的参数中。
  4.     信号和槽的参数个数与类型必须一致。
更详细的讲解可以参考: http://www.cnblogs.com/MuyouSome/p/3515941.html

    介绍完信号和槽机制,再来说说它是怎么用到不同窗体之间的值传递的。
    对于子对话框传值给主窗体:
  1.     可以把子对话框中控件的信号和主窗体的槽绑定在一起,或者是控件的信号与自定义的信号连接在一起,然后该信号与主窗体的槽函数连一起,这样子对话框的控件变化就会引起主窗口槽函数的响应,但是这种方法受限于子对话框的控件自身的传参类型。
  2.     也可以在子对话框中自定义信号,然后在主窗体中把这个信号绑定到槽函数,子对话框发射信号,主窗体的槽函数就会做出相应的处理。自定义信号可传递的参数类型很多,如int,str,dict,list,'QString'等。
例子如下:
首先是子对话框的代码DateDialog.py:
 
    
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 15 16:18:59 2015
@author: Administrator
"""
from PyQt4 . QtCore import *
from PyQt4 . QtGui import *
class DateDialog ( QDialog ):
Signal_OneParameter = pyqtSignal ( str )
def __init__ ( self , parent = None ):
super ( DateDialog , self ). __init__ ( parent )
layout = QVBoxLayout ( self )
# nice widget for editing the date
self . datetime = QDateTimeEdit ( self )
self . datetime . setCalendarPopup ( True )
self . datetime . setDateTime ( QDateTime . currentDateTime ())
self . lineedit = QLineEdit ( self )
self . btn = QPushButton ( 'emit signal' )
layout . addWidget ( self . lineedit )
layout . addWidget ( self . datetime )
layout . addWidget ( self . btn )
# OK and Cancel buttons
buttons = QDialogButtonBox (
QDialogButtonBox . Ok | QDialogButtonBox . Cancel ,
Qt . Horizontal , self )
buttons . accepted . connect ( self . accept )
buttons . rejected . connect ( self . reject )
layout . addWidget ( buttons )
self . connect ( self . datetime , SIGNAL ( 'dateTimeChanged(QDateTime)' ), self , SLOT ( 'showDate(QDateTime)' ))
self . connect ( self . datetime , SIGNAL ( 'dateTimeChanged(QDateTime)' ), self , SIGNAL ( 'sendDate(QDateTime)' ))
self . connect ( self . btn , SIGNAL ( 'clicked()' ), self , SLOT ( 'myfunc()' ))
@pyqtSlot ()
def myfunc ( self ):
self . Signal_OneParameter . emit (( self . datetime . dateTime ()). toString ())
self . lineedit . setText ( QString (( self . datetime . dateTime ()). toString ()))
@pyqtSlot ( QDateTime )
def showDate ( self , datetime ):
self . lineedit . setText ( datetime . toString ())
self . update ()
#print '12345'
# get current date and time from the dialog
def dateTime ( self ):
return self . datetime . dateTime ()
# static method to create the dialog and return (date, time, accepted)
@staticmethod
def getDateTime ( parent = None ):
dialog = DateDialog ( parent )
result = dialog . exec_ ()
date = dialog . dateTime ()
return ( date . date (), date . time (), result == QDialog . Accepted )
主窗体的代码如下testSignal:
 
    
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 16 09:02:41 2015
@author: Administrator
"""
from PyQt4 . QtGui import *
from PyQt4 . QtCore import *
from DateDialog import *
import sys
class MainWindow ( QDialog ):
def __init__ ( self , parent = None ):
QWidget . __init__ ( self )
self . resize ( 300 , 200 )
open_btn = QPushButton ( 'OPEN' )
self . le_btn = QLineEdit ( self )
self . le1_btn = QLineEdit ( self )
self . le2_btn = QLineEdit ( self )
self . le3_btn = QLineEdit ( self )
self . connect ( open_btn , SIGNAL ( 'clicked()' ), self . openDialog )
grid = QGridLayout ()
grid . addWidget ( self . le_btn )
grid . addWidget ( self . le1_btn )
grid . addWidget ( self . le2_btn )
grid . addWidget ( self . le3_btn )
grid . addWidget ( open_btn )
self . setLayout ( grid )
self . setWindowTitle ( 'main windows' )
def openDialog ( self ):
dialog = DateDialog ( self )
self . connect ( dialog , SIGNAL ( 'sendDate(QDateTime)' ), self , SLOT ( 'receiveDate(QDateTime)' ))
self . connect ( dialog , SIGNAL ( 'sendDate(QDateTime)' ), self , SLOT ( 'copyDate(QDateTime)' ))
self . connect ( dialog . datetime , SIGNAL ( 'dateTimeChanged(QDateTime)' ), self , SLOT ( 'getDate(QDateTime)' ))
#self.connect(dialog,SIGNAL('Signal_OneParameter_Overload(str)'),self,SLOT('getStrDate(str)'))
dialog . Signal_OneParameter . connect ( self . getStrDate )
dialog . show ()
@pyqtSlot ( str )
def getStrDate ( self , dateStr ):
self . le3_btn . setText ( dateStr )
@pyqtSlot ( QDateTime )
def receiveDate ( self , date ):
self . le_btn . setText ( date . toString ())
@pyqtSlot ( QDateTime )
def getDate ( self , date ):
self . le2_btn . setText ( date . toString ())
@pyqtSlot ( QDateTime )
def copyDate ( self , date ):
self . le1_btn . setText ( date . toString ())
app = QApplication ( sys . argv )
app . setFont ( QFont ( "Helvetica" , 16 ))
main = MainWindow ()
main . show ()
sys . exit ( app . exec_ ())
对于自定义的信号,使用方法是:
  1. 自定义的信号在__init__()函数之前定义。Signal_OneParameter = pyqtSignal(str)
  2. 在子对话框的槽函数发射信号,或在事件中发射信号。self.Signal_OneParameter.emit((self.datetime.dateTime()).toString())
  3. 在主窗体中连接信号和槽。dialog.Signal_OneParameter.connect(self.getStrDate)
  4. 然后实现槽函数。
参考:
http://www.cnblogs.com/caomingongli/archive/2011/09/19/2180904.html
http://blog.csdn.net/solofly752/article/details/7576641
http://blog.csdn.net/a359680405/article/details/45150569

你可能感兴趣的:(Python)