Qt qwidget即时出现并消失

问题描述:

我正在写一个与Qt 5.9的聊天程序。我完成了客户端程序并开始改进它。我做的第一件事就是制作一个新的Qwidget(辅助窗口),当按下我的主窗口上的连接按钮时会出现。一切都很顺利,但当我测试并按下主窗口上的连接按钮时,我的辅助窗口即时出现并消失。当用户按下按钮(位于辅助窗口中)时,如何使辅助窗口保持(不消失)?这里是我的两个窗口的代码:主要在window.h(fenClient.hQt qwidget即时出现并消失

#ifndef FENCLIENT_H 

#define FENCLIENT_H 

#include <QtWidgets> 
#include <QtNetwork> 
#include <ui_fenclient.h> 
#include <fenconnexion.h> 

class FenClient : public QWidget, private Ui::FenClient 
{ 
    Q_OBJECT 

public: 
    FenClient(); 
    ~FenClient(); 

private slots: 
    void on_boutonConnexion_clicked(); 
    void on_boutonEnvoyer_clicked(); 
    void on_message_returnPressed(); 
    void donneesRecues(); 
    void connecte(); 
    void deconnecte(); 
    void erreurSocket(QAbstractSocket::SocketError erreur); 


private: 
    QTcpSocket *socket; 
    quint16 tailleMessage; 


}; 

#endif // FENCLIENT_H 

#include <fenclient.h> 

主要window.cpp(fenClient.cpp)这是创建二级窗口,在其中。

FenClient::FenClient() 
{ 
    setupUi(this); 


    socket = new QTcpSocket; 
    connect(socket,SIGNAL(readyRead()),this,SLOT(donneesRecues())); 
    connect(socket,SIGNAL(connected()),this,SLOT(connecte())); 
    connect(socket,SIGNAL(disconnected()),this,SLOT(deconnecte())); 
    connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(erreurSocket(QAbstractSocket::SocketError))); 

    tailleMessage = 0; 
} 

void FenClient::on_boutonConnexion_clicked() 
{ 
    listeMessages->append(tr("<em>Tentative de connexion en cours...</em>")); 
    boutonConnexion->setEnabled(false); 
    fenConnexion *fenetreCo = new fenConnexion; //this is where my secondary window is created 
    fenetreCo->show(); 
    fenetreCo->activateWindow(); 
    fenetreCo->setParent(this); 
    fenetreCo->echangerPseudo(pseudo->text()); 


    socket->abort(); 
    socket->connectToHost(serveurIP->text(),serveurPort->value()); 

} 

void FenClient::on_boutonEnvoyer_clicked() 
{ 
    if (message->text().isEmpty()) 
    { 
     QMessageBox::information(this,"Veuillez écrire quelque chose","Pour éviter le spam, j'ai decidé d'empecher l'envoi de message vide. Veuillez écrire quelque chose..."); 
    } 
    else if(pseudo->text() == "") 
    { 
     QMessageBox::information(this,"Veuillez spécifier votre nom","Pour éviter l'anonimité, j'ai décidé d'obligé l'usage d'un pseudo."); 
    } 
    else 
    { 
     QByteArray paquet; 
     QDataStream out(&paquet, QIODevice::WriteOnly); 

     QString messageAEnvoyer = tr("<strong>") + pseudo->text() + tr("</strong> : ") + message->text(); 

     out<<(quint16) 0; 
     out<< messageAEnvoyer ; 
     out.device()->seek(0); 
     out << (quint16) (paquet.size() - sizeof(quint16)); 

     socket->write(paquet); 

     message->clear(); 
     message->setFocus(); 
     } 
} 

void FenClient::on_message_returnPressed() 
{ 
    on_boutonEnvoyer_clicked(); 
} 

