【问题标题】:Qt qwidget appearing and disappearing instantlyQt qwidget 瞬间出现和消失
【发布时间】:2017-07-24 06:37:37
【问题描述】:

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

#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,所以我似乎没有找到它。

【问题讨论】:

  • 您可以将“fenConnexion *fenetreCo”作为类的成员,这可能会导致其“超出范围”,从而导致二级窗口的破坏
  • @Sourabh 你的意思是把“fenconnexion *fenetreCo;”在我的主窗口 .h 文件中并在我的 mainwindow.cpp 文件中放置“fenetreCo = new fenconnexion”?如果是,我刚刚尝试过,但它不起作用......
  • this-&gt;close();行下断点,看看是否被调用。
  • 为什么在正确设置它之前显示窗口(即设置其父级等)?窗口是否是模态的?检查showsetVisible(bool) 的Qt 文档并没有让我立即明白这一点。 (我也有一段时间没有使用 Qt 了。)顺便说一句,发布非英语代码可能会使帮助更难获得;我自己很难理解你的代码。
  • @ray 好吧,也许这似乎是问题所在。我只是尝试更改顺序(首先设置其父级,等等)并且它起作用了。非常感谢,对这个明显的错误深表歉意。

标签: c++ qt qwidget


【解决方案1】:

在尝试显示它之前,您需要确保已正确设置窗口。

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

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

【讨论】:

    猜你喜欢
    • 2019-10-17
    • 1970-01-01
    • 2022-10-26
    • 1970-01-01
    • 2019-02-20
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多