C++ ----Qt
1.什么是QT
Qt是一个跨平台的C++应用程序开发框架。
用于开发图形用户界面、嵌入式系统、以及其他应用程序(嵌入式,桌面,汽车中控),支持Windows、macOS、Linux、Android和iOS等多个操作系统。
Qt框架提供了丰富的功能和工具,包括图形用户界面设计、数据库操作、网络编程、文件处理等。
它还包括了一个广泛的类库,开发者可以使用这些类来加速应用程序的开发过程。Qt还具有良好的文档和社区支持,因此广泛用于各种类型的应用程序开发,包括桌面应用、移动应用、嵌入式系统等。
2.QT父子关系
-
父子关系的建立
通过在对象的构造函数中传递父对象的指针,可以建立父子关系。QObject
的子类通常在构造函数中传入父对象指针,以建立父子关系,这样父对象会负责管理子对象的内存。
MyChildClass::MyChildClass(QObject *parent) : QObject(parent) { // 构造函数中传入父对象指针 }
-
父子关系的影响
当父对象被销毁时,它的所有子对象也会被自动销毁。 父对象的位置和大小变化也会影响到子对象。
-
Qobject的parent()函数
通过parent()
函数可以获取对象的父对象指针
QObject *parent = myObject->parent();
-
父子关系的使用范围
父子关系通常在GUI编程中用得比较多,例如窗口和窗口上的控件之间建立父子关系。 父子关系在对象的内存管理方面非常有用,能够简化内存释放的过程。
-
Qobject的findChild函数
-
通过
findChild
函数可以在父对象的子对象中查找特定名称的子对象。
QObject *childObject = parentObject->findChild<QObject*>("childObjectName");
-
事件传递中的父子关系
在事件传递中,父子关系也很重要。事件通常从父对象传递到子对象,父对象可以拦截事件,也可以选择传递给子对象处理。
bool MyObject::event(QEvent *event) { if (event->type() == QEvent::KeyPress) { // 处理键盘事件 return true; } return QObject::event(event); // 默认事件处理方式 }
-
QT对象树模型
一个QObject对象可以有一个父对象和多个子对象。
Qt的对象树模型是一种递归的结构,其中一个对象可以拥有多个子对象,而每个子对象又可以拥有自己的子对象。
在对象树模型中,父对象的销毁会导致所有子对象的自动销毁。当一个QObject对象被销毁时,它的所有子对象也会被递归地销毁。
3.信号与槽机制
信号:点击一个按钮时,发出一个信号
槽:程序会执行一段代码逻辑,槽函数
3.1信号与槽的实现
-
点击按钮,右击,转到槽,新增了on_commitButton_clicked()函数
void Widget::on_commitButton_clicked(){ //获取lineedit数据 QString program = ui->cmdLineEdit->text(); //启动一个进程:process对象 QProcess *myProcess = new QProcess(this); myProcess->start(program); }
-
信号与槽进行关联:发出一个信号,调用这个函数
//参数:谁发出信号 发出什么信号 谁处理信号 怎么处理 connect(ui->cmdLineEdit,SIGNAL(returnPressed()),this,SLOT(on_commitButton_clicked())); //SIGNAL(returnPressed()):点回车也有反应
-
地址的形式写
void Widget::on_cancelButton_clicked(){ this->close(); }
//取消按钮,发出点击信号,当前对象处理信号,怎么处理:关闭 connect(ui->cancelButton,&QPushButton::clicked,this,&Widget::on_cancelButton_clicked);
-
lambda表达式
#include<QMessageBox> connect(ui->browseButton,&QPushButton::clicked,[this](){ //跳出一个对话框 QMessageBox::information(this,"信息","点击浏览"); });
4.QMainWindow
QMainWindow用于创建应用程序的主窗口,他提供了一个标准的应用程序主窗口结构。
包括:菜单栏、工具栏、状态栏、停靠部件、中心部件
4.1菜单栏QMenuBar
菜单栏包含多个菜单,在菜单中包含菜单项 菜单栏--->菜单(File) ---->菜单项(open)
头文件
#include<QMenuBar> #include<QMenu> #include<QAction>
-
创建菜单栏
QMenuBar *menuBar = new QMenuBar(this);
-
在菜单栏上添加一个菜单File
QMenu *fileMenu = menuBar->addMenu(tr(File));
-
在菜单中添加菜单项open
QAction *openAction = new QAction(tr("Open"),this); fileMenu->addAction(openAction); connect(openAction,SIGNAL(triggered()),this,SLOT(openfile()));//openfile()是槽函数,当菜单项被点击时执行相应操作 triggered() 信号会在用户点击菜单项open时发出。 setMenuBar(menuBar);
4.2工具栏QToolBar
头文件
#include<QToolBar>
-
创建一个工具栏
QToolBar *toolBar = new QToolBar("MyToolBar",this); addToolBar(toolBar);
-
在工具栏上添加按钮
QAction *openAction = new QAction(QIcon("open.png"), "Open", this); connect(openAction, SIGNAL(triggered()), this, SLOT(openFile())); toolBar->addAction(openAction);
这里,open.png
是按钮的图标文件。openFile()
是一个槽函数,当按钮被点击时执行相应的操作。
4.3状态栏QStatusBar
-
创建状态栏
使用statusBar()函数来获取当前状态栏对象
-
添加标签或消息到状态栏
statusBar()->showMessage("Ready",3000);//在状态栏上显示消息,持续消息3m
-
在状态栏上添加控件
QLabel *statusLabel = new QLabel("Status Label", this); statusBar()->addPermanentWidget(statusLabel);
5.QT定时器
实现定时器:
-
QObject:开启定时器startTimer; 结束定时器 KillTimer
-
Qtimer
5.1QObject定时器
实现照片的轮询显示
#define WIDGET_H #include <QWidget> QT_BEGIN_NAMESPACE #define TIMEOUT 1*1000 namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); //虚函数,定义事件 virtual void timerEvent(QTimerEvent *event); ~Widget(); private slots: void on_statarButton_clicked(); void on_stopButton_clicked(); private: Ui::Widget *ui; int myTimerId;//定时器ID int pixId;//照片ID }; #endif // WIDGET_H
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //照片ID pixId=2; //程序启动的时候,显示一张图片 QPixmap pix("D:\\myQt\\qtProject\\QObjectTimer\\img\\1.jpeg"); //显示 ui->label->setPixmap(pix); } //event:获取当前定时器的编号 //计时一秒钟时间到了之后,就会执行这个事件 void Widget::timerEvent(QTimerEvent *event) { //判断是否是这个定时器 if(event->timerId()!=myTimerId) return; //路径 QString path("D:\\myQt\\qtProject\\QObjectTimer\\img\\"); path+=QString::number(pixId); path+=".jpeg"; //显示 QPixmap pix(path); ui->label->setPixmap(pix); pixId++; if(5==pixId){ pixId = 1; } } Widget::~Widget() { delete ui; } //开始按钮 void Widget::on_statarButton_clicked() { //开启定时器,返回定时器的编号 myTimerId = this->startTimer(TIMEOUT); } //取消按钮 void Widget::on_stopButton_clicked() { this->killTimer(myTimerId); }
5.2QTimer定时器
开始:start()
结束:stop()
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTimer> #define TIMEOUT 1*1000 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_startButton_clicked(); void timeOutSlots(); void on_stopButton_clicked(); void on_SingButton_clicked(); private: Ui::Widget *ui; QTimer* timer; int pixId; }; #endif // WIDGET_H
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //创建timer对象 timer = new QTimer(); pixId = 2; //显示图片 QImage img; img.load("D:\\myQt\\qtProject\\QObjectTimer\\img\\1.jpeg"); ui->label->setPixmap(QPixmap::fromImage(img)); //定时器时间到,发出timeout信号 connect(timer,&QTimer::timeout,this,&Widget::timeOutSlots); } Widget::~Widget() { delete ui; } void Widget::on_startButton_clicked() { //开启定时器 timer->start(TIMEOUT); } //事件 void Widget::timeOutSlots() { //切换图片 QString path("D:\\myQt\\qtProject\\QObjectTimer\\img\\"); path+=QString::number(pixId); path+=".jpeg"; QImage img; img.load(path); ui->label->setPixmap(QPixmap::fromImage(img)); pixId++; if(5==pixId){ pixId = 1; } } //解释计时 void Widget::on_stopButton_clicked() { timer->stop(); } //单次 void Widget::on_SingButton_clicked() { QTimer::singleShot(1000,this,SLOT(timeOutSlots())); }
6.QT文件操作
6.1文件和目录读写操作
在Qt中,文件和目录的读写操作主要使用QFile
和QDir
类
6.1.1文件的读写操作
1.写文件
使用QFile
类进行文件的写操作。首先,创建一个QFile
对象,然后打开文件并使用QTextStream
类进行写入操作。
QFile file("example.txt"); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << "Hello, World!"; file.close(); }
2.读文件
使用QFile
类进行文件的读操作。打开文件后,可以使用QTextStream
类逐行读取文本内容。
QFile file("example.txt"); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); QString line = in.readLine(); qDebug() << "Read from file: " << line; file.close(); }
6.1.2目录的操作
1.创建目录
使用QDir
类创建目录。如果目录已存在,mkdir()
函数会返回false。
QDir directory; if (!directory.mkdir("myDirectory")) { qDebug() << "Failed to create directory!"; }
2.遍历目录
使用QDir
类的entryList()
函数可以获取目录下的文件列表
QDir directory("myDirectory"); QStringList files = directory.entryList(QDir::Files); qDebug() << "Files in directory: " << files;
3.删除目录
使用QDir
类的rmdir()
函数可以删除目录。请注意,目录必须为空才能被成功删除。
QDir directory("myDirectory"); if (directory.exists() && directory.rmdir(".")) { qDebug() << "Directory deleted successfully!"; } else { qDebug() << "Failed to delete directory!"; }
6.2二进制文件读写
6.2.1二进制文件写入
1.打开文件
使用QFile
类打开一个文件,指定QIODevice::WriteOnly
标志表示以写入方式打开文件。
QFile file("data.bin"); if (file.open(QIODevice::WriteOnly)) { QDataStream out(&file); // 使用QDataStream关联QFile对象 }
2.写入数据
使用<<
操作符将数据写入到QDataStream
中。QDataStream
会自动处理数据的序列化。
int intValue = 42; double doubleValue = 3.14; QString stringValue = "Hello, World!"; out << intValue << doubleValue << stringValue;
3.关闭文件
file.close();
6.2.2二进制文件的读取
1.打开文件
使用QFile
类打开已有的二进制文件,指定QIODevice::ReadOnly
标志表示以只读方式打开文件。
QFile file("data.bin"); if (file.open(QIODevice::ReadOnly)) { QDataStream in(&file); // 使用QDataStream关联QFile对象 }
2.读取文件
使用>>
操作符将数据从QDataStream
中读取。QDataStream
会自动处理数据的反序列化。
int intValue; double doubleValue; QString stringValue; in >> intValue >> doubleValue >> stringValue;
3.关闭文件
file.close();
6.3利用MainWindow和文件读写实现一个编辑器
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<QFileDialog> #include<QString> #include<QMessageBox> #include<QDebug> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void newWindowSlot(); void openWindowSlot(); void saveWindowSlot(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //连接槽函数 connect(ui->newWindow,&QAction::triggered,this,&MainWindow::newWindowSlot); connect(ui->openWidow,&QAction::triggered,this,&MainWindow::openWindowSlot); connect(ui->saveWindow,&QAction::triggered,this,&MainWindow::saveWindowSlot); } MainWindow::~MainWindow() { delete ui; } //新建记事本 void MainWindow::newWindowSlot() { ui->textEdit->clear(); this->setWindowTitle("新建文本文档"); } //打开记事本 void MainWindow::openWindowSlot() { //点打开,弹出对话框getOpenFileName(对话框的父类,标题,路径,显示的文件类型) //QCoreApplication::applicationFilePath():获取当前路径 QString fileName = QFileDialog::getOpenFileName(this,"选择一个文件", QCoreApplication::applicationFilePath(),"*.cpp"); //如果文件名为空,则表示取消 if(fileName.isEmpty()){ QMessageBox::warning(this,"警告","请选择一个文件"); } else{ // qDebug() << fileName; //打开文件,创建文件对象 QFile file(fileName); //只读 file.open(QIODevice::ReadOnly); QByteArray ba = file.readAll(); //显示到界面 ui->textEdit->setText(QString(ba)); file.close(); } } //另存为 void MainWindow::saveWindowSlot() { QString fileName = QFileDialog::getSaveFileName(this,"选择一个文件", QCoreApplication::applicationFilePath()); if(fileName.isEmpty()){ QMessageBox::warning(this,"警告","请选择一个文件"); } else{ //打开文件,创建文件对象 QFile file(fileName); //只写 file.open(QIODevice::WriteOnly); QByteArray ba; //转换为QByteArray类型 QByteArray a = ui->textEdit->toPlainText().toUtf8(); ba.append(a); file.write(ba); file.close(); } }
6.4QT事件实现文件保存
QT事件类型如下:键盘事件,鼠标事件、拖放事件、滚动事件、绘屏事件、定时事件、焦点事件。
QT将系统产生的消息转化为QT事件,QT事件被封装为对象,所有的QT事件均继承抽象类QEvent,用于描述程序内部或外部发生的动作,任意的QObject对象都具备处理QT事件的能力。
event()函数是虚函数,重写event虚函数实现功能。
1.键盘事件
首先,重写虚函数keyPressEvent();
void keyPressEvent(QKeyEvent *k);
然后,实现虚函数
void MainWindow::keyPressEvent(QKeyEvent *k){ //判断ctrl+S键被按下 //modifiers哪些热键被按下了,controlModifier:ctrl键 Key_S:S键被按下了 if(k->modifiers()==Qt::controlModifier && k->key()==Qt::Key_S){ saveWindowsSlot(); } }
keyReleaseEvent(QKeyEvent *event):处理按键释放事件
2.鼠标事件
首先,重写虚函数mousePressEvent();
void mousePressEvent(QMouseEvent *m);
然后,实现虚函数
void mousePressEvent(QMouseEvent *m){ //获取鼠标位置 QPoint pt = m->pos(); qDebug() <<qt; //鼠标左键 if(m->button()==Qt::LeftButton){ qDebug() << "左键被按下"; } //鼠标右键 else if(m->button()==Qt::RightButton){ qDebug() <<"右键被按下"; } }
mouseReleaseEvent(QMouseEvent *m)//处理鼠标按键释放事件 mouseMoveEvent(QMouseEvent *m)//处理鼠标移动事件
3.定时器事件
定时器事件是在一定的事件间隔内周期性触发的事件
void MyWidget::timerEvent(QTimerEvent *event){ qDebug() <<"Timer Event Triggered!"; }
7.Qt网络--TCP
6.1TCP客户端
头文件
#include<QTcpSocket> #include<QHostAddress>
1.创建socket对象
QTcpSocket *socket; socket = new QTcpSocket;
2.获取ip地址和端口号
QString ip = ui->ipLineEdit->text(); QString port = ui->portLineEdit->text();
3.连接服务器
socket->connectToHost(QHostAddress(ip),port.toShort());
4.判断是否连接成功
connect(socket,&QTcpSocket::connected,[this](){ QMessageBox::information(this,"连接提示","连接服务器成功"); });
5.断开连接也要发出信号
connect(socket,&QTcpSocket::disconnected,[this](){ QMessageBox::information(this,"警告","与服务器断开"); });
6.2TCP服务端
头文件
#include<QTcpServer> #include<QTcpSocket> #include<QHostAddress>
1.创建server对象
QTcpServer *server; server = new QTcpServer;
2.监听,不需要绑定
server->listen(QHostAddress::AnyIPv4,8000);//监听任意ipv4地址,端口号8000
3.客户端发起连接,server发起信号
connect(server,&QTcpServer::newConnection.this,&Widget::newClientHandle);//tcp建立一个新的连接
4.创建TCP连接
void Widget::newClientHandle(){ //建立TCP连接 QTcpSocket *socket = server->nextPendingConnect(); //显示 ui->iplineEdit->setText(socket->peerAddress().toString()); ui->portlineEdit->setText(QString::number(socket->peerPort()); }
6.3QT页面跳转
1.首先创建一个新的界面chat.ui
2.在判断是否连接成功后,首先要隐藏之前的界面
this->hide();
3.然后进行页面跳转
chat* c = new chat(socket); c->show();
4.在chat.h中,添加有参构造的参数
explicit chat(QTcpSocket *s,QWidget *parent = nullptr); private: QTcpSocket *socket;
chat(QTcpSocket *s,QWidget *parent){ socket = s; }
客户端发送消息
void chat::on_sendButton_clicked(){ QByteArray ba; ba.append(ui->lineEdit->text().toUtf8); socket->write(ba); }
服务器接收消息
1.服务器接收到客户端收到的消息,socket发出readyread信号
connect(socket,&QTcpSocket::readyRead,this,&Widget::clientInfoSolt);
2.clientInfoSolt处理信号
void Widget::clientInfoSolt(){ //获取信号的发出者 QTcpSocket *s = (QTcpSocket *)sender(); //显示消息到界面 ui->clientLineEdit->setText(QString(s.readAll())); }
6.4服务器中加入多线程
1.方式一错误 socket对象不能跨线程使用
1.首先创建线程类mythread.h和mythread.cpp
void myThread::run(){ connect(socket,&QTcpSocket::readyRead,this,&myThread::clientInfoSolt); } void myThread::clientInfoSolt(){ qDebug() << socket->readAll(); }
2.在创建TCP连接之后,开启线程,线程进行连接操作
myThread *t = new myThread(socket); t->start();
2.方式二
socket对象不能跨线程使用,但是文件描述符可以
所以将socket对象转换成文件描述符传过去,然后在线程中再转换为sokcet
1.头文件
#include<QThread>
2.创建MyTcpServer类,这个类是继承QTcpServer类的
3.然后在MyTcpServer类中重写虚函数incomingConnection。
用来创建线程对象和事件对象,并建立线程和事件之间的联系,线程启动。
连接clienthander类里面的working()槽函数
//有客户端连接,会触发该函数 void MyTcpServer::incomingConnection(qintptr socketDescriptor){ QThread *subThread = new QThread; //线程对象 ClientHandler *myClient = new ClientHandler(socketDescriptor); //事件对象 把文件描述符传进去 myClient->moveToThread(subThread); //将事件添加到线程中 subThread->start(); //启动线程 connect(this,&MyTcpServer::signal_to_thread,myClient,&ClientHandler::working);//myClient这个事件来处理 working emit signal_to_thread();//发送信号 这个信号是自定义的信号,让clienthander类收到这个信号 }
4.实现working函数
void ClientHandler::working(){ socket = new QTcpSocket;//创建socket对象 socket->setSocketDescriptor(socketDescriptor);//将文件描述符添加到socket对象 connect(socket,&QTcpSocket::readyRead,this,&ClientHandler::recvInfo);//连接recvInfo } void recvInfo(){ qDebug() << socket->readAll(); //读出来 }
6.5自定义信号
在线程里操作不了UI,因此
将读出来的信息 socket->readAll()发送到ui窗口显示
不同对象之间进行通信。线程间通信
1.线程首先将数据读出来了,然后放到QByteArray里面
QByteArray ba = socket->readAll();
2.利用emit 发送信号
signals: void sendToWidget(QByteArray b); emit sendToWidget(ba);
3.widget.cpp做连接
connect(t,&myThread::sendToWiget,this,&Widget::threadSolt); void Widget::threadSolt(QByteArray b){ ui->mainLineEdit->setText(QString(b)); }
6.6.代码
TCP客户端:
widget.h: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTcpSocket> #include<QHostAddress> #include<QMessageBox> #include<chat.h> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_cancelButton_clicked(); void on_connectButton_clicked(); private: Ui::Widget *ui; QTcpSocket *socket; }; #endif // WIDGET_H
widget.cpp #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //创建socket对象 socket = new QTcpSocket; } Widget::~Widget() { delete ui; } void Widget::on_cancelButton_clicked() { this->close(); } void Widget::on_connectButton_clicked() { //获取IP地址和端口号 QString ip = ui->ipLineEdit->text(); QString port = ui->portLineEdit->text(); //连接服务器 socket->connectToHost(QHostAddress(ip),port.toShort()); //判断是否连接成功 connect(socket,&QTcpSocket::connected,[this](){ QMessageBox::information(this,"连接提示","连接服务器成功"); //隐藏之前的页面 this->hide(); //页面跳转 chat* c = new chat(socket); c->show(); }); //连接断开也会发出信号 connect(socket,&QTcpSocket::disconnected,[this](){ QMessageBox::warning(this,"警告","与服务器断开"); }); }
chat.h: #ifndef CHAT_H #define CHAT_H #include <QWidget> #include<QTcpSocket> namespace Ui { class chat; } class chat : public QWidget { Q_OBJECT public: explicit chat(QTcpSocket *s,QWidget *parent = nullptr); ~chat(); private slots: void on_clearButton_clicked(); void on_sendButton_clicked(); private: Ui::chat *ui; QTcpSocket *socket; }; #endif // CHAT_H
chat.cpp: #include "chat.h" #include "ui_chat.h" chat::chat(QTcpSocket *s, QWidget *parent) : QWidget(parent) , ui(new Ui::chat) { ui->setupUi(this); socket = s; } chat::~chat() { delete ui; } //取消 void chat::on_clearButton_clicked() { ui->lineEdit->clear(); } //发送 void chat::on_sendButton_clicked() { QByteArray ba; ba.append(ui->lineEdit->text().toUtf8()); socket->write(ba); }
TCP服务端:
myThread.h: #ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include<QThread> #include<QTcpSocket> #include<QDebug> class myThread : public QThread { Q_OBJECT public: explicit myThread(QTcpSocket *s); void run(); signals: void sendToWidget(QByteArray b); private slots: void clientInfoSlot(); private: QTcpSocket *socket; }; #endif // MYTHREAD_H
myThread.cpp: #include "mythread.h" myThread::myThread(QTcpSocket *s){ socket = s; } void myThread::run() { //连接 connect(socket,&QTcpSocket::readyRead,this,&myThread::clientInfoSlot); } void myThread::clientInfoSlot() { //接收,打印 // qDebug() << socket->readAll(); QByteArray ba = socket->readAll(); //发送 emit sendToWidget(ba); }
widget.h: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTcpServer> #include<QTcpSocket> #include<mythread.h> #define PORT 8000 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void newClientHandle(); void clientInfoSolt(); void threadSolt(QByteArray b); private: Ui::Widget *ui; QTcpServer *server; }; #endif // WIDGET_H
widget.cpp: #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //创建server对象 server = new QTcpServer; //监听就可以了,不需要绑定 server->listen(QHostAddress::AnyIPv4,PORT); //客户端发起连接,server发起信号 connect(server,&QTcpServer::newConnection,this,&Widget::newClientHandle); } Widget::~Widget() { delete ui; } void Widget::newClientHandle() { //创建TCP连接 QTcpSocket *socket = server->nextPendingConnection(); // socket->peerAddress();//客户端地址 // socket->peerPort();//客户端端口号 ui->iplineEdit->setText(socket->peerAddress().toString()); ui->portlineEdit->setText(QString::number(socket->peerPort())); //服务器接收到客户端收到的消息,socket发出readyread信号 // connect(socket,&QTcpSocket::readyRead,this,&Widget::clientInfoSolt); //开启线程 myThread* t = new myThread(socket); t->start(); connect(t,&myThread::sendToWidget,this,&Widget::threadSolt); } void Widget::threadSolt(QByteArray b) { ui->clientLineEdit->setText(QString(b)); } // void Widget::clientInfoSolt() // { // //获取信号的发出者 // QTcpSocket *s = (QTcpSocket *)sender(); // //显示消息到界面 // ui->clientLineEdit->setText(QString(s->readAll())); // }
8.QTmySql数据库操作
头文件
#include<QSqlDatabase> QSqlDatabase db;
1.连接数据库
db = QSqlDatabase::addDatabase("QMYSQL");//连接mysql数据库 db.setDatabaseName("mydatabase"); //数据库名 db.setHostName("localhost");//本机地址 db.setUserName("root");//用户名 db.setPassword("root");//密码
if(db.open()){ QMessageBox::information(this,"连接提示","连接成功"); } else{ QMessageBox::information(this,"连接提示","连接失败"); }
2.插入数据库
QString id = ui->idLineEdit->text(); QString name = ui->nameLineEdit->text(); QString birth = ui->birLineEdit->text(); //数据库 QString sql = QString("insert into student values ('%1','%2','%3');").arg(id).arg(name).arg(birth); QSqlQuery query; //插入数据 if(query.exec(sql)){ QMessageBox::information(this,'插入提示','插入成功'); } else{ QMessageBox::information(this,'插入提示','插入失败'); }
3.查询
QSqlQuery query; query.exec("select * from student;"); while(query.next()){ qDebug() << query.value(0); }
原文地址:https://blog.csdn.net/qq_51330350/article/details/142880853
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!