目录

  • 入门基础
    • 模态对话框
    • 消息提示框(messagebox)
    • 文件和目录
    • 字体选择框
    • 输入对话框
    • 进度条
    • 工具栏
    • 控件布局
    • Windows托盘案例
  • 控件
    • button
      • 下拉菜单按钮
      • `radioButton`单选按钮
      • `checkBox`:复选框,
    • 列表控件ToolBox和TableWidget
  • 属性
    • 利用属性辨别信号的发出者

入门基础

模态对话框

MyDialog1::~MyDialog1() { delete ui; }//三者都是解除阻塞
void MyDialog1::on_acceptButton_clicked() {this->accept(); //发出accepted信号返回Accepted
}
//done信号可以传递数据,同时也会返回
void MyDialog1::on_doneButton_clicked() {this->done(10); //发出finished并传递参数10,关闭模态框并且返回10
}void MyDialog1::on_rejectButton_clicked() //与accept一样
{this->reject(); //发出rejected信号返回Rejected
}MyDialog1 dlg;//done信号向槽函数传递数据connect(&dlg, &MyDialog1::finished, this,[=](int res) { qDebug() << "res:" << res; });connect(&dlg, &MyDialog1::accepted, this,[=]() { qDebug() << "accept 信号发射"; });connect(&dlg, &MyDialog1::rejected, this,[=]() { qDebug() << "reject 信号发射"; });int ret = dlg.exec();switch (ret) {case QDialog::Accepted:qDebug() << "accept button clicked";break;case QDialog::Rejected:qDebug() << "reject button clicked";break;default:qDebug() << "done button clicked";break;}

消息提示框(messagebox)

//信息提示框QMessageBox::about(this, "help", "我的messagebox");//错误提示框QMessageBox::critical(this, "critial", "error");//确认提示框auto ret =QMessageBox::question(this, "question", "是否保存当前文件",QMessageBox::Save | QMessageBox::Cancel, //按钮QMessageBox::Cancel); //默认按钮if (ret == QMessageBox::Save) {QMessageBox::information(this, "info", "save success");} else if (ret == QMessageBox::Cancel) {QMessageBox::warning(this, "warning", "cancel");}

文件和目录

  //只会显示目录                               父控件 标题          默认目录auto path = QFileDialog::getExistingDirectory(this, "打开一个目录", "..\\");qDebug() << path;auto path = QFileDialog::getOpenFileName(this, "打开一个文件", "..\\","Images(*.png *.xpm *.jpg);;Text files(*.txt);;XML files (*.xml);;Video ""files(*.mp4)");auto path = QFileDialog::getOpenFileNames(this, "打开一批文件", ".\\", "*.*");//返回文件列表QMessageBox info(QMessageBox::Information, "文件路径", path[0],QMessageBox::Yes | QMessageBox::No);for (const auto &i : path) {qDebug() << i;}info.exec();//不会创建文件,二十返回保存文件的绝对路径auto path =QFileDialog::getSaveFileName(this, "保存文件", "..\\", "txt(*.txt)");QMessageBox::information(this, "保存文件", path);
}

字体选择框

bool ok;//点了确认返回true,否则返回falseQFont font = QFontDialog::getFont(&ok, QFont("微软雅黑", 12, QFont::Bold),this, "选择字体");qDebug() << ok;//不默认指定任何参数,通过字体对话框选择一个字体对象auto font = QFontDialog::getFont(NULL);ui->fontLable->setFont(font);//静态方法,设当前GUI所有的字体QApplication::setFont(font);

输入对话框

void MainWindow::on_inputDialogButton_clicked() {#ifdef textauto in = QInputDialog::getText(this, "Text", "NO");
#endif
#ifdef INTauto in = QInputDialog::getInt(this, "输入一个int", "年龄", 1, 1, 100, 2);
#endif
#ifdef ItemQStringList list;list << "香蕉"<< "苹果"<< "香蕉"<< "哈密瓜"<< "桔子";auto in = QInputDialog::getItem(this, "选择一个水果", "选择", list, 1, false);#endifqDebug() << in;
}

进度条