void FenClient::donneesRecues() 
{ 
    QDataStream in(socket); 

    if (tailleMessage==0) 
    { 
     if(socket->bytesAvailable() < (int)sizeof(quint16)) 
     {return;} 

     in >> tailleMessage; 

    } 
    if (socket->bytesAvailable() < tailleMessage) 
    {return;} 


    QString messageRecu; 
    in >> messageRecu; 

    listeMessages->append(messageRecu); 

    tailleMessage = 0; 
} 

void FenClient::connecte() 
{ 
    listeMessages->append(tr("<em>Connexion réussie</em>")); 
    boutonConnexion->setEnabled(true); 
    message->setEnabled(true); 
} 

void FenClient::deconnecte() 
{ 
    listeMessages->append(tr("<em>Déconnecté!</em>")); 
    message->setEnabled(false); 
} 
void FenClient::erreurSocket(QAbstractSocket::SocketError erreur) 
{ 
    switch(erreur) 
    { 
     case QAbstractSocket::HostNotFoundError: 
      listeMessages->append(tr("<em>ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port.</em>")); 
    break; 
case QAbstractSocket::ConnectionRefusedError: 
    listeMessages->append(tr("<em>ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port.</em>")); 
    break; 
case QAbstractSocket::RemoteHostClosedError: 
    listeMessages->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>")); 
    break; 
default: 
    listeMessages->append(tr("<em>ERREUR : ") + socket->errorString() + tr("</em>")); 
} 

boutonConnexion->setEnabled(true); 
} 
FenClient::~FenClient() 
{} 

次级window.h中(fenconnexion.h)

#ifndef FENCONNEXION_H 
#define FENCONNEXION_H 

#include <ui_fenconnexion.h> 
#include <QtWidgets> 


class fenConnexion : public QWidget, private Ui::Form 
{ 
    Q_OBJECT 
public: 
    fenConnexion(); 
    QString pseudoUtilisateur; 
    void echangerPseudo(QString pseudoAEchanger); 
private slots : 
    void checkPseudo(); 
private: 
    QString pseudo; 



}; 


#endif // FENCONNEXION_H 

次级window.cpp(fenconnexion.cpp)

#include <fenconnexion.h> 

fenConnexion::fenConnexion() 
{ setupUi(this); 


    connect(boutonInserer,SIGNAL(clicked(bool)),this,SLOT(checkPseudo())); 
} 

void fenConnexion::checkPseudo() 
{ 
    pseudo=pseudoInsere->text(); 
    if (pseudo.isEmpty()) 
    { 
     QMessageBox::information(this,"Probleme","Veuillez entre un pseudo conetenant au moins un caractere."); 
    } 
    else 
    { 
     pseudoUtilisateur=pseudo; 
     pseudoInsere->clear(); 
     pseudo.clear(); 
     this->close(); 
    } 
} 
void fenConnexion::echangerPseudo(QString pseudoAEchanger) 
{ 
    pseudoAEchanger.clear(); 
    pseudoAEchanger = pseudoUtilisateur; 
} 

感觉像我做了一个非常简单的错误或者,但是由于我在6个月以上没有使用过Qt,所以我似乎没有找到它。

+0

您可以将“fenConnexion * fenetreCo”作为课程的一员,可能会出现一些“超出范围”,从而导致破坏后窗 – SourabhKus

+0

@Sourabh您的意思是把“fenconnexion * fenetreCo;”在我的主窗口.h文件中,并在我的mainwindow.cpp文件中放置“fenetreCo = new fenconnexion”?如果是,我刚刚尝试过,它不起作用... – WKstraw

+0

在'this-> close();'行上放置一个断点并查看它是否被调用。 – vahancho

您需要确保在试图展示之前正确设置了窗口。

fenConnexion *fenetreCo = new fenConnexion; 
fenetreCo->show(); 
fenetreCo->activateWindow(); 
fenetreCo->setParent(this); 

在调用show之前设置窗口的父窗口。这使得窗口this'孩子,这意味着它是this'负责管理其生命周期。