模拟cmd窗口
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QProcess>
#include <QMessageBox>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
// 将槽函数放在这里
void on_commitButton_clicked();
void on_cancelButton_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 信号与槽函数的三种连接方式
connect(ui->comLineEdit,SIGNAL(returnPressed()),this,SLOT(on_commitButton_clicked()));
connect(ui->comLineEdit,&QLineEdit::returnPressed,this,&Widget::on_commitButton_clicked);
connect(ui->cancelButton,&QPushButton::clicked,this,&Widget::on_cancelButton_clicked);
// 当槽函数的代码过少时可以考虑,这种连接方式,不需要额外的的槽函数
connect(ui->browsButton_3,&QPushButton::clicked,[this](){
// QMessageBox 产生弹窗,this表示当前的窗口是这个窗口的父类,需要添加#include <QMessageBox>
QMessageBox::information(this,"左上角","内容");
});
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_commitButton_clicked()
{
// 获取文本框的数据
QString program=ui->comLineEdit->text();
// 运行程序,需要添加#include <QProcess>
QProcess *myProcess = new QProcess(this);
myProcess->start(program);
}
void Widget::on_cancelButton_clicked()
{
// 关闭窗口
this->close();
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
计算器
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置窗口的大小,使它不会因为拖动而改变大小
this->setMaximumSize(180,270);
this->setMinimumSize(180,270);
// 设置标题
this->setWindowTitle("计算机");
// 设置行编辑的字体和大小
QFont f("宋体",22);
ui->lineEdit->setFont(f);
// 按钮贴上图片
QIcon Icon("C:\\Users\\地表最菜\\Pictures\\Saved Pictures\\test.jpg");
QSize IconSize(60,60);
ui->pushButton_back->setIcon(Icon);
ui->pushButton_back->setIconSize(IconSize);
// 改变按钮背景色
ui->pushButton_equal->setStyleSheet("background:blue");
connect(ui->pushButton_0,&QPushButton::clicked,this,&Widget::clicked_Button_0);
connect(ui->pushButton_1,&QPushButton::clicked,this,&Widget::clicked_Button_1);
connect(ui->pushButton_2,&QPushButton::clicked,this,&Widget::clicked_Button_2);
connect(ui->pushButton_3,&QPushButton::clicked,this,&Widget::clicked_Button_3);
connect(ui->pushButton_4,&QPushButton::clicked,this,&Widget::clicked_Button_4);
connect(ui->pushButton_5,&QPushButton::clicked,this,&Widget::clicked_Button_5);
connect(ui->pushButton_6,&QPushButton::clicked,this,&Widget::clicked_Button_6);
connect(ui->pushButton_7,&QPushButton::clicked,this,&Widget::clicked_Button_7);
connect(ui->pushButton_8,&QPushButton::clicked,this,&Widget::clicked_Button_8);
connect(ui->pushButton_9,&QPushButton::clicked,this,&Widget::clicked_Button_9);
connect(ui->pushButton_muti,&QPushButton::clicked,this,&Widget::clicked_Button_muti);
connect(ui->pushButton_reduce,&QPushButton::clicked,this,&Widget::clicked_Button_reduce);
connect(ui->pushButton_add,&QPushButton::clicked,this,&Widget::clicked_Button_add);
connect(ui->pushButton_div,&QPushButton::clicked,this,&Widget::clicked_Button_div);
connect(ui->pushButton_equal,&QPushButton::clicked,this,&Widget::clicked_Button_equal);
connect(ui->pushButton_back,&QPushButton::clicked,this,&Widget::clicked_Button_back);
connect(ui->pushButton_Clear,&QPushButton::clicked,this,&Widget::clicked_Button_clear);
connect(ui->pushButton_right,&QPushButton::clicked,this,&Widget::clicked_Button_right);
connect(ui->pushButton_left,&QPushButton::clicked,this,&Widget::clicked_Button_left);
}
Widget::~Widget()
{
delete ui;
}
void Widget::clicked_Button_0()
{
expression+='0';
// 设置行编辑的输出
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_1()
{
expression+='1';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_2()
{
expression+='2';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_3()
{
expression+='3';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_4()
{
expression+='4';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_5()
{
expression+='5';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_6()
{
expression+='6';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_7()
{
expression+='7';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_8()
{
expression+='8';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_9()
{
expression+='9';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_muti()
{
expression+='*';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_reduce()
{
expression+='-';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_add()
{
expression+='+';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_div()
{
expression+='/';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_equal()
{
expression.clear();
ui->lineEdit->clear();
expression+="我也不知道,懒得写了";
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_right()
{
expression+=')';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_left()
{
expression+='(';
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_back()
{
// 删除最后一位
expression.chop(1);
ui->lineEdit->setText(expression);
}
void Widget::clicked_Button_clear()
{
expression.clear();
ui->lineEdit->clear();
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
// 解决设计时大小与运行之后大小相差太大的缺陷
if(QT_VERSION>=QT_VERSION_CHECK(5,6,0))
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void clicked_Button_0();
void clicked_Button_1();
void clicked_Button_2();
void clicked_Button_3();
void clicked_Button_4();
void clicked_Button_5();
void clicked_Button_6();
void clicked_Button_7();
void clicked_Button_8();
void clicked_Button_9();
void clicked_Button_add();
void clicked_Button_reduce();
void clicked_Button_muti();
void clicked_Button_div();
void clicked_Button_equal();
void clicked_Button_back();
void clicked_Button_clear();
void clicked_Button_right();
void clicked_Button_left();
private:
Ui::Widget *ui;
QString expression;
};
#endif // WIDGET_H
基于定时器与图片的相册
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButton_start,&QPushButton::clicked,this,&Widget::pushButton_start_clicked);
connect(ui->pushButton_stop,&QPushButton::clicked,this,&Widget::pushButton_stop_clicked);
// 显示图片
QPixmap pic("C:\\Users\\地表最菜\\Pictures\\Saved Pictures\\pic (1).png");
ui->label->setPixmap(pic);
namekey=2;
}
Widget::~Widget()
{
delete ui;
}
void Widget::pushButton_start_clicked()
{
// 开启定时器,返回定时器编号
// 当时间到了发出信号调用timerEvent,之后又循环计时间
mytimerid=this->startTimer(TIMEOUT);
}
void Widget::timerEvent(QTimerEvent *event)
{
if(event->timerId()!=mytimerid){
return;
}
// 拼接图片的路径
QString picname("C:\\Users\\地表最菜\\Pictures\\Saved Pictures\\pic (");
// 将数字转换为QString
picname+=QString::number(namekey);
picname+=").png";
// 让标签显示图片
QPixmap pic(picname);
ui->label->setPixmap(pic);
namekey++;
if(namekey>=12)
namekey=1;
}
void Widget::pushButton_stop_clicked()
{
// 关闭定时器
this->killTimer(mytimerid);
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPixmap>
#include <QTimer>
#define TIMEOUT 2*1000
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
virtual void timerEvent(QTimerEvent *event);
~Widget();
private slots:
void pushButton_start_clicked();
void pushButton_stop_clicked();
private:
Ui::Widget *ui;
int namekey;
int mytimerid;
};
#endif // WIDGET_H
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
if(QT_VERSION>=QT_VERSION_CHECK(5,6,0))
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
必须要勾上scaledContents,让图片自适应标签,否则图片会出现只会显示部分的情况
其它方式展示图片与定时器的功能
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTimer>
#define TIMEOUT 2*1000
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void pushButton_start_clicked();
void pushButton_stop_clicked();
void pushButton_signal_clicked();
void myTimerEvent();
private:
Ui::Widget *ui;
int picId;
QTimer *timer;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
timer=new QTimer;
connect(timer,&QTimer::timeout,this,&Widget::myTimerEvent);
connect(ui->pushButton_start,&QPushButton::clicked,this,&Widget::pushButton_start_clicked);
connect(ui->pushButton_stop,&QPushButton::clicked,this,&Widget::pushButton_stop_clicked);
connect(ui->pushButton_signal,&QPushButton::clicked,this,&Widget::pushButton_signal_clicked);
picId=2;
QImage img;
img.load("C:\\Users\\地表最菜\\Pictures\\Saved Pictures\\pic (1).png");
ui->label->setPixmap(QPixmap::fromImage(img));
}
Widget::~Widget()
{
delete ui;
}
void Widget::pushButton_start_clicked()
{
timer->start(TIMEOUT);
}
void Widget::myTimerEvent()
{
// 文件路径名拼接
QString imgname("C:\\Users\\地表最菜\\Pictures\\Saved Pictures\\pic (");
imgname+=QString::number(picId);
imgname+=").png";
// 图片显示
QImage img;
img.load(imgname);
ui->label->setPixmap(QPixmap::fromImage(img));
picId++;
if(picId>=12)
picId=1;
}
void Widget::pushButton_stop_clicked()
{
timer->stop();
}
void Widget::pushButton_signal_clicked()
{
// 单次定时
QTimer::singleShot(TIMEOUT,this,&Widget::myTimerEvent);
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
文件操作
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void open_file();
void save_file();
void new_file();
};
#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->action_new,&QAction::triggered,this,&MainWindow::new_file);
connect(ui->action_open,&QAction::triggered,this,&MainWindow::open_file);
connect(ui->action_save,&QAction::triggered,this,&MainWindow::save_file);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::new_file()
{
// 清空内容
ui->textEdit->clear();
// 修改窗口文字
this->setWindowTitle("新建一个文件");
}
void MainWindow::open_file()
{
// 选择文件,并且返回文件的路径,如果点击取消则会返回空,需要添加#include <QFileDialog>
// applicationFilePath获取当前进程的路径,默认路径
// .txt限制文件的类型,如果不写则代表所有的类型
QString fileName = QFileDialog::getOpenFileName(this, "打开一个文件",
QApplication::applicationFilePath(),"*.txt");
if(fileName.isEmpty()){
// 警告窗口,需要添加QMessageBox头文件
QMessageBox::warning(this,"警告","请选择一个文件");
}else{
// 在调试信息输出文件的名字
qDebug() << fileName;
// 打开文件,并且以只读方式打开
QFile file(fileName);
file.open(QIODevice::ReadOnly);
// 读取文件,注意返回类型是QByteArray
QByteArray data=file.readAll();
// 修改textEdit里面的内容
ui->textEdit->setText(QString(data));
// 注意关闭文件
file.close();
}
}
void MainWindow::save_file()
{
// 打开要保存的路径,并且返回路径,如果不写第四个参数则代表所有的文件
QString fileName=QFileDialog::getSaveFileName(this,"保存文件",
QApplication::applicationFilePath());
if(fileName.isEmpty()){
QMessageBox::warning(this,"警告","请选择一个文件");
}else{
QFile file(fileName);
file.open(QIODevice::WriteOnly);
// 获取textEdit里面的内容,返回的是QString
QString data=ui->textEdit->toPlainText();
// 将QString转换为QByteArray
QByteArray bytedata;
bytedata.append(data);
file.write(bytedata);
file.close();
}
}
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
注意UI时要加上&符号,让用户可以通过键盘来实现点击操作
消息基础
application能够知道哪个窗口在哪个位置,能知道应该由哪个窗口来接收消息,这个窗口会调用自己的消息处理函数
窗口的event()函数处理所有经过窗口的消息
消息处理函数是虚函数,使用要进行重载
常见的QT事件类型如下:
- 键盘事件:按键按下和松开
- 鼠标事件:鼠标移动,鼠标按键的按下和松开
- 拖放事件:用鼠标进行拖放
- 滚轮事件:鼠标滚轮滚动
- 绘屏事件:重绘屏幕的某些部分
- 定时事件:定时器到时
- 焦点事件:键盘焦点移动
- 进入和离开事件:鼠标移动widget之内,或是移出
- 移动事件:widget的位置改变
- 大小改变事件:widget的大小改变
- 显示和隐藏事件:widget显示和隐藏
- 窗口事件:窗口是否为当前窗口
QT将系统产生的消息转化为QT事件,QT事件被封装为对象,所有的QT事件均继承抽象类QEvent,用于描述内部或外部发生的动作,任意的QObject对象都具备处理QT事件的能力。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QMouseEvent>
#include <QKeyEvent>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
// 重载键盘事件
virtual void keyPressEvent(QKeyEvent *k);
// 重载鼠标事件
virtual void mousePressEvent(QMouseEvent *m);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void open_file();
void save_file();
void new_file();
};
#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->action_new,&QAction::triggered,this,&MainWindow::new_file);
connect(ui->action_open,&QAction::triggered,this,&MainWindow::open_file);
connect(ui->action_save,&QAction::triggered,this,&MainWindow::save_file);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::new_file()
{
// 清空内容
ui->textEdit->clear();
// 修改窗口文字
this->setWindowTitle("新建一个文件");
}
void MainWindow::open_file()
{
// 选择文件,并且返回文件的路径,如果点击取消则会返回空,需要添加#include <QFileDialog>
// applicationFilePath获取当前进程的路径,默认路径
// .txt限制文件的类型,如果不写则代表所有的类型
QString fileName = QFileDialog::getOpenFileName(this, "打开一个文件",
QApplication::applicationFilePath(),"*.txt");
if(fileName.isEmpty()){
// 警告窗口,需要添加QMessageBox头文件
QMessageBox::warning(this,"警告","请选择一个文件");
}else{
// 在调试信息输出文件的名字
qDebug() << fileName;
// 打开文件,并且以只读方式打开
QFile file(fileName);
file.open(QIODevice::ReadOnly);
// 读取文件,注意返回类型是QByteArray
QByteArray data=file.readAll();
// 修改textEdit里面的内容
ui->textEdit->setText(QString(data));
// 注意关闭文件
file.close();
}
}
void MainWindow::save_file()
{
// 打开要保存的路径,并且返回路径,如果不写第四个参数则代表所有的文件
QString fileName=QFileDialog::getSaveFileName(this,"保存文件",
QApplication::applicationFilePath());
if(fileName.isEmpty()){
QMessageBox::warning(this,"警告","请选择一个文件");
}else{
QFile file(fileName);
file.open(QIODevice::WriteOnly);
// 获取textEdit里面的内容,返回的是QString
QString data=ui->textEdit->toPlainText();
// 将QString转换为QByteArray
QByteArray bytedata;
bytedata.append(data);
file.write(bytedata);
file.close();
}
}
void MainWindow::keyPressEvent(QKeyEvent *k)
{
// 实现ctrl+s保存文件
// 需要添加头文件,#include <QMouseEvent>
// 可以通过帮助搜素查找函数和宏
// modifiers查看热键是否被按下,key代表普通键是否被按下
if(k->modifiers()==Qt::ControlModifier&&k->key()==Qt::Key_S){
save_file();
}
}
void MainWindow::mousePressEvent(QMouseEvent *m)
{
// 需要添加头文件,#include <QKeyEvent>
// pos函数返回坐标
qDebug()<<m->pos();
if(m->button()==Qt::LeftButton){
qDebug()<<"按下左键";
}else if(m->button()==Qt::RightButton){
qDebug()<<"按下右键";
}
}
客户端
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QMessageBox>
#include <QHostAddress>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void buttonCommitClicked(void);
void buttonCancelClicked(void);
private:
Ui::Widget *ui;
QTcpSocket *socket;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButton_Commit,&QPushButton::clicked,this,&Widget::buttonCommitClicked);
connect(ui->pushButton_Cancel,&QPushButton::clicked,this,&Widget::buttonCancelClicked);
// 初始化socket
socket=new QTcpSocket;
}
Widget::~Widget()
{
delete ui;
}
void Widget::buttonCommitClicked(void)
{
// 获取ip和端口号
QString ip=ui->lineEdit_Ip->text();
QString port=ui->lineEdit_Port->text();
// 连接服务器
socket->connectToHost(QHostAddress(ip),port.toShort());
// 连接状态提醒
connect(socket,&QTcpSocket::connected,[this](){
QMessageBox::information(this,"连接提示","连接成功");
});
connect(socket,&QTcpSocket::disconnected,[this](){
QMessageBox::warning(this,"连接提示","连接失败");
});
}
void Widget::buttonCancelClicked(void)
{
this->close();
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
注意:必须修改.pro工程文件,在第七行QT末尾加上network
服务器
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#define PORT 8000
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void newConnectHander(void);
private:
Ui::Widget *ui;
QTcpServer *server;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
server=new QTcpServer;
// 进入监听状态
// 需要QHostAddress和QTcpServer头文件
server->listen(QHostAddress::AnyIPv4,PORT);
// 当出现连接时运行函数
connect(server,&QTcpServer::newConnection,this,&Widget::newConnectHander);
}
Widget::~Widget()
{
delete ui;
}
void Widget::newConnectHander(void)
{
// 建立TCP连接
// 需要QTcpSocket头文件
QTcpSocket *s=server->nextPendingConnection();
// 获取客户端的IP地址
// 将QHostAddress类型转换为QString类型
ui->lineEdit_IP->setText(s->peerAddress().toString());
// 获取客户端的端口号,端口号很有可能与服务器端口号不一样
// 将数字类型转换为QString类型
ui->lineEdit_PORT->setText(QString::number(s->peerPort()));
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
注意:必须修改.pro工程文件,在第七行QT末尾加上network
在TCP客户端基础实现信息传输
#ifndef CHAT_H
#define CHAT_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class Chat;
}
class Chat : public QWidget
{
Q_OBJECT
public:
explicit Chat(QTcpSocket* socket,QWidget *parent = 0);
~Chat();
private slots:
void sendMessage(void);
void recvMessage(void);
void clearMessage(void);
private:
Ui::Chat *ui;
QTcpSocket *socket;
};
#endif // CHAT_H
#include <QTcpSocket>
#include <QMessageBox>
#include <QHostAddress>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void buttonCommitClicked(void);
void buttonCancelClicked(void);
private:
Ui::Widget *ui;
QTcpSocket *socket;
};
#endif // WIDGET_H
#include "chat.h"
#include "ui_chat.h"
Chat::Chat(QTcpSocket *socket, QWidget *parent) :
QWidget(parent),
ui(new Ui::Chat)
{
ui->setupUi(this);
this->socket=socket;
// 服务器发送数据到客户端,客户端会产生readyRead信号
connect(socket,&QTcpSocket::readyRead,this,&Chat::recvMessage);
connect(ui->pushButtonSend,&QPushButton::clicked,this,&Chat::sendMessage);
connect(ui->pushButtonClear,&QPushButton::clicked,this,&Chat::clearMessage);
}
Chat::~Chat()
{
delete ui;
}
void Chat::recvMessage()
{
// 将QByteArray类型转换为QString
// 读出数据
ui->lineEditRecv->setText(QString(socket->readAll()));
}
void Chat::sendMessage()
{
QByteArray data;
// 将QString转换为QByteArray类型
data.append(ui->lineEditSend->text());
// 写数据
socket->write(data);
ui->lineEditSend->clear();
}
void Chat::clearMessage()
{
ui->lineEditRecv->clear();
}
#include "widget.h"
#include "ui_widget.h"
#include "chat.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButton_Commit,&QPushButton::clicked,this,&Widget::buttonCommitClicked);
connect(ui->pushButton_Cancel,&QPushButton::clicked,this,&Widget::buttonCancelClicked);
// 初始化socket
socket=new QTcpSocket;
}
Widget::~Widget()
{
delete ui;
}
void Widget::buttonCommitClicked(void)
{
// 获取ip和端口号
QString ip=ui->lineEdit_Ip->text();
QString port=ui->lineEdit_Port->text();
// 连接服务器
socket->connectToHost(QHostAddress(ip),port.toShort());
// 连接状态提醒
connect(socket,&QTcpSocket::connected,[this](){
QMessageBox::information(this,"连接提示","连接成功");
// 注意这里必须使用堆空间,如果使用栈空间当函数运行完毕会被释放
Chat *c=new Chat(socket);
// 展示窗口
c->show();
// 隐藏现在这个窗口
this->hide();
});
connect(socket,&QTcpSocket::disconnected,[this](){
QMessageBox::warning(this,"连接提示","连接失败");
});
}
void Widget::buttonCancelClicked(void)
{
this->close();
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
TCP服务器基础上实现信息传输
#ifndef CHATSERVER_H
#define CHATSERVER_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class ChatServer;
}
class ChatServer : public QWidget
{
Q_OBJECT
public:
explicit ChatServer(QTcpSocket *socket, QWidget *parent = 0);
~ChatServer();
private slots:
void SendMessage(void);
void RecvMessage(void);
void ClearMessage(void);
private:
Ui::ChatServer *ui;
QTcpSocket *socket;
};
#endif // CHATSERVER_H
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#define PORT 8000
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void newConnectHander(void);
private:
Ui::Widget *ui;
QTcpServer *server;
};
#endif // WIDGET_H
#include "chatserver.h"
#include "ui_chatserver.h"
ChatServer::ChatServer(QTcpSocket *socket, QWidget *parent) :
QWidget(parent),
ui(new Ui::ChatServer)
{
ui->setupUi(this);
this->socket=socket;
connect(socket,&QTcpSocket::readyRead,this,&ChatServer::RecvMessage);
connect(ui->pushButtonSend,&QPushButton::clicked,this,&ChatServer::SendMessage);
connect(ui->pushButtonClear,&QPushButton::clicked,this,&ChatServer::ClearMessage);
}
ChatServer::~ChatServer()
{
delete ui;
}
void ChatServer::RecvMessage()
{
// 获取信号的发送者
QTcpSocket *s=(QTcpSocket *)sender();
ui->lineEditRecv->setText(QString(s->readAll()));
}
void ChatServer::SendMessage()
{
QByteArray data;
data.append(ui->lineEditSend->text());
socket->write(data);
ui->lineEditSend->clear();
}
void ChatServer::ClearMessage()
{
ui->lineEditRecv->clear();
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "widget.h"
#include "ui_widget.h"
#include "chatserver.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
server=new QTcpServer;
// 进入监听状态
// 需要QHostAddress和QTcpServer头文件
server->listen(QHostAddress::AnyIPv4,PORT);
// 当出现连接时运行函数
connect(server,&QTcpServer::newConnection,this,&Widget::newConnectHander);
}
Widget::~Widget()
{
delete ui;
}
void Widget::newConnectHander(void)
{
// 建立TCP连接
// 需要QTcpSocket头文件
QTcpSocket *s=server->nextPendingConnection();
// 获取客户端的IP地址
// 将QHostAddress类型转换为QString类型
ui->lineEdit_IP->setText(s->peerAddress().toString());
// 获取客户端的端口号,端口号很有可能与服务器端口号不一样
// 将数字类型转换为QString类型
ui->lineEdit_PORT->setText(QString::number(s->peerPort()));
ChatServer *chat=new ChatServer(s);
chat->show();
}
创建新窗口的操作与在TCP客户端基础实现信息传输是一样的
多线程和自定义信号
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QThread>
#include <QTcpSocket>
class myThread:public QThread
{
Q_OBJECT
public:
myThread(QTcpSocket *socket);
// 线程运行函数
void run();
private slots:
void handleData(void);
signals:
// 创建信号
void sendData(QByteArray data);
private:
QTcpSocket *socket;
};
#endif // MYTHREAD_H
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#define PORT 8000
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void newConnectHander(void);
void handData(QByteArray data);
private:
Ui::Widget *ui;
QTcpServer *server;
};
#endif // WIDGET_H
#include "mythread.h"
myThread::myThread(QTcpSocket *socket)
{
// 接收socket
this->socket=socket;
}
void myThread::run()
{
// 当有可读事件时用handleData函数处理
connect(socket,&QTcpSocket::readyRead,this,&myThread::handleData);
}
void myThread::handleData()
{
QByteArray data;
data=socket->readAll();
// 发送信号,不能通过传参的方式对ui进行修改,ui只能自己类可以进行修改
emit sendData(data);
}
#include "widget.h"
#include "ui_widget.h"
#include "mythread.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
server=new QTcpServer;
server->listen(QHostAddress::AnyIPv4,PORT);
connect(server,&QTcpServer::newConnection,this,&Widget::newConnectHander);
}
Widget::~Widget()
{
delete ui;
}
void Widget::newConnectHander(void)
{
QTcpSocket *s=server->nextPendingConnection();
ui->lineEditIp->setText(s->peerAddress().toString());
ui->lineEditPort->setText(QString::number(s->peerPort()));
myThread *thread=new myThread(s);
// 开始线程
thread->start();
// 处理thread发出来的sendData信号
connect(thread,&myThread::sendData,this,&Widget::handData);
}
void Widget::handData(QByteArray data)
{
ui->lineEditShow->setText(QString(data));
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
ui只能在自己类才可以进行修改
连接MYSQL数据库
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlQuery>
#include <QDebug>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void insertButton(void);
void cancelButton(void);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 加载mysql驱动
QSqlDatabase base=QSqlDatabase::addDatabase("QMYSQL");
base.setHostName("47.108.71.9");
base.setDatabaseName("dyl");
base.setUserName("DYL");
base.setPassword("199911");
// open成功返回true,失败返回false
if(base.open()){
QMessageBox::information(this,"连接提示","连接成功");
}else{
QMessageBox::warning(this,"连接提示","连接失败");
}
connect(ui->pushButtonCheck,&QPushButton::clicked,this,&Widget::cancelButton);
connect(ui->pushButtonInsert,&QPushButton::clicked,this,&Widget::insertButton);
}
Widget::~Widget()
{
delete ui;
}
void Widget::insertButton()
{
QString id=ui->lineEditId->text();
QString name=ui->lineEditName->text();
QString sex=ui->lineEditSex->text();
QString birth=ui->lineEditBirthday->text();
QString sclass=ui->lineEditClass->text();
QString command=QString("insert into student values('%1','%2','%3','%4','%5');").arg(id).arg(name).arg(sex).arg(birth).arg(sclass);
// 操作数据库的对象,需要头文件
QSqlQuery data;
if(data.exec(command)){
QMessageBox::information(this,"插入提示","插入成功");
}else{
QMessageBox::warning(this,"插入提示","插入失败");
}
}
void Widget::cancelButton()
{
QSqlQuery data;
QString command("select * from student;");
data.exec(command);
while(data.next()){
qDebug()<<data.value(0);
qDebug()<<data.value(1);
qDebug()<<data.value(2);
qDebug()<<data.value(3);
qDebug()<<data.value(4);
}
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
注意:需要在工程文件.pro下加入sql,而且必须在qc的lib库中加入libmysql.dll文件,不然无法加载驱动
使用模型显示数据库表
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlTableModel>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void checkButton(void);
private:
Ui::Widget *ui;
QSqlTableModel *view;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("47.108.71.9");
db.setDatabaseName("dyl");
db.setUserName("DYL");
db.setPassword("199911");
if(db.open()){
QMessageBox::information(this,"连接提示","连接成功");
view=new QSqlTableModel;
// 模型与表进行关联
view->setTable("student");
// 模型与界面进行关联
ui->tableView->setModel(view);
connect(ui->checkButton,&QPushButton::clicked,this,&Widget::checkButton);
}else{
QMessageBox::warning(this,"连接提示","连接失败");
}
}
Widget::~Widget()
{
delete ui;
}
void Widget::checkButton()
{
// 显示出表
view->select();
}
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}