【发布时间】:2020-01-20 14:44:21
【问题描述】:
我正在尝试暂时删除此连接:
connect(clipBoard, SIGNAL(dataChanged()), this, SLOT(copiage())); (line 20)
我已尽我所能,但总是以崩溃告终。我真的不知道是什么原因造成的。当我尝试在该行之前停用连接(第 93 行)时,它总是崩溃:
clipBoard->setText(messageRecu); (line 94)
我的想法是,当程序本身更改剪贴板时,我不想要连接。
任何人都可以帮助我了解它为什么会崩溃?
这是.h:
#ifndef FENCLIENT_H
#define FENCLIENT_H
#include <QtWidgets>
#include <QtNetwork>
#include <QClipboard>
#include "ui_fenclient.h"
class FenClient : public QWidget, private Ui::FenClient
{
Q_OBJECT
public:
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);
void copiage();
private:
QTcpSocket *socket; // Représente le serveur
quint16 tailleMessage;
QClipboard *clipBoard;
};
#endif // FENCLIENT_H
这是.cpp
#include "fenclient.h"
using namespace std;
#include<iostream>
#include <ostream>//sinon cout marche pas
FenClient::FenClient()
{
setupUi(this);
socket = new QTcpSocket(this);
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;
QClipboard *clipBoard = QGuiApplication::clipboard();//Ca a été long mais il me faut ca...pas tout compris
connect(clipBoard, SIGNAL(dataChanged()), this, SLOT(copiage()));
}
// Tentative de connexion au serveur
void FenClient::on_boutonConnexion_clicked()
{
// On annonce sur la fenêtre qu'on est en train de se connecter
listeMessages->append(tr("<em>Tentative de connexion en cours...</em>"));
boutonConnexion->setEnabled(false);
socket->abort(); // On désactive les connexions précédentes s'il y en a
socket->connectToHost(serveurIP->text(), serveurPort->value()); // On se connecte au serveur demandé
}
// Envoi d'un message au serveur
void FenClient::on_boutonEnvoyer_clicked()
{
QByteArray paquet;
QDataStream out(&paquet, QIODevice::WriteOnly);
// On prépare le paquet à envoyer
QString messageAEnvoyer = message->text();//on enlève tr("<strong>") + pseudo->text() +tr("</strong> : ") +
out << (quint16) 0;
out << messageAEnvoyer;
out.device()->seek(0);
out << (quint16) (paquet.size() - sizeof(quint16));
socket->write(paquet); // On envoie le paquet
message->clear(); // On vide la zone d'écriture du message
message->setFocus(); // Et on remet le curseur à l'intérieur
}
// Appuyer sur la touche Entrée a le même effet que cliquer sur le bouton "Envoyer"
void FenClient::on_message_returnPressed()
{
on_boutonEnvoyer_clicked();
}
// On a reçu un paquet (ou un sous-paquet)
void FenClient::donneesRecues()
{
/* Même principe que lorsque le serveur reçoit un paquet :
On essaie de récupérer la taille du message
Une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncée tailleMessage)
*/
QDataStream in(socket);
if (tailleMessage == 0)
{
if (socket->bytesAvailable() < (int)sizeof(quint16))
return;
in >> tailleMessage;
}
if (socket->bytesAvailable() < tailleMessage)
return;
// Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
QString messageRecu;
in >> messageRecu;
// On affiche le message sur la zone de Chat
listeMessages->append(messageRecu);
//clipBoard->disconnect();
//const QSignalBlocker blocker(clipBoard);
//on met dans le clipBoard
cout << "Avant " << endl;
bool oldState = clipBoard->blockSignals(true);
clipBoard->setText(messageRecu);
clipBoard->blockSignals(oldState);
cout << "Après " << endl;
//connect(clipBoard, SIGNAL(dataChanged()), this, SLOT(copiage()));
// On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
tailleMessage = 0;
}
// Ce slot est appelé lorsque la connexion au serveur a réussi
void FenClient::connecte()
{
listeMessages->append(tr("<em>Connexion réussie !</em>"));
boutonConnexion->setEnabled(true);
}
// Ce slot est appelé lorsqu'on est déconnecté du serveur
void FenClient::deconnecte()
{
listeMessages->append(tr("<em>Déconnecté du serveur</em>"));
}
// Ce slot est appelé lorsqu'on que le presse-papiers change
void FenClient::copiage()
{ cout << "Copiage= " << endl;
/* QString textCopie;
textCopie = clipBoard->text();
QByteArray paquet;
QDataStream out(&paquet, QIODevice::WriteOnly);
// On prépare le paquet à envoyer
QString messageAEnvoyer = textCopie;
out << (quint16) 0;
out << messageAEnvoyer;
out.device()->seek(0);
out << (quint16) (paquet.size() - sizeof(quint16));
socket->write(paquet); // On envoie le paquet
//message->clear(); // On vide la zone d'écriture du message
//message->setFocus(); // Et on remet le curseur à l'intérieur */
}
// Ce slot est appelé lorsqu'il y a une erreur
void FenClient::erreurSocket(QAbstractSocket::SocketError erreur)
{
switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique
{
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);
}
【问题讨论】:
-
建议:停止使用旧的基于字符串的
SIGNAL和SLOT宏,如果它们不匹配,它们会在运行时“静默”地失败。改用新的编译时检查(和更快)的基于成员函数指针的语法。
标签: c++ qt qclipboard