对话框,顾名思义就是用于“对话”的交互窗口。其主要是体现人机交互的一个重要的方式和渠道。交互要达到实时性,其优先级也相对较高,所以一般对话框都是没有父窗口的顶级的窗口。如果对话框是父窗口的,对话框也一般显示在父窗口的中心位置。
QDialog是Qt的所有对话框的基类。其主要实现与用户的实时信息或作操作的交互。根据对话框与其他是否处理顺序及输入时间的处理方式,对话框设置为模态或者非模态的。即是否会阻止本程序其他可见窗口的输入。其模式方式可以是应用级模式application,或者窗口window模态方式。如果是系统模态的话,在对话框完成之前,其他窗口时不能操作。通常用户必须完成交互后,关闭对话框,才能访问其他的窗口。如果是window模态的话,其只能阻止和其相关联的的窗口,允许其访问其他在应用程序,和此窗口没有相互关联的窗口。通常显示一个模态,调用exec(),如果exec退出,则会返回一个返回值。其表示窗口时接受accepted或者拒绝rejected。返回值可以使用result调用其值。
通常为了关闭窗口并返回对应的值,则连接一个button到accept()槽函数,或者reject()槽函数。或者使用done()槽函数,传Accepted及Rejected值。一般需要调用setModal(true)或者setWindowModality设置模态,然后使用show。使用show的时候,会将控制权交给用户。setModal对进度条对话框非常有用。这时候需要使用QApplication::progressEvents移交控制权。
1.1 QDialog的模态对话框返回值定义
QDialog::Accepted 1 表示此对话框是被接受的
QDialog::Rejected 0 表示此对话框被拒绝。
1.2 QDialog的重要属性
1)modal :bool 模态,此属性表示show()函数会将一个对话框一模态modal或者非模态modeless方式显示。一般,此值为false,并且show执行后显示的是 modeless非模态。通过isModal返回是否为模态,setModel设置其值。如果设置为true,其等效于QWidget::windowModality为Qt::ApplicationModel.
2)sizeGridEnabled:bool设置尺寸手柄是否激活。通常放置到右下端角,当被激活的时候显示,用于控制控件显示的尺寸。isSizeGripEnabled获取状态,setSizeGridEnabled进行设置此值。
1.3 重要的信号
1) accepted() 这个信号时用户被接受或者用户调用accept或者down(QDialog::Accepted)发射。但是如果隐藏窗口使用hide()方法或者setVisible(false)时。
2) finished(int result)如果对话框的result变量被设置,使用setResult设置或者用户调用done,accept,或者reject()槽后发射此信号。dialog在隐藏或者setVisible(false)后则不能发射。
3) rejected()如果窗口被拒了或者用户调用reject()或者done(QDialog::Reject)值。如果widget影藏或者delete掉之后也不发射此信号
1.4 总要的槽函数
1)accept()隐藏模态对话框并将结果设置为Accepted。
2)done(int r) 关闭对话框,并将设置的结果为r。如果说dialog显示使用exec,done()导致本地事件循环 关闭。
3)exec():使用modal模态显示一个对话框。阻止事件直到对话框也结束。
4)open()显示对话框使用windos modaldialog,即,并且立马返回。
5)reject()隐藏模态modal对话框并将resutl值设置为rejected。
1.5) 其他重要的函数
1)result() :int 返回模态对话框的结果,及Accepted或者Rejected。如U哦Qt::WA_DeleteOnClose属性,因为其会删除对象,如果调用则会出现内存非法访问的问题。
2)setResult(int)设置模态对话框的result值为Accepted或者Rejected.。此操作一般会导致finished信号被发射。
3)setVisible(true)显示或者隐藏对话框。
测试程序如下:
class ConnForm : public QDialog
{
Q_OBJECT
public:
ConnForm(QWidget *parent = 0);
~ConnForm(void);
private:
QLabel *hostAddressLabel;
QLineEdit *hostAddressEdit;
QLabel *hostPortLabel;
QLineEdit *hostPortEdit;
QPushButton *connButton;
QPushButton*cancelButton;
QLabel *statusLabel;
QFormLayout *mainFormLayout;
TcpManager *tcpManager;
//QTcpSocket *tcpSocket;
private slots:
void handleStateChange(QAbstractSocket::SocketState);
void handleError(QAbstractSocket::SocketError socketError);
void handleHostFound(void);
void handleConnected();
void connectHost(void);
signals:
void connected(void);
};
ConnForm::ConnForm(QWidget *parent)
:QDialog(parent)
{
setWindowFlags(Qt::FramelessWindowHint);
hostAddressLabel = new QLabel;
hostAddressLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hostAddressLabel->setWordWrap(false);
hostAddressLabel->setText(QObject::tr("Host &Address:"));
hostAddressEdit = new QLineEdit();
hostAddressEdit->setEchoMode(QLineEdit::Normal);
hostAddressEdit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
hostAddressEdit->setDragEnabled(false);
hostAddressEdit->setFrame(true);
hostAddressEdit->setInputMask("000.000.000.000; ");
hostAddressEdit->setText("0.0.0.0");
hostAddressLabel->setBuddy(hostAddressEdit);
hostPortLabel = new QLabel();
hostPortLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
hostPortLabel->setWordWrap(false);
hostPortLabel->setText(QObject::tr("Host &Port:"));
hostPortEdit = new QLineEdit;
hostPortEdit->setEchoMode(QLineEdit::Normal);
hostPortEdit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
hostPortEdit->setDragEnabled(false);
hostPortEdit->setInputMask("00000; ");
hostPortEdit->setFrame(true);
hostPortEdit->setText("9999");
hostPortLabel->setBuddy(hostPortEdit);
connButton = new QPushButton;
connButton->setAutoRepeat(false);
connButton->setAutoDefault(true);
connButton->setFlat(false);
connButton->setText(QObject::tr("Connect"));
connect(connButton,SIGNAL(pressed()),this,SLOT(connectHost()));
cancelButton = new QPushButton;
cancelButton->setFlat(false);
cancelButton->setDefault(true);
cancelButton->setAutoRepeat(false);
cancelButton->setText(QObject::tr("Cancel"));
connect(cancelButton,SIGNAL(pressed()),this,SLOT(reject()));
statusLabel = new QLabel;
statusLabel->setAlignment(Qt::AlignCenter);
statusLabel->setWordWrap(true);
statusLabel->setText("");
mainFormLayout = new QFormLayout;
mainFormLayout->setFormAlignment(Qt::AlignCenter);
mainFormLayout->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
mainFormLayout->setSizeConstraint(QLayout::SetFixedSize);
mainFormLayout->setHorizontalSpacing(20);
mainFormLayout->setVerticalSpacing(10);
mainFormLayout->setContentsMargins(10,30,10,20);
mainFormLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
mainFormLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
mainFormLayout->addRow(hostAddressLabel,hostAddressEdit);
mainFormLayout->addRow(hostPortLabel,hostPortEdit);
mainFormLayout->addRow(connButton,cancelButton);
mainFormLayout->addRow(statusLabel);
setLayout(mainFormLayout);
//tcpSocket = new QTcpSocket(this);
tcpManager = TcpManager::getInstance(NULL);
if(tcpManager->getTcpSocket())
{
connect(tcpManager->getTcpSocket(),SIGNAL(hostFound()),this,SLOT(handleHostFound()));
connect(tcpManager->getTcpSocket(),SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(handleStateChange(QAbstractSocket::SocketState)));
connect(tcpManager->getTcpSocket(),SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(handleError(QAbstractSocket::SocketError)));
connect(tcpManager->getTcpSocket(),SIGNAL(connected()),this,SLOT(handleConnected()));
}
//5GeDJ6wM
}
ConnForm::~ConnForm(void)
{
}
void ConnForm::handleStateChange(QAbstractSocket::SocketState stat)
{
QAbstractSocket::SocketState state = tcpManager->getTcpSocket()->state();
QString infoStr = "";
if(state == stat)
{
infoStr.append(" equal ");
}
else
{
infoStr.append(" no equal ");
}
switch(stat)
{
case QAbstractSocket::UnconnectedState: //0
infoStr.append(" UnconnectedState ");
break;
case QAbstractSocket::HostLookupState: //1
infoStr.append(" HostLookupState ");
break;
case QAbstractSocket::ConnectingState: //2
infoStr.append(" ConnectingState ");
break;
case QAbstractSocket::ConnectedState://3
infoStr.append(" ConnectedState ");
break;
case QAbstractSocket::BoundState://4
infoStr.append(" BoundState ");
break;
case QAbstractSocket::ClosingState: //6
infoStr.append(" C losingState ");
break;
case QAbstractSocket::ListeningState://5
infoStr.append(" ListingState ");
break;
}
statusLabel->setText(statusLabel->text()+infoStr);
}
void ConnForm::handleError(QAbstractSocket::SocketError socketError)
{
QAbstractSocket::SocketError se=tcpManager->getTcpSocket()->error();
static QString errInfo = "";
if(se == socketError)
{
errInfo.append("err equal");
}
else
{
errInfo.append("err no equal");
}
//statusLabel->setText(errInfo);
}
void ConnForm::handleHostFound(void)
{
}
void ConnForm::handleConnected()
{
statusLabel->setText("Onnected success");
accept();
}
void ConnForm::connectHost(void)
{
statusLabel->setText(hostAddressEdit->text()+hostPortEdit->text());
tcpManager->connectToHost(hostAddressEdit->text(),hostPortEdit->text().toInt());
}
执行效果如:
上述例子只是一个网络连接的交互接口,如果连接服务器成功,则进入到首页,按取消则退出
总结:
QDialog作为一种交互方式,其模态方式确定交互必须完成后才能操作其他功能。通过信号accept done 及reject表示执行结果并隐藏窗口。在模态下返回对应的结果。可以通过捕捉对应的accepted及rejected,finished信号确定对话框的推出方式。