QT 使用 SIGNAL 和 SLOT 改变 GUI
QT change GUI with SIGNAL and SLOT
我有一个关于开发 QT 应用程序的问题。
我想使用 SINGAL 和 SLOT 更改 GUI。
从 mythread.cpp 的 sendValue() 到 myserver.cpp 的 showValue() 运行良好。
连接非常好,我可以检查值。
但是从 myserver.cpp 到 application.cpp 的 showApp() 的 sendApp() 无法正常工作。
我很困惑没有连接或没有发射或其他问题。
有两个问题。一个是如何使用 SIGNAL 和 SLOT 从 sendApp() 连接到 showApp()。
emit 不行?或连接不工作?我找不到原因。
另一个是如果 showApp() 函数工作是否可能?
请回答我。第一次开发QT应用,非常抱歉。
application.h
#ifndef APPLICATION_H
#define APPLICATION_H
#include <QWidget>
#include <QObject>
#include <menu.h>
#include <QTcpServer>
#include "myserver.h"
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class application; }
QT_END_NAMESPACE
class application : public QWidget
{
Q_OBJECT
public:
application(QWidget *parent = nullptr);
~application();
private slots:
void on_menuBt_clicked();
void menuBackBtClicked();
void showApp(QString strValue);
private:
Ui::application *ui;
menu menuPage;
};
#endif // APPLICATION_H
application.cpp
#include "application.h"
#include "ui_application.h"
#include "myserver.h"
#include "mythread.h"
application::application(QWidget *parent)
: QWidget(parent)
, ui(new Ui::application)
{
ui->setupUi(this);
Myserver *myserver = new Myserver(this);
ui->firstToggle->setVisible(false);
ui->secondToggle->setVisible(false);
ui->thirdToggle->setVisible(false);
ui->forthToggle->setVisible(false);
ui->stackedWidget->addWidget(&menuPage);
ui->stackedWidget->insertWidget(1, &menuPage);
connect(&menuPage, SIGNAL(menuBackClick()), this, SLOT(menuBackBtClicked()));
connect(myserver, SIGNAL(sendApp(QString)), this, SLOT(showApp(QString)));
setWindowFlags(Qt::FramelessWindowHint);
}
application::~application()
{
delete ui;
}
void application::on_menuBt_clicked()
{
ui->stackedWidget->setCurrentIndex(1); //menuLayout
}
void application::menuBackBtClicked()
{
ui->stackedWidget->setCurrentIndex(0);
}
void application::showApp(QString strValue) {
QString compare = "13";
int x = QString::compare(strValue,compare, Qt::CaseInsensitive);
if(x == 0) {
ui->firstToggle->setVisible(true);
}
}
myserver.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QObject>
#include <QTcpServer>
#include "mythread.h"
#include "application.h"
class Myserver : public QTcpServer
{
Q_OBJECT
public:
explicit Myserver(QObject *parent = 0);
void startServer();
signals:
void sendApp(QString strValue);
private slots:
void showValue(QString strValue);
protected:
void incomingConnection(qintptr socketDescriptor);
private:
MyThread *mythread;
};
#endif // MYSERVER_H
myserver.cpp
#include "myserver.h"
#include "mythread.h"
#include "application.h"
Myserver::Myserver(QObject *parent) :
QTcpServer(parent)
{
}
void Myserver::startServer()
{
int port = 3333;
if(!this->listen(QHostAddress::Any,port))
{
qDebug() << "Could not start server";
}
else
{
qDebug() << "Listening to port " << port << "...";
}
}
void Myserver::incomingConnection(qintptr socketDescriptor)
{
// We have a new connection
qDebug() << socketDescriptor << " Connecting...";
MyThread *thread = new MyThread(socketDescriptor, this);
// connect signal/slot
// once a thread is not needed, it will be beleted later
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(sendValue(QString)), this, SLOT(showValue(QString)));
thread->start();
}
void Myserver::showValue(QString strValue){
emit sendApp(strValue);
}
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QTcpSocket>
#include <QThread>
#include <QDebug>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(qintptr ID, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketerror);
void sendValue(QString strValue);
private slots:
void readyRead();
void disconnected();
private:
QTcpSocket *socket;
qintptr socketDescriptor;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QThread>
MyThread::MyThread(qintptr ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
}
int count = 0;
void MyThread::run()
{
// thread starts here
qDebug() << " Thread started";
socket = new QTcpSocket();
// set the ID
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
// something's wrong, we just emit a signal
emit error(socket->error());
return;
}
// connect socket and signal
// note - Qt::DirectConnection is used because it's multithreaded
// This makes the slot to be invoked immediately, when the signal is emitted.
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
// We'll have multiple clients, we want to know which is which
qDebug() << socketDescriptor << "Client connected";
QString strValue = QString::number(socketDescriptor);
emit sendValue(strValue);
// make this thread a loop,
// thread will stay alive so that signal/slot to function properly
// not dropped out in the middle when thread dies
exec();
}
void MyThread::readyRead()
{
// get the information
QByteArray Data = socket->readAll();
// will write on server side window
qDebug() << socketDescriptor << " Data in: " << Data;
socket->write(Data);
}
void MyThread::disconnected()
{
qDebug() << socketDescriptor << " Disconnected";
socket->deleteLater();
exit(0);
}
您刚刚忘记启动服务器!
在 application class constructor.
中的连接后添加 startServer()
函数调用可能会起作用
connect(&menuPage, SIGNAL(menuBackClick()), this, SLOT(menuBackBtClicked()));
connect(myserver, SIGNAL(sendApp(QString)), this, SLOT(showApp(QString)));
myserver->startServer();
我有一个关于开发 QT 应用程序的问题。 我想使用 SINGAL 和 SLOT 更改 GUI。 从 mythread.cpp 的 sendValue() 到 myserver.cpp 的 showValue() 运行良好。 连接非常好,我可以检查值。
但是从 myserver.cpp 到 application.cpp 的 showApp() 的 sendApp() 无法正常工作。 我很困惑没有连接或没有发射或其他问题。 有两个问题。一个是如何使用 SIGNAL 和 SLOT 从 sendApp() 连接到 showApp()。 emit 不行?或连接不工作?我找不到原因。 另一个是如果 showApp() 函数工作是否可能? 请回答我。第一次开发QT应用,非常抱歉。
application.h
#ifndef APPLICATION_H
#define APPLICATION_H
#include <QWidget>
#include <QObject>
#include <menu.h>
#include <QTcpServer>
#include "myserver.h"
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class application; }
QT_END_NAMESPACE
class application : public QWidget
{
Q_OBJECT
public:
application(QWidget *parent = nullptr);
~application();
private slots:
void on_menuBt_clicked();
void menuBackBtClicked();
void showApp(QString strValue);
private:
Ui::application *ui;
menu menuPage;
};
#endif // APPLICATION_H
application.cpp
#include "application.h"
#include "ui_application.h"
#include "myserver.h"
#include "mythread.h"
application::application(QWidget *parent)
: QWidget(parent)
, ui(new Ui::application)
{
ui->setupUi(this);
Myserver *myserver = new Myserver(this);
ui->firstToggle->setVisible(false);
ui->secondToggle->setVisible(false);
ui->thirdToggle->setVisible(false);
ui->forthToggle->setVisible(false);
ui->stackedWidget->addWidget(&menuPage);
ui->stackedWidget->insertWidget(1, &menuPage);
connect(&menuPage, SIGNAL(menuBackClick()), this, SLOT(menuBackBtClicked()));
connect(myserver, SIGNAL(sendApp(QString)), this, SLOT(showApp(QString)));
setWindowFlags(Qt::FramelessWindowHint);
}
application::~application()
{
delete ui;
}
void application::on_menuBt_clicked()
{
ui->stackedWidget->setCurrentIndex(1); //menuLayout
}
void application::menuBackBtClicked()
{
ui->stackedWidget->setCurrentIndex(0);
}
void application::showApp(QString strValue) {
QString compare = "13";
int x = QString::compare(strValue,compare, Qt::CaseInsensitive);
if(x == 0) {
ui->firstToggle->setVisible(true);
}
}
myserver.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QObject>
#include <QTcpServer>
#include "mythread.h"
#include "application.h"
class Myserver : public QTcpServer
{
Q_OBJECT
public:
explicit Myserver(QObject *parent = 0);
void startServer();
signals:
void sendApp(QString strValue);
private slots:
void showValue(QString strValue);
protected:
void incomingConnection(qintptr socketDescriptor);
private:
MyThread *mythread;
};
#endif // MYSERVER_H
myserver.cpp
#include "myserver.h"
#include "mythread.h"
#include "application.h"
Myserver::Myserver(QObject *parent) :
QTcpServer(parent)
{
}
void Myserver::startServer()
{
int port = 3333;
if(!this->listen(QHostAddress::Any,port))
{
qDebug() << "Could not start server";
}
else
{
qDebug() << "Listening to port " << port << "...";
}
}
void Myserver::incomingConnection(qintptr socketDescriptor)
{
// We have a new connection
qDebug() << socketDescriptor << " Connecting...";
MyThread *thread = new MyThread(socketDescriptor, this);
// connect signal/slot
// once a thread is not needed, it will be beleted later
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(sendValue(QString)), this, SLOT(showValue(QString)));
thread->start();
}
void Myserver::showValue(QString strValue){
emit sendApp(strValue);
}
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QTcpSocket>
#include <QThread>
#include <QDebug>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(qintptr ID, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketerror);
void sendValue(QString strValue);
private slots:
void readyRead();
void disconnected();
private:
QTcpSocket *socket;
qintptr socketDescriptor;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QThread>
MyThread::MyThread(qintptr ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
}
int count = 0;
void MyThread::run()
{
// thread starts here
qDebug() << " Thread started";
socket = new QTcpSocket();
// set the ID
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
// something's wrong, we just emit a signal
emit error(socket->error());
return;
}
// connect socket and signal
// note - Qt::DirectConnection is used because it's multithreaded
// This makes the slot to be invoked immediately, when the signal is emitted.
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
// We'll have multiple clients, we want to know which is which
qDebug() << socketDescriptor << "Client connected";
QString strValue = QString::number(socketDescriptor);
emit sendValue(strValue);
// make this thread a loop,
// thread will stay alive so that signal/slot to function properly
// not dropped out in the middle when thread dies
exec();
}
void MyThread::readyRead()
{
// get the information
QByteArray Data = socket->readAll();
// will write on server side window
qDebug() << socketDescriptor << " Data in: " << Data;
socket->write(Data);
}
void MyThread::disconnected()
{
qDebug() << socketDescriptor << " Disconnected";
socket->deleteLater();
exit(0);
}
您刚刚忘记启动服务器!
在 application class constructor.
中的连接后添加startServer()
函数调用可能会起作用
connect(&menuPage, SIGNAL(menuBackClick()), this, SLOT(menuBackBtClicked()));
connect(myserver, SIGNAL(sendApp(QString)), this, SLOT(showApp(QString)));
myserver->startServer();