Qt网络编程笔记
本博客是在已经写完的一本笔记上而进行的,所以整理清除,结构清晰,有不懂的朋友可以一起交流呀。
下文为了方便,将(xxx.h)和(xxx.cpp)文件放到了一个代码区,以"空格+换行符+//"为分割线
初始代码(main.cpp)
因为main.cpp代码基本一样,因此在下文中该代码区的代码以此为准,如若修改会做说明
#include "mywidget.h"
#include // 应用程序类
#include // 窗口基类:一个大窗口
/*QApplication应用程序类Qt头文件my.h头文件和类名一样
*/
int main(int argc, char *argv[])
{// 有且只有一个应用程序类的对象QApplication a(argc, argv);// MyWidget继承于QWidget,QWidget是一个窗口基类// 所以MyWidget也是窗口类// w就是一个窗口MyWidget w;// 窗口创建默认是隐藏的,需要人为显示w.show();// 让程序一直执行,等待用户操作return a.exec();
}
(基础 + 代码)部件部分
小贴士(small tips):指定父类(基类)的两种方式
// .cpp
#include
// 1. setParent关键字
QPushButton b;
b.setParent(&w);
// 2. 通过构造参数传参
QPushButton b(&w);
小贴士(small tips):定义成员变量的两种方式
#include
// 1. 普通创建(容易造成内存泄漏)// .hprivate:QPushButton b;// .cppb.setParent(this); // 指定父类
// 2. 通过指针创建// .hprivate:QPushButton *b;// .cppb2 = new QPushButton(this); // 指定父类
标准信号和槽
信号:由发出者发出的信息
槽:由接收者接收的信息
// mainwidget.h
#include
private:QPushButton b; // 定义一个成员对象
// mainwidget.cpp
#include "mainwidget.h"
#include
#include // 主页面的基类,没有Widget类功能多,但是更精MainWidget::MainWidget(QWidget *parent): QWidget(parent)
{b.setParent(this);b.setText("沙雕");b.move(100, 100);// 信号与槽举例connect(&b, &QPushButton::pressed, this, &MainWidget::close);/** &b:信号发出者* &QPushButton::pressed:处理的信号* this:信号接收者* &MainWidget::close:槽函数,信号处理函数*/MainWidget::~MainWidget() // 析构函数{}
}
自 定义槽
// .hvoid mySlot() // 声明槽函数{}
// .cpp
connect(&b2, &QPushButton::released, this, &MainWidget::mySlot);
void MainWidget::mySlot()
{b.setText("123"); // 改变b按钮的显示文本
}
自定义信号
小贴士(small tips):创建两个窗口(A,B)并把他们联系起来+自定义信号
conclusion:当父窗口切换到子窗口的时候,直接切换;当子窗口切换到父窗口的时候,因为子窗口是在父窗口之中,因此子窗口必须先发射一个信号,这个信号是由子窗口按钮发出的。
// 第一步:分别创建两个窗口和两个按钮
// A.h
#include // 给父窗口创建一个按钮用来切换页面
QPushButton b1;
// B.h
#include // 给子窗口创建一个按钮用来切换页面
QPushButton b2;// 第二步:把B作为A的子类
// A.h
#include "B.h" // 把子窗口头文件放到父窗口头文件里面
B b; // 创建一个子窗口的类// 第三步:当是父类窗口的时候,点击按钮,会切换到子类窗口
// A.h
void change_windows(); // 改变窗口的函数
// A.cpp
#include
connect(&b1, &QPushButton::release, this, &A::change_windows) // 建立一个槽函数
void B::change_windows()
{this->hide(); // 父窗口隐藏b.show(); // 子窗口显示
}// 第四步:当是子类窗口的时候,点击按钮,会切换到父类窗口
// B.h
signals:void mySiganl();
public:void sendslots();
// B.cpp
#include
connect(&b2, &QPushButton::clicked, this, &B::sendslots); // 自定义信号
void B::sendslots()
{emit mySignal() // 发出信号
}
// A.h
void dealB(); // 父类中的槽函数
// A.cpp
connect(&b, &B::mySignal, this, A::deals); // b表示的是一个窗口,而不是一个按钮
void A::deals()
{b.hide(); // 子窗口隐藏this->show(); // 父窗口显示
}
信号二义性
illusion:当出现两个信号的时候,必须在父类中指定接收哪一个信号,不同的信号是由不同的动作发出来的
小贴士(small tips):信号出现重载
// B.cpp
#include
connect(&b2, &QPushButton::clicked, this, &B::sendslots); // 自定义信号
void B::sendslots()
{emit mySignal(250, "浩浩牛啊!")
}
// A.cpp
connect(&b, &B::mySignal, this, A::deals);
void A::deals(int a, Qstring str) // 接收信号的时候也要带上参数
{b.hide(); // 子窗口隐藏this->show(); // 父窗口显示
}
信号选择性
// 第一种方法:以函数指针代替信号
void (B::*sendslots1)() == &B::mySignal; // 声明这个信号(函数)是没有参数的
connect(&b, &B::sendslots1, this, A::deals);
void (B::*sendslots2)(int QString) == &B::mySignal; // 声明这个信号(函数)是有参数的
connect(&b, &B::sendslots2, this, A::deals);
void A::deals(int a, Qstring str) // 表明调用的是有参数的信号
{b.hide(); // 子窗口隐藏this->show(); // 父窗口显示
}
// 第二种方法:Qt4信号连接(容易出问题)
// Qt4槽函数必须有slots关键字来修饰
// A.h 中所有槽函数的声明都必须加上public slots
public slots:void deal();
connect(&b, SIGNAL(mysignal()), this, SLOT(deal())); // 不带参数的信号和槽函数
connect(&b, SIGNAL(mysignal(int, QString)), this, SLOT(deal(int, QString))); // 带参数的信号和槽函数
lambda表达式之信号
// .cpp
// 变量传入只可读
#include
#include
connect(&b, &QPushButton::checked,[=]() // =以值传递传入外部所有的变量(可读),()表示函数的参数是匿名的{qDebug() << "你才是个猪头!";})
// 变量传入只可读可改
#include
#include
connect(&b, &QPushButton::checked,[=]() mutable // =以值传递传入外部所有的变量(可读可改),()表示函数的参数是匿名的{qDebug() << "你才是个猪头!";})
// 对于信号中有参数的情况
#include
#include
connect(&b, &QPushButton::checked,[=](bool isCheck) // bool isCheck指的是传入的参数{qDebug() << isCheck;})
坐标系统
{/*对于父窗口(主窗口,坐标系统相对于屏幕* 原点:相对于屏幕左上角* x:往右递增* y:往下递增*/move(100, 100);/*对于父窗口(主窗口,坐标系统相对于父窗口* 原点:相对于窗口空白左上角(不包括边框)* x:往右递增* y:往下递增*/b1 -> resize(100, 100);//设置按钮大小
}
(基础+代码)控件部分
菜单栏和工具栏
// 基类选择QMainWindow
#include "mainwindow.h"
#include // 菜单栏
#include
#include
#include
#include // 添加工具栏
#include // 按钮
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{// 菜单栏QMenuBar *mBar = menuBar(); // 构造参数构建菜单栏// 添加菜单QMenu *pFile = mBar->addMenu("文件"); // 添加小菜单// 添加菜单项,添加动作QAction *pNew = pFile->addAction("new"); // 每个小菜单里面的部件connect(pNew, &QAction::triggered,[=](){qDebug() << "新建被按下";});pFile->addSeparator(); // 添加分割线QAction *pOpen = pFile->addAction("open");// 工具栏,菜单项的快捷方式QToolBar *toolbar = addToolBar("toolbar");// 工具栏添加快捷键toolbar->addAction(pNew); // pNew表示的是菜单项对应的工具项,并且槽函数也是使用的是菜单项的槽函数QPushButton *b = new QPushButton(this);b->setText("^>^");// 添加小控件toolbar->addWidget(b); // 把工具项绑定按钮// 信号处理connect(b, QPushButton::clicked,[=](){b->setText("*——*");});}MainWindow::~MainWindow() // 析构函数
{}
状态栏
#include // 状态栏
#include // 标签
...// 状态栏,左下角的状态QStatusBar *sbar = statusBar();QLabel *lable = new QLabel(this);lable->setText("Normal text file");// 添加小空间sbar->addWidget(lable);// 第二种添加方法,默认从左往右依次添加sbar->addWidget(new QLabel("2", this));// 第三种添加方法,默认从右往左依次添加sbar->addPermanentWidget(new QLabel("2", this));
...
核心控件和浮动窗口
#include // 使用文本编辑区,
#include // 浮动窗口// 核心控件QTextEdit *Te = new QTextEdit(this); // 也可看做是一个小插件this->setCentralWidget(Te);// 浮动窗口QDockWidget *dock = new QDockWidget(this);this->addDockWidget(Qt::RightDockWidgetArea, dock); // 第一个参数是浮窗的初始位置QTextEdit *Te2 = new QTextEdit(this); // 也可看做是一个小插件dock->setWidget(Te2);
模态和非模态对话框
#include "mainwindow.h"
#include
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{QMenuBar *mbar = menuBar();setMenuBar(mbar);QMenu *menu = mbar->addMenu("对话框");QAction *p1 = menu->addAction("模态对话框");connect(p1, &QAction::triggered, [=](){QDialog dlg;dlg.exec() // 等待用户操作qDebug() << "浩浩牛啊!";});QAction *p2 = menu->addAction("非模态对话框");connect(p2, &QAction::triggered, [=](){QDialog *p = new QDialog;p->setAttribute(Qt::WA_DeleteOnClose); // 关闭的时候才释放内存p->show();});
}MainWindow::~MainWindow()
{}
标准对话框和文件对话框
#include "mainwindow.h"
#include
#include
#include
#include
#include
#include // 对话框
#include // 文件对话框
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{QMenuBar *mbar = menuBar();this->setMenuBar(mbar);QMenu *menu = mbar->addMenu("对话框");QAction *p1 = menu->addAction("模态对话框");connect(p1, &QAction::triggered, [=](){QDialog dlg;dlg.exec() // 等待用户操作qDebug() << "浩浩牛啊!";});QAction *p2 = menu->addAction("非模态对话框");connect(p2, &QAction::triggered, [=](){QDialog *p = new QDialog;p->setAttribute(Qt::WA_DeleteOnClose); // 关闭的时候才释放内存p->show();});QAction *p3 = menu->addAction("关于对话框");connect(p3, &QAction::triggered, [=](){QMessageBox::about(this, "about", "content"); // about是对话框的标题,content是内容});QAction *p4 = menu->addAction("问题对话框");connect(p4, &QAction::triggered, [=](){int ret = QMessageBox::question(this,"question", "content"QMessageBox::Yes |QMessageBox::Cancel // 指定类型); // 默认给ok和no按钮switch(ret){case QMessageBox::Yes:QDebug << "i am ok";break;case QMessageBox::No:QDebug << "i am bad";break;default:break;}} );// 文件对话框QAction *p5 = menu->addAction("文件对话框");connect(p5, &QAction::triggered, [=](){QString path = QFileDialog::getOpenFileName(this, // 指定父对象"open", // 显示操作"../", // 显示路径"source(*.cpp *.h);;Text(*txt);;all(*.*)" // 指定文件格式);QDebug() << path;});
}MainWindow::~MainWindow()
{}
(进阶+UI)控件大全
如果要找到对应的控件,只需ui->xxx即可
ui->setupUi(this);
Buttons:按钮类
特点:可以自动生成槽函数(右键,转向槽)
| 类型 | 作用 |
|---|---|
| Push Button | 按钮 |
| Tool Button | 按钮 |
| Radio Button | 单选按钮 |
| Check Box | 多选按钮 |
| Command Link Button | 控制链接按钮 |
| Dialog Button Box | ok、cancel |
Containers:容器类
| 类型 | 作用 |
|---|---|
| Group Box | 放大部件容器 |
| Scroll Area | 可滑动 |
| Tool Box | 抽屉式容器 |
| Tab Widgets | 标签式容器 |
| Stacked Widget | 栈容器(可切换页面容器) |
| Frame | 带边框的,布局容器 |
| Widget | 不带边框的,布局容器 |
| MDI Area | 文档分栏显示 |
| Dock Widget | 浮动窗口 |
| QAxWidget | 、、、 |
Input Widgets:输入类
| 类型 | 作用 |
|---|---|
| Combo Box | 下拉自定义选择框 |
| Font Combo Box | 字体选怎框 |
| Line Edit(获取内容—text()) | 行编辑 |
| Text Edit | 文本编辑 |
| Plain Text Edit | 空白文本编辑 |
| Spin Box | 滑动调整数值(整数) |
| Double Spin Box | 滑动调整数值(小数) |
| Time Edit | 时间编辑器 |
| Date Edit | 日期编辑器 |
| Date/Time Edit | 时间/日期编辑器 |
| Dial | 控制器 |
| Horizontal Scroll Bar | 横向滚动条 |
| Vertical Scroll Bar | 纵向滚动条 |
| Horizontal Slider | 横向滑块 |
| Vertical Slider | 纵向滑块 |
| Key Sequence Edit | 设置快捷方式 |
小贴士(small tips):对于Line Edit(行编辑)
// 获取编辑框内容
Qstring text();
// 设置编辑框内容
setText();
// 设置显示间隙
setTextMargins(x, y, z, s) // 四个参数分别为距离左上右下的间距
// 设置显示模式
#include
setEchoMode(QLineEdit::Normal) 正常显示
setEchoMode(QLineEdit::NoEcho) 不显示任何内容
setEchoMode(QLineEdit::Password) 密码模式
setEchoMode(QLineEdit::PasswordEchoOnEdit) 编辑时显示字符否则为密码模式
Display Widgets:显示类
| 类型 | 作用 | 类型 | 作用 |
|---|---|---|---|
| Label | 设置标签 | Horizontal Line | 横线 |
| Text Browser | 文本显示器 | Vertical Line | 垂直线 |
| Graphics View | 绘图工具 | OpenGL Widget | 此部分不做讲解 |
| Calendar Widget | 日历 | QDeclarative View | 此部分不做讲解 |
| LCD Number | 数码管 | QQuickWidget | 此部分不做讲解 |
| Progress Bar | 进度条 | QWebView | 此部分不做讲解 |
小贴士(small tips):对于Label类
#include
// 设置文本内容
ui->labelText->setText("xxxx");#include
// 设置图片
ui->labelImage->setPixmap(QPixmap("workspace"));
// 让图片自动适应label大小
ui->labelImage->setScaledContents(true);// 创建动画
#include
QMovie *myMovie = new QMovie("路径");
// 设置动画
ui->labelImage->setMovie(myMovie);
// 启动动画
myMovie->start();
ui->labelImage->setScaledContents(true);// 设置html
ui->labelUrl->setText("xxx
");
ui->labelUrl->setOpenExternalLinks(true);
小贴士(small tips):对于Progress Bar类
ui->progressBar->setMinimum(0); // 设置最小值
ui->progressBar->setMaximum(0); // 设置最大值
ui->progressBar->setValue(0); // 设置当前值
Spacer:弹簧类
| 类型 | 作用 |
|---|---|
| Horizontal Spacer | 横向弹簧 |
| Vertical Spacer | 纵向弹簧 |
Layouts:布局类
| 类型 | 作用 |
|---|---|
| Vertical Layouts | 纵向布局 |
| Horizontal Layouts | 横向布局 |
| Grid Layouts | 网格布局 |
| Form Layouts | 表格布局 |
自定义控件
把两个cpp文件相连接:【提升为】
Qt样式表
selector { attribute: value; },一般selectior为setStyleSheet()
/* such as
* 1. QLabel{ color: red} 第一种使用基本的颜色单词 默认设置的是字体的颜色
* 2. QLabel{ color: sgb(0, 255, 255)} 第二种使用RGB颜色配色
* 3. background-color:sgb(0, 0, 255) 背景色
* 4. background-image:url() 图片
*/
方箱重合
创建可伸缩样式
// 以按钮为例,对于按钮内的图片边框地带距离border距离要有4个像素点
QPushButton
{border-width:4px;border-image:url()
}
伪状态
QPushButton::press
{border-image:url()
}
伪状态列表
| 伪状态 | 描述 | 伪状态 | 描述 |
|---|---|---|---|
| ::checked | button部件被选中 | ::indeterminate | checkbox或radiobutton被部分选中 |
| ::disabled | 部件被禁用 | ::off | 部件可以切换,且处于off状态 |
| ::enabled | 部件被启用 | ::on | 部件可以切换,且处于on状态 |
| ::focus | 部件获得焦点 | ::pressed | 部件被鼠标按下 |
| ::hover | 鼠标位于部件上 | ::unchecked | button部件未被选中 |
注明:写出来作用不大,主要是要自己会使用
事件
具体可见上一篇博客:
键盘和鼠标事件监听
QT中所有的事件类都继承于QEvent.
#include
void mousePressEvent(QMouseEvent *ev) {}; // 鼠标按下
void mouseReleaseEvent(QMouseEvent *ev) {}; // 鼠标抬起
void mouseMoveEvent(QMouseEvent *ev) {}; // 鼠标移动
void enterEvent(QEvent *e); // 进入窗口区域
void leaveEvent(QEvent *e); // 离开窗口区域
void keyPressEvent(QKeyEvent *e) // 键盘按下事件
ev->button() == ???
事件的接收和忽略
ignore(); // 忽略事件,传递给父组件,不是父类
accept(); //接收事件
event()函数
控制各个函数的进程
#include
// 第一步:在主类头文件里面建立成员函数bool event(xxx)
// 第二步:定义函数来进行事件分发
// 第三步:代码
switch(e->type())
{case QEvent::Close:closeEvent(); // closeEvent此函数要自定义.... // 如果传入的事件已被识别并且处理,则需要返回true,否则返回false,如果直接return true则可以跳过这个事件
}
事件过滤器:bool eventFitler
// 给控件安装过滤器
ui->label->installEventFilter(this); // this 表示是父对象
ui->label->setMouseTrack(); // 鼠标追踪
if(obj == label)
{// 判断事件if(e->type() == QEvent:: MouseMove){ui->label->setTEext("sadf");return true; // 不要让事件传播}
}
(进阶+代码)其他工具
绘图
文件操作
网络通信
TCP
UDP
线程
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
