mySignalSlot.pro
#-------------------------------------------------
#
# Project created by QtCreator 2011-04-23T11:05:03
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = mySignalSlot
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp \
mydialog.cpp
HEADERS += widget.h \
mydialog.h
FORMS += widget.ui \
mydialog.ui
mydialog.h
#ifndef MYDIALOG_H#define MYDIALOG_H#include <QDialog>namespace Ui {class MyDialog;}class MyDialog : public QDialog{Q_OBJECTpublic:
explicit MyDialog(QWidget *parent = 0);~MyDialog();private slots:void on_pushButton_clicked();signals:
void dlgReturn(int); //自定义的信号private:
Ui::MyDialog *ui;};#endif // MYDIALOG_H
widget.h
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:
explicit Widget(QWidget *parent = 0);~Widget();private slots:void showValue(int value);private:
Ui::Widget *ui;};#endif // WIDGET_H
main.cpp
#include <QApplication>#include "widget.h"#include <QTextCodec>int main(int argc, char *argv[]){QApplication a(argc, argv);QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));Widget w;w.show();
return a.exec();}
mydialog.cpp
#include "mydialog.h"#include "ui_mydialog.h"MyDialog::MyDialog(QWidget *parent) :QDialog(parent),ui(new Ui::MyDialog){ui->setupUi(this);}MyDialog::~MyDialog(){delete ui;}// 确定按钮void MyDialog::on_pushButton_clicked(){// 获取输入的数值int value = ui->spinBox->value();// 发射信号emit dlgReturn(value);// 关闭对话框close();
}
widget.cpp
#include "mydialog.h"#include "ui_mydialog.h"MyDialog::MyDialog(QWidget *parent) :QDialog(parent),ui(new Ui::MyDialog){ui->setupUi(this);}MyDialog::~MyDialog(){delete ui;}// 确定按钮void MyDialog::on_pushButton_clicked(){// 获取输入的数值int value = ui->spinBox->value();// 发射信号emit dlgReturn(value);// 关闭对话框close();
}在图形界面编程中,在什么地方进行窗体创建和初始化才最好,是需要研究的;采用直接建立消息循环的exec()函数,或只是在主消息循环中将窗体显示出来的show()函数来进行窗体的显示和隐藏,也是需要研究的。为了帮助同学们逐步探索形成独立的编程思想,参考附件“多窗口创建和模态”文件夹,从以下研究提纲出发,写出你的研究结果。
1、如果写一个普通函数去创建窗体,采用直接创建窗体对象的方式,会有什么问题?如果写一个普通函数去创建窗体,利用指针动态创建窗体对象,又会有什么问题?
可以看到窗口闪一下就会消失,因为函数里面的dialog是一个局部变量,只在那个函数中有效,出了函数体就会失效,所以看到窗口闪一下就消失了
2、除了show()函数可以用来显示出一个窗体以外,QDialog类还支持建立独立消息循环的exec()函数,使用这两种方式有什么区别?
利用指针动态创建窗口当运行完毕后没有delete时,会使内存发生严重泄露,非常不安全
3、如果的确需要两个窗体,一个主窗体和一个子窗体,那么,最好是在什么地方,以什么方式去创建和初始化、显示子窗体?
主窗口和子窗口放分别在一个类当中,然后再主窗口中调用子窗口,用构造函数去创建和初始化,也在主窗口的构造函数中去显示子窗口
4、阅读http://www.jellythink.com/archives/42和 http://blog.csdn.net/lightupheaven/article/details/38823067 关于C++简单工厂和静态工厂设计模式的描述,为family_relationship项目新建一个FamilyBuilder类,能够安全地生成许许多多完整的家庭。静态工厂方法统一管理对象的创建。静态工厂方法通过传入的参数判断决定创建哪一个产品的实例,封装了对象的创建,客户端只管消费,实现了对责任(模块)的分割。静态工厂方法推迟了产品的实例化。通过XML配置文件就能改变具体要创建的产品实例,修改为其它的产品实例,代码不须重新编译。对于工厂模式,具体上可以分为三类:简单工厂模式;工厂方法模式;抽象工厂模式。适用场合在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式;由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。#ifndef FATHER_H#define FATHER_H#include <string>using namespace std;class FamilyBuilder;class Child;class Mother;class Father{public:friend class FamilyBuilder;string name;Child* child;Mother* mother;void callChild();void callMother();void answer();~Father();private:Father(string fa_name,string mo_name,string ch_name);};#endif // FATHER_H#include "father.h"#include "child.h"#include "mother.h"#include <iostream>Father::Father(string fa_name,string mo_name,string ch_name):name(fa_name){child = new Child(ch_name);child->father = this;mother = new Mother(this,child,mo_name);child->mother = mother;}void Father::callChild(){cout<<endl<<"Father calling child!";child->answer();}void Father::callMother(){cout<<endl<<"Father calling child!";mother->answer();}void Father::answer(){cout<<endl<<name<<" is here waiting for you!";}Father::~Father(){delete mother;delete child;}#ifndef CCACULATORFACTORY#define CCACULATORFACTORY#include <string>using namespace std;class Father;class FamilyBuilder{public:static Father * Create(string fa_name,string mo_name,string ch_name);};#endif // CCACULATORFACTORY#include "father.h"#include "familyBuilder.h"#include <iostream>Father * FamilyBuilder::Create(string fa_name,string mo_name,string ch_name){Father * fa = new Father(fa_name,mo_name,ch_name);return fa;}#include <QCoreApplication>#include "father.h"#include "child.h"#include "mother.h"#include "familyBuilder.h"#include <iostream>using namespace std;int main(int argc, char *argv[]){QCoreApplication a(argc, argv);Father *baba1 =FamilyBuilder::Create("lao hua","hua ma","xiao hua");// 第一个家庭baba1->callChild();baba1->callMother();baba1->child->callFather();baba1->child->callMother();baba1->mother->callChild();baba1->mother->callFather();cout<<endl;Father *baba2 =FamilyBuilder::Create("lao li","li ma","xiao li");// 第二个家庭baba2->callChild();baba2->callMother();baba2->child->callFather();baba2->child->callMother();baba2->mother->callChild();baba2->mother->callFather();cout<<endl;return a.exec();}5、读懂课本第55页和第59页的程序(没有带课本的同学读参考代码3-6和3-7),实现一个模拟QQ登陆机制的项目:
在登陆界面中用户输入用户名和密码,然后点击“登陆”按钮:如果用户名密码不正确,则弹出提示对话框,请用户重新输入;如果用户名密码正确,则登陆窗体关闭,且进入第二个窗体。在第二个窗体中,有一个“注销”按钮,点击该按钮则回到登陆窗体。
#include"mywidget.h"
#include<QApplication>
#include"mydialog.h"
int main(int argc,char *argv[])
{
QApplication a(argc,argv);
mywidget w;
myDialog dialog;
if(dialog.exec()==QDialog::Accepted){
w.show();
return a.exec()
}
else return 0;
}
void myWidget::on_pushButton_clicked()
{
close();
MyDialog dlg;
if(dlg,exec()==QDialog::Accepted) show();
}
6、读懂课本51-52页(没有带课本的同学读参考代码3-4)、131-134页(没有带课本的同学读参考代码7-1)所讲的信号与槽机制,实现一个效果:
创建父窗体和子窗体,父窗体上有一个按钮和一个文本输入框,子窗体上有一个文本输入框,按父窗口上的按钮能够显示出子窗口,然后随着用户在父窗体中进行输入,在父窗口中的输入的文本能够实时复制到子窗口中的文本框里。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicitMainWindow(QWidget *parent = 0);
~MainWindow();
private:
voidputText(QString s);
private slots:
voidon_action456_triggered();
private:
Ui::MainWindow*ui;
};
#endif // MAINWINDOW_H
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
namespace Ui {
class MyDialog;
}
class MyDialog : public QDialog
{
Q_OBJECT
public:
explicitMyDialog(QWidget *parent = 0);
~MyDialog();
signals:
voidgiveText(QString s);
private slots:
voidon_pushButton_clicked();
private:
Ui::MyDialog*ui;
};
#endif // MYDIALOG_H
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplicationa(argc, argv);
MainWindoww;
w.show();
returna.exec();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <mydialog.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(newUi::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
deleteui;
}
void MainWindow::putText(QString s)
{
ui->label->setText(s);
}
void MainWindow::on_action456_triggered()
{
MyDialog* d = new MyDialog(this);
connect(d,&MyDialog::giveText,this,&MainWindow::putText);
d->show();
}
#include "mydialog.h"
#include "ui_mydialog.h"
MyDialog::MyDialog(QWidget *parent) :
QDialog(parent),
ui(newUi::MyDialog)
{
ui->setupUi(this);
}
MyDialog::~MyDialog()
{
deleteui;
}
void MyDialog::on_pushButton_clicked()
{
QStrings = ui->lineEdit->text();
emitgiveText(s);
}
7、阅读http://blog.csdn.net/htyurencaotang/article/details/9322607上关于C++单例模式的描述,为family_relationship项目新建一个BigFamily类,实现整个项目中只能够有唯一一个大家庭,大家庭中可以有多个孩子。#ifndef BIGFAMILY
#define BIGFAMILY
#include <string>
using namespace std;
class Father;
class Child;
class Mother;
class BigFamily{
public:
string name;
Child* child[5]; //保存孩子的指针数组,最多有五个孩子
Mother* mother;
Father* father;
static BigFamily* getInstance();
Child* newChild(string name0);
~BigFamily();
private:
BigFamily();
static BigFamily *m_pInstance;
};
#endif // BIGFAMILY
#ifndef CHILD_H
#define CHILD_H
#include <string>
using namespace std;
class Father;
class Mother;
class Child
{
public:
friend class BigFamily;
string name;
Father*father;
Mother* mother;
void answer();
void callFather();
void callMother();
~Child();
private:
Child(string name0);
};
#endif // CHILD_H
#ifndef FATHER_H
#define FATHER_H
#include <string>
using namespace std;
class Child;
class Mother;
class BigFamily;
class Father
{
public:
friend class BigFamily;
string name;
Child* child[5];
Mother* mother;
void callChild(int num);
void callMother();
void answer();
~Father();
private:
Father();
};
#endif // FATHER_H
#ifndef MOTHER
#define MOTHER
using namespace std;
class Father;
class Child;
class Mother{
public:
friend class BigFamily;
string name;
Father* father;
Child* child[5];
void answer();
void callFather();
void callChild(int num);
~Mother();
private:
Mother(Father *f,Child *c);
};
#endif // MOTHER
#include "father.h"
#include "child.h"
#include "mother.h"
#include "bigfamily.h"
#include <iostream>
int child_num = 0;
BigFamily::BigFamily()
{
father= new Father();
child[0] = new Child("xiao hua");
child[0]->father = father;
mother = new Mother(father,child[0]);
child[0]->mother = mother;
father->child[0] = child[0];
father->mother = mother;
}
BigFamily* BigFamily::m_pInstance = NULL;
BigFamily* BigFamily::getInstance()
{
if(m_pInstance == NULL){
m_pInstance = new BigFamily();
}
return m_pInstance;
}
Child* BigFamily::newChild(string name0)
{
child_num++;
child[child_num] = new Child(name0);
child[child_num]->father = father;
child[child_num]->mother = mother;//所有孩子指向同一个爸爸妈妈
father->child[child_num] = child[child_num];
mother->child[child_num] = child[child_num];
return child[child_num];
}
BigFamily::~BigFamily()
{
delete m_pInstance;
delete father;
delete mother;
delete[] child;
}
#include "child.h"
#include "father.h"
#include "mother.h"
#include "iostream"
Child::Child(string name0)
{
name = name0;
}
void Child::answer(){
cout<<endl<<name<<" is here waiting foryou!";
}
void Child::callFather(){
cout<<endl<<"Child is calling father!";
father->answer();
}
void Child::callMother(){
cout<<endl<<"Child is calling Mother!";
mother->answer();
}
Child::~Child()
{
delete father;
delete mother;
}
#include "father.h"
#include "child.h"
#include "mother.h"
#include <iostream>
Father::Father()
:name("Lao Hua")
{}
void Father::callChild(int num){
num--;
cout<<endl<<"Father is calling child!";
child[num]->answer();
}
void Father::callMother(){
cout<<endl<<"Father is calling child!";
mother->answer();
}
void Father::answer(){
cout<<endl<<name<<" is here waiting foryou!";
}
Father::~Father()
{
delete mother;
delete[] child;
}
#include "child.h"
#include "father.h"
#include "mother.h"
#include "iostream"
Mother::Mother(Father *f = 0,Child *c =0):name("Hua mama")
{
child[0] = c;
father = f;
}
void Mother::answer(){
cout<<endl<<name<<" is here waiting foryou!";
}
void Mother::callFather(){
cout<<endl<<"Mother is calling father!";
father->answer();
}
void Mother::callChild(int num){
num--;
cout<<endl<<"Mother is calling child!";
child[num]->answer();
}
Mother::~Mother()
{
delete father;
delete[] child;
}
#include <QCoreApplication>
#include "father.h"
#include "child.h"
#include "mother.h"
#include "bigfamily.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
BigFamily *bf =BigFamily::getInstance();//新建一个家庭
bf->child[0]->callFather();
bf->child[0]->callMother();
cout<<endl;
bf->father->callChild(1); //爸爸呼叫老大
bf->father->callMother();
cout<<endl;
bf->mother->callChild(1); //妈妈呼叫老大
bf->mother->callFather();
cout<<endl;
cout<<"++++++++++++++++++++++++++++";
Child *child2 = bf->newChild("Hua2"); //新建一个孩子,老二
child2->callFather();
child2->callMother();
cout<<endl;
bf->father->callChild(2);
bf->father->callMother();
cout<<endl;
bf->mother->callChild(2);
bf->mother->callFather();
cout<<endl;
cout<<"++++++++++++++++++++++++++++";
bf->father->callChild(1);//爸爸呼叫老大
bf->father->callChild(2);//爸爸呼叫老二
return a.exec();
}