赞
踩
1、windows安装
msvc编译器模块需要安装Windows软件开发工具包。
MinGW是Windows平台使用GNU工具导入库的集合。
2、Linux环境安装
双击.run文件即可
安装常用的开发依赖
apt-get install g++
apt-get install make
apt-get install libgl1-mesa-dev #gui运行依赖库
3、visual studio中创建Qt项目以及配置
1、工具安装
a、工具->扩展和更新->联机右上角搜索qt,下载安装Qt Visual Studio Tools
b、下载离线安装
配置Qt编译器版本:
1、点击Qt VS Tools选项 -> Qt Versions, 再弹出的框中添加对应的编译器版本
比如:D:\Qt\Qt5.12.12\5.12.12\msvc2017_64\bin
visual studio中开发qt程序打开控制台:
右键项目 -> 属性 -> 链接器 -> 系统 -> 子系统 修改为控制台 然后保存
QT += core gui #项目依赖模块 # qt版本大于4才加入widgets模块 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets # app表示项目是exe应,lib表示是库 TEMPLATE = app # 生成的可执行文件名称 TAEGET = “ceshi_demo” # 使用C++11标准 CONFIG += c++11 # 设置头文件搜索路径 INCLUDEPATH += ../include # $$PWD是pro的目录 INCLUDEPATH += $$PWD/../include message("pwd = "$$PWD) # 项目包含的源码 SOURCES += \ dialog.cpp \ main.cpp \ widget.cpp # 项目包含的头文件 HEADERS += \ dialog.h \ widget.h # 项目包含的窗体文件 FORMS += \ dialog.ui \ widget.ui # 指定库引用路径和名称 -L库路径 -l库名 LIBS += -L"./lib" -ltest #修改可执行文件/目标文件输出路径 DESTDIR += ../build qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target # 项目资源文件 RESOURCES += \ res.qrc #debug和release环境判断 CONFIG(debug,debug|release){ TARGET = "ceshi_demo_debug" } else { TARGET = "ceshi_demo_relsease" } #跨平台编译配置 win32 linux macx unix win32{ message("win32") } !win32{ message("!win") } win32|linux{ message("win32|linux") } # 查看编译器信息 message($$QMAKESPEC) # 查看编译器包括那些 D:\Qt\Qt5.12.12\5.12.12\mingw73_32\mkspecs # dll输出路径 DLLDESTDIR += "../bin" # 设置可执行程序图标 demo.ico存放在pro相同目录 RC_ICONS = demo.ico # OBJECTS_DIR 表示程序生成的中间临时文件的存放路径 # MOC_DIR moc命令生成的临时文件路径 # RCC_DIR 用来描述qt资源编译器输出文件路径
在中大型项目中用pri文件配置各个子项目的公共变量、公共编译选项、公共路径
# 用来在pro/pri中引入某pri文件 include空格()
include (../my.pri)
# 环境变量 $${环境变量}
#自定义变量
CUSTOM_PATH = "../../home"
1、编译pro生成makefile
2、jom或者make编译makefile
# 生成界面的源码
D:\Qt\Qt5.12.12\5.12.12\mingw73_32\bin\uic.exe widget.ui -o ui_widget.h
# 生成信号槽代码
D:\Qt\Qt5.12.12\5.12.12\mingw73_32\bin\moc.exe widget.h moc_widget.cpp
qmake -o makefile demo.pro
jom /f makefile.Debug #windows
make # linux/mac
QObject类是所有元对象系统的类的基类
在一个类的private部分声明Q_OBJECT宏,使得类可以使用元对象的特性如动态属性、信号与槽
Q_PROPERTY()宏可以定义属性
QObject ob;
// 设置动态属性
ob.setProperty("name", "zhansan");
// 获取属性值
ob.property("name")
顺序容器类:QList、QLinkedList、QVector、QStack、QQueue
QList数组列表
QLinkedList链式列表
QVector动态数组的功能,支持迭代器和下标访问
QStack类似堆栈先进后出
QQueue类似队列的先入先出
关联容器类:QMap、QMultiMap、QHash、QMultiHash、QSet
QMultiMap、QMultiHash支持一个键关联多个值
QSet是基于散列表的集合模板类,存储无顺序、查找速度快,内部用QHash实现
QMap存储基于键值对,存储按照key的顺序,不在乎顺序用QHash更快
QHash基于散列表来实现字典功能的模板类
类似windows的消息机制,信号函数只发送,不需要知道接受者,需要QObject来绑定。
原理:
1、绑定信号函数和槽函数
2、调用信号函数(将信号写入队列)
3、主线程从队列中获取信号,在信号线程中找到信号和槽关联的队列处理,调用槽函数
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
1、一个信号可以连接多个槽
2、多个信号可以连接同一个槽
3、一个信号可以连接另外一个信号
4、信号与槽的参数个数需要一致,信号的参数不能少于槽的参数
5、信号与槽的类中需要加入Q_OBJECT
6、当信号发射时,与其关联的槽函数立即执行,当关联的槽函数执行完毕之后才能执行发射信号处后的代码
手动添加信号槽:
1、Q_OBJECT
2、手动创建信号signals
3、手动创建槽 public slots
1、所用用户界面对象的基类
2、窗口部件接收鼠标、键盘等事件
3、屏幕上绘制自己
4、父子关系有相对坐标
手动创建QWidget对象 QWidget w; w.show(); //显示包含子窗口 w.hide(); // 隐藏包含子窗口 w.geometry(); // 获取窗口坐标大小 // 获取x.y.width.height int x = w.x(); int y = w.y(); int width = w.width(); int height = w.height(); // 重新设置窗口大小、移动窗口位置 w.resize(300, 400); w.move(0, 0); // 设置窗口状态 WindowMinimized WindowFullScreen setWindowState(Qt::WindowMaximized); // 同setWindowState效果 showNormal(); showMinimized(); showMaximized(); showFullScreen(); // 去除界面边框和标题栏,无法缩放移动 //setWindowFlags(Qt::FramelessWindowHint); // 标题栏保留,去除所有按钮 setWindowFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint);
QString中字符串是Unicode码,每一个字符是一个16位的QChar。所以处理中文没有问题。
// 1.字符串判空 QString str; // QString str = nullptr; str == "" str.isNull() str.isEmpty() // 2.字符串拼接 =+ 、append() str += " end"; // 3.格式化输出 QString str2 = QString("print %1 %2").arg("number = ").arg(45); QString str3 = QString("格式化输出 %1, %2").arg(16, 0, 2).arg(255, 0, 16); QString str; str.sprintf("age is %d", 34); // 4.数字转QString QString num = QString::number(35); // 5.字符串遍历 QString itstr = QString("hello, blob asfdfdasm fafasdfad"); // 方法一 for (QString::iterator itr = itstr.begin(); itr != itstr.end(); itr++) { qDebug() << *itr; } // 方法二 for (int i = 0; i<itstr.size(); i++) { qDebug() << itstr[i]; } // 6.字符串查找 // 从左往右 int location = itstr.indexOf("blob"); // 从后往前 int lastlocation = itstr.lastIndexOf("fa"); // 7.字符串截断 // 截断后面几个字符 itstr.chop(4); // 从左边截断n个字符 QString left = itstr.left(5); QString right = itstr.right(5); // 8.字符串替换 itstr.replace("hello", "hahah"); // 9.去掉字符串空格 QString str = QString(" were ewre ewr "); // 去掉字符串首位空格 qDebug() << str.trimmed(); // 去掉字符串首位空格,中间有连续空格也用一个空格替换 qDebug() << str.simplified(); // 10 字符串包含 str.contains("we"); // 字符串以什么结尾 str.endsWith("we"); // 字符串以什么开头 str.startsWith("ss");
Qt中文乱码问题:
1、默认字符集设置(默认UTF-8)
2、文件字符集格式vs qtcreator中设置,vs中默认是gbk的编码
3、字符集转换QStringLiteral
// qt creator中输出中文 QString str = "中文测试"; qDebug() << str; // vscode中开发qt,输出中文 QString str1 = QStringLiteral("中文测试"); qDebug() << str1; // vscode中开发qt,输出中文 // 1.头文件中设置编码方式 #pragma execution_character_set("UTF-8") QString str = "中文测试"; qDebug() << str; // 2.文件编码为GBK const char* src = "元数据是中文GBK,多字节数据存入QString"; QString str1 = QString::fromLocal8Bit(src); qDebug() << str1; // 把QString转为gbk std::cout << str1.toLocal8Bit().toStdString() << std::endl; QString s = QStringLiteral("测试"); // win api调用QString作为参数 MessageBox(0, s.toStdWString().c_str(), L"标题", 0);
显示文字、换行、样式设置字体、颜色、背景色、显示图片、播放gif动画
换行直接输入\n
label = new QLabel(Widget);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(190, 320, 251, 101));
// 设置样式表
label->setStyleSheet(QString::fromUtf8("font: 14pt \"Algerian\";color: rgb(119, 51, 255);"));
// 播放gif
QMovie *mov = new QMovie("test.gif");
label->setMovie(mov);
事件设置、快捷键、样式设置
click()/click(bool)/pressed()/released()
// 设置按钮快捷键
ui->pushButton->setShortcut(tr("Ctrl+x"));
// 设置样式
pushButton->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 255, 0);color: rgb(42, 74, 255);border-radius:10px"));
// hover样式设置
pushButton->setStyleSheet(QString::fromUtf8("QPushButton::hover{background-color: rgb(0, 0, 0);}\n"
"QPushButton::!hover{background-color: rgb(255, 255, 0);color: rgb(42, 74, 255);border-radius:10px;}"));
QLineEdit *edit = new QLineEdit(this); edit->setObjectName("edit"); // 占位文字 edit->setPlaceholderText(QString("中文测试2")); edit->move(100, 30); edit->resize(100, 80); // 清除按钮 edit->setClearButtonEnabled(true); edit->setMaxLength(10); // 设置显示密码的显示模式 edit->setEchoMode(QLineEdit::Password); edit->setStyleSheet(QString("color: rgb(170, 0, 0);border-raduis: 20px;")); // 输入验证 //edit->setInputMask("00.00;_"); // 只读 //eiit->setReadOnly(true); // 校验器 QDoubleValidator *validator = new QDoubleValidator(); validator->setRange(-100, 1000, 3); edit->setValidator(validator); // returnPressed 有效触发信号 connect(edit, SIGNAL(returnPressed()), this, SLOT(returnPressedTest())); // 另外一个按钮事件里面获取相关数据 void Widget::on_pushButton_clicked() { QLineEdit *eiit = findChild<QLineEdit*>("edit"); // 获取内容 qDebug() << eiit->text(); }
QObjectList list = this->children();
for (int i = 0; i < list.size(); i++) {
QObject* obj = list[i];
const QMetaObject* metaObject = obj->metaObject();
// 获取子元素类名
QString className = metaObject->className();
// 获取子元素objectName
qDebug() << obj->objectName();
qDebug() << className;
// 转化
if(className == "QPushButton") {
QPushButton *btn = qobject_cast<QPushButton*>(obj);
qDebug() << "找到了QPushButton text = " << btn->text();
}
}
//sizeHint推荐尺寸只能重载修改 //size() 不包含边框的窗口大小 //QSizePolicy::PolicyFlag //GrowFlag 必要时可超过推荐 //ExpandFlag 尽可能的拓展 //ShrinkFlag 必要时可小于推荐 //IgnoreFlag 缺省大小被忽略 //QVBoxLayout // 垂直布局 QVBoxLayout *layout = new QVBoxLayout(this); // 设置距离边框的边距 layout->setContentsMargins(10,20,30,40); // 设置元素之间的间距 layout->setSpacing(30); QPushButton *btn = new QPushButton("btn1"); // 设置按钮size的策略 推荐的大小 btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); layout->addWidget(btn); QPushButton *btn2 = new QPushButton("btn2"); btn2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layout->addWidget(btn2); QPushButton *btn3 = new QPushButton("btn3"); // 忽略 大小尽量缩放 btn3->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // 设置最大和最小值 btn3->setMaximumSize(300, 300); btn3->setMinimumSize(50,50); layout->addWidget(btn3); // QGridLayout QGridLayout *layout = new QGridLayout(this); // 设置间距 layout->setVerticalSpacing(20); layout->setHorizontalSpacing(10); QPushButton *btn1 = new QPushButton("btn1"); layout->addWidget(btn1, 0, 0); QPushButton *btn2 = new QPushButton("btn2"); layout->addWidget(btn2, 0, 1); QPushButton *btn3 = new QPushButton("btn3"); layout->addWidget(btn3, 1, 0); QPushButton *btn4 = new QPushButton("btn4"); layout->addWidget(btn4, 1, 1); // QFormLayout QFormLayout *layout = new QFormLayout(this); layout->setVerticalSpacing(20); layout->setHorizontalSpacing(10); QLineEdit *account = new QLineEdit(); layout->addRow(QString("账号"), account); QLineEdit *password = new QLineEdit(); layout->addRow(QString("密码"), password); QHBoxLayout *hLayout = new QHBoxLayout(); layout->addRow(hLayout); QPushButton *login = new QPushButton(QString("登录")); hLayout->addWidget(login); connect(login, SIGNAL(clicked()), this, SLOT(test())); void Widget::test() { qDebug() << "test"; QFormLayout *lay = qobject_cast<QFormLayout*>(this->layout()); qDebug() << lay; }
// 1
qDebug() << "state = " << state;
// 2
qDebug("message = %s", info);
// 3 自定义类输出到qDebug
// 4 将标准输出重定向为到文件qInstallMessageHandler()
QString res = ui->checkBox->text(); qDebug() << res; ui->checkBox1->setText("text"); // 快捷键 ui->checkBox->setShortcut(tr("x")); // 选中状态 ui->checkBox->isChecked(); // 同一父组件中的box单选 ui->checkBox->setAutoExclusive(true); // QButtonGroup QButtonGroup *group= new QButtonGroup(this); // .ui 拖拽生成box1 // 加组后默认变单选 group->addButton(ui->box1); group->addButton(ui->box2); group->addButton(ui->box3); // 单选变多选 group->setExclusive(false); // 绑定信号 QObject::connect(group, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(testClicked(QAbstractButton *)));
QButtonGroup *group= new QButtonGroup(this); group->setObjectName("group"); QRadioButton *radio1 = new QRadioButton("QRadioButton1"); QRadioButton *radio2 = new QRadioButton("QRadioButton2"); QRadioButton *radio3 = new QRadioButton("QRadioButton3"); group->addButton(radio1); group->addButton(radio2); group->addButton(radio3); QVBoxLayout *layout = new QVBoxLayout(this); for (int i = 0; i<group->buttons().size() ; i++) { layout->addWidget(group->buttons()[i]); } // 获取选中的radioButton QButtonGroup *group = findChild<QButtonGroup *>("group"); QRadioButton *radio = (QRadioButton *)group->checkedButton(); qDebug() << radio->text();
属性编辑、图标大小、插入数据(字符串、图标、自定义数据)、读取数据、信号事件
// 自定义数据处理 struct CustomType { QString name; }; Q_DECLARE_METATYPE(CustomType); // 清空之前的item ui->comboBox->clear(); ui->comboBox->addItem("item1"); ui->comboBox->addItem("item2"); // 添加带图标的item 图标在资源文件中 QIcon icon(":/tt/image/install_logo.png"); ui->comboBox->addItem(icon, "item_icon"); // 添加自定义数据item CustomType type; type.name = "zhansan"; QVariant ant; ant.setValue(type); ui->comboBox->addItem("custom_item", ant); // 获取数据 QString res = ui->comboBox->itemText(0); qDebug() << res; // 获取自定义数据 QVariant ant = ui->comboBox->itemData(3); CustomType type = ant.value<CustomType>(); qDebug() << type.name;
常用属性、信号事件、样式设计、重载鼠标自定义事件
// 滑动槽的样式 QSlider::groove { border: 1px solid #999999; height:28px; background: rgba(155,155,155,200); border-radius: 10px; } // 滑块的样式 QSlider::handle { background: rgba(255,0,0,200); border-radius: 10px; width:20px; margin: -10px 0; } // 剩余槽的样式 QSlider::add-page { background: rgba(255, 0, 0, 10); } // 滑过的槽的样式 QSlider::sub-page { background: rgba(0, 255, 0, 30); }
QSlider重载鼠标事件:
1、界面设计器添加自定义CustomSlider类,提升控件
2、覆写mousePressEvent
3、计算鼠标位置
// customSlider.h #ifndef CUSTOMSLIDER_H #define CUSTOMSLIDER_H #include <QSlider> #include <QWidget> class CustomSlider : public QSlider { public: CustomSlider(QWidget *p = NULL); virtual void mousePressEvent(QMouseEvent *ev); }; #endif // CUSTOMSLIDER_H // customSlider.cpp #include "customslider.h" #include <QDebug> #include <QMouseEvent> CustomSlider::CustomSlider(QWidget *p): QSlider(p) { } void CustomSlider::mousePressEvent(QMouseEvent *ev) { qDebug() << ev->pos().x(); QSlider::mousePressEvent(ev); // 百分比 double p = (double)ev->pos().x() / (double)width(); int val = p*(maximum() - minimum()) + minimum(); setValue(val); }
基本属性、插入和获取选中内容、遍历和排序、在列表中显示其他控件
// 关闭 水平垂直滚动条 ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 多选模式 //ui->listWidget->setSelectionMode(QAbstractItemView::MultiSelection); // 设置方向 //ui->listWidget->setFlow(QListView::LeftToRight); // 设置每一行的大小 //ui->listWidget->setGridSize(QSize(100, 50)); // 清除.ui中添加的数据 ui->listWidget->clear(); // 插入数据 QListWidgetItem *item = new QListWidgetItem("code insert"); ui->listWidget->addItem(item); ui->listWidget->addItems({"item2","item 3", "item3"}); // 插入包含图标的item QListWidgetItem *item_icon = new QListWidgetItem("icon item"); item_icon->setIcon(QIcon(":/tt/image/install_logo.png")); ui->listWidget->addItem(item_icon); // 遍历 for (int i = 0; i< ui->listWidget->count() ; i++) { qDebug() << ui->listWidget->item(i)->text(); } // 设置 双击为可编辑状态 ui->listWidget->setEditTriggers(QAbstractItemView::DoubleClicked); for (int i = 0; i< ui->listWidget->count() ; i++) { ui->listWidget->item(i)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable); } // 排序 ui->listWidget->sortItems(Qt::DescendingOrder); // 添加其他控件 QLineEdit *edit = new QLineEdit("QLineEdit"); // item(0) 第一个组件替换为QLineEdit ui->listWidget->setItemWidget(ui->listWidget->item(0), edit);
常用属性设置、设置水平/垂直标题、插入数据、获取选中数据、删除、信号
// 清空所有标题和内容 ui->tableWidget->setColumnCount(0); ui->tableWidget->setRowCount(0); ui->tableWidget->setColumnCount(4); ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("header1")); ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem()); ui->tableWidget->horizontalHeaderItem(1)->setText("header2"); ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("header3")); ui->tableWidget->setHorizontalHeaderItem(3, new QTableWidgetItem("header4")); // 设置 第0列 标题的宽度 ui->tableWidget->setColumnWidth(0, 200); // 设置垂直标题 ui->tableWidget->setRowCount(3); QStringList list = {"col1", "col2", "col3"}; ui->tableWidget->setVerticalHeaderLabels(list); // 插入数据 ui->tableWidget->setItem(0,0, new QTableWidgetItem("col 0,0")); ui->tableWidget->setItem(0,1, new QTableWidgetItem("col 0,1")); ui->tableWidget->setItem(0,2, new QTableWidgetItem("col 0,2")); ui->tableWidget->setItem(1,0, new QTableWidgetItem("col 1,0")); ui->tableWidget->setItem(2,0, new QTableWidgetItem("col 2,0")); // 结尾添加一行 int row = ui->tableWidget->rowCount(); ui->tableWidget->insertRow(row); ui->tableWidget->setItem(row, 0, new QTableWidgetItem("new row 4")); // 开始添加一行 ui->tableWidget->insertRow(0); ui->tableWidget->setItem(0, 0, new QTableWidgetItem("new row 0")); // 插入图片 ui->tableWidget->setItem(0, 1, new QTableWidgetItem("new row 1 icon")); ui->tableWidget->item(0, 1)->setIcon(QIcon(":/tt/image/install_logo.png")); // 设置行高 ui->tableWidget->setRowHeight(0, 80); // 设置图标显示大小 ui->tableWidget->setIconSize(QSize(ui->tableWidget->rowHeight(0), ui->tableWidget->rowHeight(0))); // 插入widght 图片 QLabel *label = new QLabel(); QPixmap pix(":/tt/image/install_logo.png"); // 缩放图片 pix = pix.scaled(ui->tableWidget->columnWidth(0), ui->tableWidget->rowHeight(row)); label->setPixmap(pix); ui->tableWidget->setCellWidget(row, 0, label); // 如何获取选中的数据? // 没有数据的item无法选择 auto items = ui->tableWidget->selectedItems(); for (int i = 0; i < items.size() ; i++ ) { qDebug() << "row = " << items[i]->row() << " col = " << items[i]->column() << " text = " << items[i]->text(); } // 选择模式器 QItemSelectionModel *mode = ui->tableWidget->selectionModel(); // 获取所有的选择索引 auto list = mode->selectedIndexes(); qDebug() << list;
样式:标题格式、间隔线、背景颜色间隔
// 标题样式 QHeaderView::section { background-color: rgb(60, 193, 255); color: white; padding-left: 4px; border: 1px solid #6c6c6c; } // 选中 QHeaderView::section:checked { background-color: rgb(255, 170, 0); } // 悬停 QHeaderView::section:hover { background-color: red; }
常用属性、标题、内容插入、内容选择、拖动和删除、信号事件
// 清理.ui中生成的标题 ui->treeWidget->setHeaderItem(new QTreeWidgetItem()); // 清理数据 ui->treeWidget->clear(); ui->treeWidget->setColumnCount(3); // 设置标题 ui->treeWidget->headerItem()->setText(0, "header1"); ui->treeWidget->headerItem()->setText(1, "header2"); ui->treeWidget->headerItem()->setText(2, "header3"); // 插入数据 // 从结尾处插入 ui->treeWidget->addTopLevelItem(new QTreeWidgetItem()); ui->treeWidget->topLevelItem(0)->setText(0, "tree node col1"); ui->treeWidget->topLevelItem(0)->setText(1, "tree node col2"); ui->treeWidget->addTopLevelItem(new QTreeWidgetItem({"tree row1 col1", "tree row1 col2"})); // 开头插入 ui->treeWidget->insertTopLevelItem(0, new QTreeWidgetItem({"tree row0 col1", "tree row0 col2"})); // 结尾插入 ui->treeWidget->insertTopLevelItem(ui->treeWidget->topLevelItemCount(), new QTreeWidgetItem({"tree end col1"})); // 结尾插入 QTreeWidgetItem *node = new QTreeWidgetItem(ui->treeWidget); node->setText(0, "new end col1"); // 插入子节点 ui->treeWidget->topLevelItem(0)->addChild(new QTreeWidgetItem({"child1"})); ui->treeWidget->topLevelItem(0)->addChild(new QTreeWidgetItem({"child2"})); ui->treeWidget->topLevelItem(0)->addChild(new QTreeWidgetItem({"child3"})); ui->treeWidget->topLevelItem(1)->addChild(new QTreeWidgetItem({"2 - child1"})); ui->treeWidget->topLevelItem(1)->addChild(new QTreeWidgetItem({"2 - child2"})); // 插入孙节点 ui->treeWidget->topLevelItem(0)->child(1)->addChild(new QTreeWidgetItem({"grandSon"})); // 设置图标 ui->treeWidget->setIconSize(QSize(50, 50)); ui->treeWidget->topLevelItem(0)->setIcon(0, QIcon(":/tt/image/install_logo.png")); // 插入 widget QPushButton *btn = new QPushButton("button"); ui->treeWidget->setItemWidget(ui->treeWidget->topLevelItem(1), 0, btn); // 设置颜色交错 ui->treeWidget->setAlternatingRowColors(true);
样式处理
// 行列样式 QTreeView { background-color:#fefff7; alternate-background-color: #cbe8d9; } QTreeView::item { border: 1px solid #c5daff; } // 选中和悬停的样式 QTreeView::item:hover { background: #c5daff; } QTreeView::item:selected { background: #debbe8; } // 标题样式 QTreeView::section { background-color: #ffe0d8; border: 1px solid #c5daff; }
如何利用手册查看对应的样式示例:
点击帮助 -> 搜索 -> style sheeet -> Qt Style Sheets Examples -> 查找对应的控件设置详情
// 图片放在资源文件中 QTreeView::branch:has-siblings:!adjoins-item { border-image: url(":/tt/image/vline.png") 0; } QTreeView::branch:has-siblings:adjoins-item { border-image: url(":/tt/image/branch-more.png") 0; } QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: url(":/tt/image/branch-end.png") 0; } QTreeView::branch:has-children:!has-siblings:closed, QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(":/tt/image/branch-closed.png"); } QTreeView::branch:open:has-children:!has-siblings, QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(":/tt/image/branch-open.png"); }
QDialog包括QColorDialog、QErrorMessage、QFileDialog、QFontDialog、QInputDialog、QMessageBox、QProgressDialog.
CustomDialog dialog;
dialog.setWindowTitle("dialog");
int result = dialog.exec();
switch (result) {
case QDialog::Accepted:
qDebug() << "Accepted";
break;
case QDialog::Rejected:
qDebug() << "Rejected";
break;
default:
break;;
}
自定义messagebox
// 添加qt设计师界面类 // 在界面中自定义ui // 添加必要的信号槽 // CustomMessageBox.h #ifndef CUSTOMMESSAGEBOX_H #define CUSTOMMESSAGEBOX_H #include <QDialog> namespace Ui { class CustomMessageBox; } class CustomMessageBox : public QDialog { Q_OBJECT public: explicit CustomMessageBox(QWidget *parent = nullptr); ~CustomMessageBox(); static int info(QString msg); private: Ui::CustomMessageBox *ui; }; #endif // CUSTOMMESSAGEBOX_H // CustomMessageBox.cpp #include "custommessagebox.h" #include "ui_custommessagebox.h" CustomMessageBox::CustomMessageBox(QWidget *parent) : QDialog(parent), ui(new Ui::CustomMessageBox) { ui->setupUi(this); // 去掉标题栏 setWindowFlags(Qt::FramelessWindowHint); // 设置背景透明 this->setAttribute(Qt::WA_TranslucentBackground, true); } CustomMessageBox::~CustomMessageBox() { delete ui; } int CustomMessageBox::info(QString msg) { CustomMessageBox box; box.ui->label->setText(msg); return box.exec(); } // ui中添加了一个widght作为背景视图,添加一个label、两个按钮 // 添加样式表,圆角 #widget { border-radius:30px; background-color: rgb(204, 204, 204); } Qdialog { border-radius:30px; background-color: rgb(204, 204, 204); border: 1px solid gray; }
自定义processDialog进度条
// ProcessDialog.h #include <QDialog> namespace Ui { class ProcessDialog; } class ProcessDialog : public QDialog { Q_OBJECT public: explicit ProcessDialog(QWidget *parent = nullptr); ~ProcessDialog(); public slots: void setDialog(int value); private: Ui::ProcessDialog *ui; }; #endif // ProcessDialog.cpp #include <QThread> ProcessDialog::ProcessDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ProcessDialog) { ui->setupUi(this); // 去掉标题栏和设置背景透明 setWindowFlags(Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground, true); } ProcessDialog::~ProcessDialog() { delete ui; } void ProcessDialog::setDialog(int value) { ui->progressBar->setValue(value); if (value == 1000) { for (int i = 100; i > 0; i-- ) { this->setWindowOpacity((float)i / 100.0); QThread::msleep(5); // 设置label,shoudon // ui->label->setText(QString::number(i)); // QEventLoop loop; // loop.processEvents(); } this->close(); } } // 自定义多线程 CustomThread.h #include <QThread> class CustomThread : public QThread { Q_OBJECT public: CustomThread(); void run(); signals: void setPos(int value); }; // CustomThread.cpp void CustomThread::run() { for(int i = 0; i <= 1000; i ++) { setPos(i); msleep(10); } } // 外部使用 ProcessDialog dialog; CustomThread thread; QObject::connect(&thread, SIGNAL(setPos(int)), &dialog, SLOT(setDialog(int))); thread.start(); dialog.exec();
QMenuBar、QMenu、QAction
// 插入菜单栏 QMenuBar *bar = new QMenuBar(this); bar->resize(width(), bar->height()); // 一级菜单 QMenu *menu = bar->addMenu("菜单一"); m_menu = menu; // 二级菜单 QAction *action1 = menu->addAction("二级菜单1"); QAction *action2 = menu->addAction("二级菜单2"); QAction *action3 = menu->addAction("二级菜单3"); QMenu *menu1 = menu->addMenu("二级菜单4"); // 菜单设置图标 menu1->setIcon(QIcon(":/tt/image/install_logo.png")); menu1->addAction("三级菜单"); // 添加快捷键 action1->setShortcut(tr("x")); // 绑定点击信号 connect(action1, SIGNAL(triggered()), this, SLOT(test())); // 绑定鼠标悬停信号 connect(action2, SIGNAL(hovered()), this, SLOT(testHovered())); // 设置action可以选中 action1->setCheckable(true); action2->setCheckable(true); action3->setCheckable(true); // QActionGroup QActionGroup *group = new QActionGroup(this); group->addAction(action1); group->addAction(action2); group->addAction(action3); // 设置group中的按钮单选 group->setExclusive(true); // 鼠标位置显示菜单(用于动态显示创建好的菜单) m_menu->exec(QCursor::pos());
QToolBar *toolbar = new QToolBar(this);
toolbar->setGeometry(0, bar->height(), width(), 40);
toolbar->setIconSize(QSize(30, 30));
QAction *a = new QAction(QIcon(":/tt/image/install_logo.png"), "toolaction");
//a->setIcon(QIcon(":/tt/image/install_logo.png"));
toolbar->addAction(a);
QStatusBar *statusBar = new QStatusBar(this);
statusBar->setGeometry(0, height() - 40, width(), 40);
statusBar->showMessage("测试status message", 3000);
menuBar()->addAction("menu1");
statusBar()->showMessage("status bar message");
QToolBar *toolBar = new QToolBar(this);
toolBar->addAction("topaction");
QAction *a = new QAction(QIcon(":/tt/image/install_logo.png"), "icon action");
toolBar->addAction(a);
// 设置action text在icon下面
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
// 在左侧添加toolbar Qt::LeftToolBarArea
addToolBar(Qt::TopToolBarArea, toolBar);
事件函数event、鼠标事件、键盘事件、窗口大小变化事件、重绘事件QPainter
// QEvent子类 QKeyEvent、QMouseEvent、QWheelEvent、QTouchEvent bool EventDemo::event(QEvent *ev) { qDebug() << ev->type(); // 键盘事件 if (ev->type() == QEvent::KeyPress) { QKeyEvent *keyEv = static_cast<QKeyEvent*>(ev); qDebug() << keyEv->key(); // 代表处理,不会把事件传递给其他控件,继续处理下一个事件 return true; } // 父类处理 return QWidget::event(ev); } // 键盘按下 void EventDemo::keyPressEvent(QKeyEvent *event) { // 过滤自动重复触发的 if(event->isAutoRepeat()) return; qDebug() << "keyPressEvent = " << event->key(); } // 键盘弹起 void EventDemo::keyReleaseEvent(QKeyEvent *event) { qDebug() << "keyReleaseEvent = " << event->key(); }
鼠标事件
bool EventDemo::event(QEvent *ev) { qDebug() << ev->type(); // 鼠标事件 if (ev->type() == QEvent::MouseButtonPress) { QMouseEvent *event = static_cast<QMouseEvent*>(ev); // 相对坐标 qDebug() << "QMouseEvent x = " << event->x() << " y = " << event->y(); // 程序坐标 qDebug() << "windowPos x = " << event->windowPos().x() << " y = " << event->windowPos().y(); // 屏幕坐标 qDebug() << "screenPos x = " << event->screenPos().x() << " y = " << event->screenPos().y(); // 本地坐标转屏幕坐标 QPoint point = mapToGlobal(event->pos()); qDebug() << "mapToGlobal x = " << point.x() << " y = " << point.y(); // 获取鼠标的屏幕坐标 qDebug() << "QCursor x = " << QCursor::pos().x() << " y = " << QCursor::pos().y(); // 鼠标按键事件 if (event->buttons() & Qt::LeftButton) { qDebug() << "LeftButton click"; } if (event->buttons() & Qt::RightButton) { qDebug() << "RightButton click"; } if (event->buttons() & Qt::MidButton) { qDebug() << "MidButton click"; } if ((event->buttons() & Qt::LeftButton) && (event->buttons() & Qt::RightButton)) { qDebug() << "LeftButton && RightButton click"; } return true; } return QWidget::event(ev); }
修改鼠标样式
QCursor cursor;
QPixmap map(":/tt/image/install_logo.png");
cursor = QCursor(map, -1, -1);
setCursor(cursor);
// 还原
setCursor(Qt::ArrowCursor);
窗口大小改变事件
void EventDemo::resizeEvent(QResizeEvent *event)
{
qDebug() << "resizeEvent";
// 改变子控件的大小
ui->pushButton->resize(width() * 0.3, height() * 0.3);
}
绘制文字、绘制线、绘制图形、绘制融合图片
QPen用于控制线条的颜色、宽度、线型等
QBrush用于设置填充颜色、填充方式、渐变特性等,可以使用图片做填充
QFont用于绘制文字时设置文字的样式大小
void PainterDemo::paintEvent(QPaintEvent *event) { // 设置绘制设备 QPainter p(this); // 画笔颜色 p.setPen(QColor(255,0,0,150)); // 字体 p.setFont(QFont("黑体", 20)); p.drawText(100, 50, "绘制文字"); // 绘制线 QPen pen; // 实线 pen.setStyle(Qt::SolidLine); // 线的宽度 pen.setWidth(10); // 线刷子 pen.setBrush(Qt::red); // 设置刷子为图片 //pen.setBrush(QBrush(QImage(":/tt/image/install_logo.png"))); // 结尾端样式 pen.setCapStyle(Qt::RoundCap); // 连接处样式 pen.setJoinStyle(Qt::RoundJoin); p.setPen(pen); p.drawLine(QLine(10, 10, 300, 90)); }
QImageDemo::QImageDemo(QWidget *parent) : QWidget(parent), ui(new Ui::QImageDemo) { ui->setupUi(this); img = QImage(1280, 720, QImage::Format_RGBA8888); // 填入颜色 img.fill(QColor(255,0,0,200)); // 遍历设置颜色 uchar *data = img.bits(); // 假定已对齐,不对齐就出错 for (int i = 0; i < img.width() ; i++ ) { for (int j = 0; j < img.height() / 2 ; j++) { data[j * img.width() * 4 + i * 4] = 0; // r data[j * img.width() * 4 + i * 4 + 1] = 255; // g data[j * img.width() * 4 + i * 4 + 1] = 0; // b data[j * img.width() * 4 + i * 4 + 1] = 255; // a } } for (int i = img.width() / 2; i < img.width() ; i++ ) { for (int j = 0; j < img.height() ; j++) { img.setPixelColor(i,j, QColor(0, 0, 0, 255)); } } } void QImageDemo::paintEvent(QPaintEvent *ev) { QPainter p(this); if(!img.isNull()) { p.drawImage(0, 0, img); } }
QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;
QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。
QFlie:访问本地文件或者嵌入资源;
QTemporaryFile:创建和访问本地文件系统的临时文件;
QBuffer:读写QbyteArray, 内存文件;
QProcess:运行外部程序,处理进程间通讯;
QAbstractSocket:所有套接字类的父类;
QTcpSocket:TCP协议网络数据传输;
QUdpSocket:传输 UDP 报文;
QSslSocket:使用 SSL/TLS 传输数据;
顺序访问设备:
是指它们的数据只能访问一遍:从头走到尾,从第一个字节开始访问,直到最后一个字节,中途不能返回去读取上一个字节,这其中,QProcess、QTcpSocket、QUdpSoctet和QSslSocket是顺序访问设备。
随机访问设备:
可以访问任意位置任意次数,还可以使用QIODevice::seek()函数来重新定位文件访问位置指针,QFile、QTemporaryFile和QBuffer是随机访问设备
QFile file("D:\\code\\123.txt"); // 获取当前目录 //QDir::currentPath() if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Open file failed."; return; } else { while (!file.atEnd()) { qDebug() << file.readLine(); } } QFileInfo info(file); qDebug() << info.isDir(); qDebug() << info.isExecutable(); qDebug() << info.baseName(); qDebug() << info.completeBaseName(); qDebug() << info.suffix(); qDebug() << info.completeSuffix();
QDataStream二进制文件读写
// 写入 QFile file("D:\\code\\123.txt"); if (!file.open(QIODevice::WriteOnly)) { qDebug() << "Open file failed."; return; } else { QDataStream out(&file); out << QString("123"); file.close(); } // 读取 QFile file("D:\\code\\123.txt"); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Open file failed."; return; } else { // 读取 QString res; QDataStream in(&file); in >> res; qDebug() << "res = " << res; file.close(); }
QTextStream文本文件读写
// 写入 QFile file("D:\\code\\123.txt"); if (!file.open(QIODevice::WriteOnly| QIODevice::Truncate)) { qDebug() << "Open file failed."; return; } else { QTextStream out(&file); out.setCodec("UTF-8"); // 写入一行换行 out << QString("test message") << endl; out << QString("test message other"); file.close(); } // 读取多行 QFile file("D:\\code\\123.txt"); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Open file failed."; return; } else { QTextStream in(&file); QString res; while (in.readLineInto(&res)) { qDebug() << res; } file.close(); }
1、Qt样式表支持CSS2中定义的所有选择器
选择器 | 例子 | 用途 |
---|---|---|
通用选择器 | * | 所有组件 |
类型选择器 | QPushButton | 所有QPushButton类及其子类 |
属性选择器 | QPushButton[flat=“false”] | 所有QPushButton属性flat=false的类及其子类 |
非子类选择器 | .QPushButton | 所有QPushButton类不包括其子类 |
ID选择器 | QPushButton#btn | ObjectName="btn"的QPushButton组件 |
从属对象选择器 | QDialog QPushButton | QDialog下面的所有QPushButton实例 |
子对象选择器 | QDialog>QPushButton | QDialog下面直接从属的所有QPushButton实例 |
2、子控件,组合组件下面的控件控制,例如QProgressBar::chunk 进度显示块的控制
3、伪状态的控制,如:hover
4、属性的控制 如:border
样式表的使用:
1、设计窗体中设置
2、setStyleSheet函数设置
基础使用
#ifndef CUSTOMTHREAD_H #define CUSTOMTHREAD_H #include <QThread> class CustomThread : public QThread { Q_OBJECT public: CustomThread(); void run(); signals: void setPos(int value); }; #endif // CUSTOMTHREAD_H // cpp #include "customthread.h" CustomThread::CustomThread() { } void CustomThread::run() { for(int i = 0; i <= 1000; i ++) { // 发送信号,外面绑定信号处理 setPos(i); msleep(10); } }
1、基于互斥量的线程同步
QMutex、QMutexLocker 每次只有一个线程获得互斥量的权限
2、QReadWriteLock 适合用于一个线程写,多个线程获取的场景
3、QWaitCondition 适用于一个线程满足某个条件,然后通知其他线程响应的场景
4、基于信号量的线程同步 QSemaphore 适用于保护一定数量的资源
QHostInfo、QNetworkInterface
// QT += network // 电脑设备名称 QString hostName = QHostInfo::localHostName(); QString domainName = QHostInfo::localDomainName(); qDebug() << hostName; qDebug() << domainName; QHostInfo host = QHostInfo::fromName(hostName); // 获取地址列表 QList<QHostAddress> address = host.addresses(); for(int i = 0; i < address.size(); i++) { qDebug() << address[i]; if (address[i].protocol() == QAbstractSocket::IPv4Protocol) { qDebug() << "IPv4Protocol"; } else { qDebug() << "IPv6Protocol"; } } // 获取主机网络接口 QList<QNetworkInterface> interface = QNetworkInterface::allInterfaces(); for(int i = 0; i < interface.size(); i++) { // 设备名称 qDebug() << interface[i].humanReadableName(); // 设备地址 qDebug() << interface[i].hardwareAddress(); }
QTcpSocket
QUdpSocket
QNetworkRequest、QNetworkRequest、QNetworkAccessManager
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkAccessManager> #include <QFile> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_readyRead(); void on_finished(); void on_process(qint64 current, qint64 totle); private: Ui::Widget *ui; QNetworkRequest request; QNetworkAccessManager manger; QNetworkReply *reply; QFile *downloadFile; }; #endif // WIDGET_H // cpp Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); QString urlString = "http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"; QUrl url = QUrl::fromUserInput(urlString); if (!url.isValid()) { qDebug() << "url error"; return; } request = QNetworkRequest(url); reply = manger.get(request); connect(reply, SIGNAL(finished()), this, SLOT(on_finished())); connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead())); connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(on_process(qint64,qint64))); QString fileName = QDir::currentPath() + "/" + url.fileName(); qDebug() << "fileName = " << fileName; if (QFile::exists(fileName)) QFile::remove(fileName); downloadFile = new QFile(fileName); downloadFile->open(QIODevice::ReadWrite); } void Widget::on_readyRead() { qDebug() << "on_readyRead"; downloadFile->write(reply->readAll()); } void Widget::on_finished() { qDebug() << "on_finished"; downloadFile->close(); } void Widget::on_process(qint64 current, qint64 totle) { qDebug() << "current = " << current << " totle = " << totle; }
静态发布:将所有的需要的运行库编译到应用程序中,生成独立的可执行文件
共享库形式发布:将程序依赖的共享库和可执行程序一起发布
1、进入编译完成的release版本安装包目录
2、找到对应编译器的工具windeployqt
# D:\Qt\Qt5.12.12\5.12.12\msvc2017\bin
# windeployqt一般再对应的编译器bin目录下
# 打包程序 等待完成即可
# windeployqt并不能保证一次将所有的依赖都复制到对应的目录下,需要移除qt环境变量或者找个不包含qt环境的电脑测试,如果有缺失dll,将缺失的dll复制到对应的目录
D:\Qt\Qt5.12.12\5.12.12\msvc2017\bin\windeployqt.exe demo.exe
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。