void MainWindow::on_progressButton_clicked() {auto *p = new QProgressDialog("正在拷贝", "取消拷贝", 0, 100,this); //不指定父对象就需要自己析构p->setWindowModality(Qt::WindowModal);p->setWindowTitle("稍后");p->show();auto time = new QTimer(); //不指定父对象就需要自己析构time->start(50);          // 50ms更新一次size_t *value = new size_t();*value = 0;connect(time, &QTimer::timeout, this, [value, p, time]() {p->setValue(*value);(*value)++;if (*value > p->maximum()) {time->stop();*value = 0;delete p;delete time;}});

工具栏

工具栏主要是在ui文件中添加(菜单栏一样),通过以下方式添加工具栏中的控件

  ui->toolBar->addWidget(new QPushButton("搜索"));//不建议使用匿名对象ui->toolBar->addWidget(new QLineEdit());

通过代码添加工具栏

 auto toolbar = new QToolBar(this);toolbar->setMovable(false);toolbar->setFloatable(false);toolbar->setFixedWidth(50);toolbar->setAllowedAreas(Qt::RightToolBarArea);this->addToolBar(Qt::RightToolBarArea, toolbar);

控件布局


基本的控件布局就这些。布局一般是在Widget内,控件添加入Widget然后Widget自动按照布局排列,Widget里面可以套Widget
弹簧是布局中的重要工具,通过弹簧可以设置控件之间的相对距离。比如说,如果需要Widget中的label居中显示,可以在label的两侧各放一根弹簧,有水平弹簧和垂直弹簧

弹簧控件

使用示例

代码进行布局


Windows托盘案例

  • #include <QSystemTrayIcon>
  • 新建并且设置托盘图标
  QIcon icon = QIcon("D:\\MyProject\\C++\\transFile\\transfile.ico");this->trayIcon = new QSystemTrayIcon(this);this->trayIcon->setIcon(icon);this->trayIcon->setToolTip("a tray example");this->trayIcon->show();
  • 设置Action
  this->normal = new QAction("还原", this);connect(this->normal, &QAction::triggered, this, &myForm::showNormal);//正常展示窗口this->quit = new QAction("退出", this);connect(this->quit, &QAction::triggered, qApp, &QApplication::quit);  //qAPP是全局的,表示当前程序
  • 将Action放入托盘图标右键menu中并且设置右键点击
  this->trayMenu = new QMenu(this);this->trayMenu->addAction(this->normal);this->trayMenu->addAction(this->quit);this->trayIcon->setContextMenu(this->trayMenu);
  • 重写右上角的关闭和隐藏按钮事件
//重写右上角按钮事件,需要在.h声名文件中声名
//设置右上角关闭按钮为最小化
void myForm::closeEvent(QCloseEvent *event) {if (trayIcon->isVisible()) {hide();trayIcon->showMessage("title", "Close");//忽略这个事件,则不会关闭event->ignore();}
}
void myForm::hideEvent(QHideEvent *event) {if (trayIcon->isVisible()) {hide();trayIcon->showMessage("title", "hide");event->ignore();}
}
  • 托盘图标的点击事件
connect(this->trayIcon, &QSystemTrayIcon::activated, this,&myForm::iconIsActived);//利用activated信号//对应的槽函数                             //一个枚举值
void myForm::iconIsActived(QSystemTrayIcon::ActivationReason reason) {switch (reason) {case QSystemTrayIcon::DoubleClick://双击图标窗口换源this->showNormal();break;case QSystemTrayIcon::Trigger:       //单击展示托盘菜单this->trayMenu->move(QCursor().pos());this->trayMenu->show();break;default:break;}
}

控件

button

都是基于QAbstractbutton,公共的信号有clicked,toggled,pressed,released,使用起来较为简单,常用的就是clicked
设置一个开关按钮,通过这种方式可以使一个pushbutton变为一个开关按钮

  ui->toggleButton->setCheckable(true);connect(ui->toggleButton, &QPushButton::toggled, this, [=](bool bl) {qDebug() << "check按钮当前状态为" << bl;auto status = bl ? "开" : "关";ui->toggleButton->setText(status);});

                       


下拉菜单按钮

  ui->menuButton->setText("选择你最喜欢的水果");auto menu = new QMenu();auto act1 = new QAction("西瓜");menu->addAction(act1);menu->addAction("菠萝");menu->addAction("香蕉");menu->addAction("苹果");menu->addAction("葡萄");menu->addAction("脐橙");ui->menuButton->setMenu(menu);connect(act1, &QAction::triggered, this,[act1]() { qDebug() << act1->text(); });


上面的应用都可一用在QToolButton


radioButton单选按钮


同一组按钮只能选中一个,通常使用Group Box分组因为自带了标题,记得要设置布局


checkBox:复选框,

布局与上述一样,有三个状态选中 未选中 半选中,默认是选中和未选中两种状态,需要setTristate为True才有半选中状态。
常用信号stateChanged参数反应的就是CheckBox的状态

void MainWindow::on_checkBox_stateChanged(int arg1) {QString str{};str = (arg1 == Qt::Checked) ? "你讨厌加班" : "可以接受加班";qDebug() << str;
}

树形结构复选框

内层是Widget,外层是Group Box都是垂直布局
逻辑设计思路

  1. 引入计数机制,记录子节点被中的个数
  2. 当子节点全部被选中,则父节点设置为Checked,部分被选中设置为PartiallyChecked,选中数为0则为Unchecked
  3. 对父节点的点击事件进行相应,若选中父节点,则子节点全部选中
    代码实现:
 //初始化ui->WenKe->setTristate(true);connect(ui->ZhengZhi, &QCheckBox::stateChanged, this,&MainWindow::CheboxSlot);connect(ui->LiShi, &QCheckBox::stateChanged, this, &MainWindow::CheboxSlot);//clicked信号属于父类,参数为选中状态,bool类型connect(ui->WenKe, &QCheckBox::clicked, this, [this](bool bl) {if (bl) { //被选中ui->ZhengZhi->setCheckState(Qt::Checked);ui->LiShi->setCheckState(Qt::Checked);} else {ui->ZhengZhi->setCheckState(Qt::Unchecked);ui->LiShi->setCheckState(Qt::Unchecked);}});

子节点绑定的槽函数,所有子节点绑定同一个槽函数,槽函数只对计数进行操作

void MainWindow::CheboxSlot(int state) {if (state == Qt::Checked) {++(this->cheboxTrueNumWenKe);//int类型,初始化为0} else {--(this->cheboxTrueNumWenKe);}switch (this->cheboxTrueNumWenKe) {case 0:ui->WenKe->setCheckState(Qt::Unchecked);break;case 1:ui->WenKe->setCheckState(Qt::PartiallyChecked);break;default://全部选中ui->WenKe->setCheckState(Qt::Checked);break;}
}

对于重载信号,应该使用这种写法绑定,表示形参为int类型的重载

列表控件ToolBox和TableWidget


同时选中二者使用拆分器水平布局可以将二者绑定在一起

属性

QObject类:QT所有类的基类

class MyPerson:public QObject{Q_OBJECT                               //必须的Q_CLASSINFO("author", "lhh")           Q_CLASSINFO("date", "2022-05-08")Q_PROPERTY(unsigned age READ age WRITE setAge NOTIFY ageChanged)Q_PROPERTY(QString name MEMBER m_name)Q_PROPERTY(QString sex MEMBER m_sex)Q_PROPERTY(unsigned score MEMBER m_score)// Q_PROPERTY(unsigned age MEMBER m_age)// //将成员变量m_age导出为属性值age,使得其可通过属性操作成员变量
private:unsigned int m_age;unsigned int m_score;QString m_name;QString m_sex;
public:unsigned int age(){return m_age;}void setAge(unsigned int value){m_age=value;ageChanged();}signals:void ageChanged();
}

上述类中使用了两个宏Q_PROPERTYQ_CLASSINFO
Q_CLASSINFO主要存放类的信息,可以不用

Q_PROPERTY定义

Q_PROPERTY(type nameREAD getFunction[WRITE setFunction][RESET resetFunction][NOTIFY notifySignal][DESIGNABLE bool][SCRIPTABLE bool][STORED bool][USER bool][CONSTANT][FINAL])

上述MyPerson类中的Q_PROPERTY第一种用法就是定义一个属性age,设置读取属性的函数为age()
,写属性的函数为setAge(),信号为ageChanged(),其中读写函数必须实现,可以再相应的;
第二种用法就是使用MEMBER关键字将成员变量注册为属性,使用setproperty修改属性就可以操作成员变量

  boy = new QPerson;boy->setProperty("score", 80);boy->setProperty("age", 18);

由于age属性和m_age绑定,所以此处m_age=18;
获取属性:

QMetaProperty*b=boy.metaObject();
QString m_name= boy->property("name").toString();

利用属性辨别信号的发出者

同属于一个类的多个对象,可以同时向一个一个对象发出信号,那接收者如何分别发送信号的是哪一个类呢?

 this->boy = new QPerson();this->girl = new QPerson();//设置一个属性判断性别ui->boyAgeSpinBox->setProperty("isBoy", true);ui->girlAgeSpinBox->setProperty("isBoy", false);//二者同时绑定同一个槽函数connect(this->girl, &QPerson::ageChanged, this, &on_spinBoxValue_Changed);connect(this->boy, &QPerson::ageChanged, this, &on_spinBoxValue_Changed);//槽函数,接收ageChanged信号
void MainWindow::on_spinBoxValue_Changed(int value) {QPerson*spinBox = qobject_cast<QPerson*>(sender());if (spinBox->property("isBoy").toBool()) {qDebug()<<"男孩";} else {qDebug()<<"女孩";}
}

C++编程笔记(QT)相关推荐

  1. java qt gui_工控编程,Qt 学习之路

    原标题:工控编程,Qt 学习之路 Qt 是一个著名的 C++ 库--或许并不能说这只是一个 GUI 库,因为 Qt 十分庞大,并不仅仅是 GUI.使用 Qt,在一定程序上你获得的是一个"一站 ...

  2. 响应式编程笔记(二):代码编写

    2019独角兽企业重金招聘Python工程师标准>>> 响应式编程笔记(二):代码编写 博客分类: 架构 原文:Notes on Reactive Programming Part ...

  3. NDK 高级编程(笔记)

    Android 开发中针对 NDK 的书籍很少,<Pro Android C++ with the NDK>也是出版的比较早的一本书,有些内容可能对现在的开发并不适用.但是书中介绍的内容比 ...

  4. Java网络编程笔记5

    在Java网络编程笔记4中我们看到了客户端与服务器通信的过程,只是在前面的程序只是单个客户端与服务器通信 的例子. 接下来我们看如何实现多个客户端与服务器通信,对于服务器来说,它要为每个客户端请求的S ...

  5. MSSQL编程笔记四 解决count distinct多个字段的方法

    MSSQL编程笔记四 解决count distinct多个字段的方法 参考文章: (1)MSSQL编程笔记四 解决count distinct多个字段的方法 (2)https://www.cnblog ...

  6. Java TCP/IP Socket 编程 笔记

    http://jimmee.iteye.com/blog/617110 http://jimmee.iteye.com/category/93740 Java TCP/IP Socket 编程 笔记( ...

  7. java并发编程笔记_java并发编程笔记(一)——并发编程简介

    java并发编程笔记(一)--简介 线程不安全的类示例 public class CountExample1 { // 请求总数 public static int clientTotal = 500 ...

  8. C# Socket编程笔记(转)

    C# Socket编程笔记 http://www.cnblogs.com/stg609/archive/2008/11/15/1333889.html TCP Socket: Server 端连接步骤 ...

  9. Java编程笔记7:内部类

    Java编程笔记7:内部类 图源:PHP中文网 所谓的内部类,其实就是定义在类中的类.这和Java编程笔记6:接口 - 魔芋红茶's blog (icexmoon.xyz)中提到的接口嵌套的方式有点相 ...

  10. Java编程笔记16:深入容器

    Java编程笔记16:深入容器 图源:PHP中文网 填充容器 填充容器会有Java编程笔记15:数组 - 魔芋红茶's blog (icexmoon.cn)种提到的填充数组同样的问题. 和数组类似,标 ...

最新文章

  1. python使用sklearn的ConfusionMatrixDisplay来可视化混淆矩阵
  2. python对字典的基本操作(遍历、排序)总结,Python字典操作简明总结
  3. Google+强推实名制引爆不满 用户增速放缓
  4. Activiti流程定义部署、删除
  5. 人脸图像特征提取方法(HOG、Dlib、CNN)简述
  6. Solidity 系列教程
  7. windows安全中心接口
  8. java实现逆波兰表达式求值
  9. matlab画倾斜的椭球_用matlab绘制椭球体x^2/4+y^2/9+z^2/16=1,并通过改变观察点获得它在各个坐标面上的投影。...
  10. 校园商铺项目 SSM迭代Spring Boot项目实战视频
  11. adb install 时 日志输出Performing Streamed Instal 一直卡着不动,处理方法
  12. 筛选两张表中id不同的数据
  13. 元旦技术大礼包 - 2017金秋将要发布的PostgreSQL 10.0已装备了哪些核武器?
  14. TSN(temporal segment networks)环境配置
  15. 学习笔记:有源晶振与无源晶振(一)
  16. 动手深度学习笔记(四十五)8.1. 序列模型
  17. 合工大计算机学硕和专硕报录比,2019合肥工业大学计算机考研初试科目、参考书目、报录比汇总...
  18. 从源码一步步学习,Ryan Dahl的Deno实现原理
  19. 7-7 修理牧场 (25分)嗯嗯
  20. c语言数星星结构体,数星星(结构体专题)

热门文章

  1. SMART200 DP01模块通讯问题
  2. Unity 粒子特效
  3. java案例4-5图形的面积与周长计算程序
  4. JavaScript封装对象和类
  5. 如何设置Idea字体颜色
  6. 机器学习与深度学习常见面试题
  7. PFC2D学习笔记——geometry的使用
  8. window10计算机策略,如何打开组策略,教您win10如何打开组策略
  9. Matlab Coder将m文件转换成C/C++
  10. 【计算理论】计算理论总结 ( 上下文无关文法 | 乔姆斯基范式 | 乔姆斯基范式转化步骤 | 示例 ) ★★