QT

信号: 相当于窗口消息, 对于窗口的所有操作, 都会产生窗口消息. 只不过看此窗口消息是否有函数响应

槽: 消息处理函数, 相当于 MFC 的 onCreate onMouseMove onPressUp 等 指定的消息处理函数,
不过此处是注册的消息处理回调

注册 信号-槽:

使用信号和槽,类需要继承QObject,并且添加Q_OBJECT宏:

connect()函数最常用的一般形式:

connect(sender, signal, receiver, slot);
// 参数可以理解为: 某个对象, 的 某个信号, 被 某个对象, 的 某个函数 响应
参数说明:
 sender:发出信号的对象
 signal:发送对象发出的信号
 receiver:接收信号的对象
 slot:接收对象在接收到信号之后所需要调用的函数

信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。如果不一致,允许的情况是,槽函数的参数可以比信号的少。

Qt4 的书写方式:
connect(&button, SIGNAL(pressed()), this, SLOT(close()));
这里使用了SIGNAL和SLOT这两个宏,将两个函数名转换成了字符串。注意到connect()函数的 signal 和 slot 都是接受字符串,一旦出现连接不成功的情况,Qt4是没有编译错误的(因为一切都是字符串,编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增加程序的不稳定性。

Qt5的书写方式:
connect(&button, &QPushButton::pressed, this, &QWidget::close);

这样的定义方式, 虽然在书写的时候可能会很麻烦, 在消息响应上, 会很灵活, 自有默认的消息响应规则


自定义槽函数:

在Qt4中,槽函数需要在函数声明前加入slots关键字,在类中 声明 关键词 slots 受正常的类权限约束
在Qt5 中,任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数。

‘emit’ 关键字 激活信号, 发送此信号, 激活对应的回调

自定义信号和槽注意事项
 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
 使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
 使用 emit 在恰当的位置发送信号;
 使用QObject::connect()函数连接信号和槽;
 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数

信号和槽的更多用法:
1) 一个信号可以和多个槽相连
如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
2) 多个信号可以连接到一个槽
只要任意一个信号发出,这个槽就会被调用。
3) 一个信号可以连接到另外的一个信号
当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
4) 槽可以被取消连接
5) 使用Lambda 表达式
在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的。


窗口的主要分类
 QMainWindow 类提供一个有菜单条、锚接窗口(例如工具条)和一个状态条的主应用程序窗口。
 QWidget 类是所有用户界面对象的基类。
 QDialog 类是对话框窗口的基类。对话框窗口是主要用于短期任务以及和用户进行简要通讯的顶级窗口。

========================================
MainWindow (相当于多文档)

添加菜单:
// 获得当前窗口 菜单对象
QMenuBar * pobjMenuBar = this->menuBar();

// 添加一个菜单主选项, 返回一个菜单对象
QMenu * pobjMenu = pobjMenuBar->addMenu(“Menu_Test”);

// 在菜单住选项, 添加一个子菜单选项
QAction * pobjAction = pobjMenu->addAction(“Menu_Test_Action”);

// 设置槽和信号的连接
connect(pobjAction, &QAction::triggered, &
{
QMessageBox::information(this, NULL,
“Menu_Test 的 Menu_Test_Action 菜单被触发”,
QMessageBox::Ok);

  1. });

添加菜单分割线
QMenu::addSeparator();


添加控件说明
QAction::setToolTip();


生成工具栏
QToolBar* pobjToolBar = this->addToolBar(“ToolBarName”);

在工具栏添加控件
pobjToolBar->addWidget(pobjBtnPush);


添加核心控件
QTextEdit * pobjTextEdit = new QTextEdit(this);
this->setCentralWidget(pobjTextEdit);

动态添加一个窗口
QDockWidget* pobjNewDockWidget = new QDockWidget(this);
this->addDockWidget(Qt::RightDockWidgetArea, pobjNewDockWidget);

给动态窗口添加控件
QPushButton * pobjBtnNewPush = new QPushButton(pobjNewDockWidget);

================================================================================
Tips:

error: C2001: 常量中有换行符设置编译器为MinGW, 暂不使用VS系列编译器如需使用VS系列编译器时, 选择文件格式保存为 “UTF-8 BOM” 格式

模态对话框
QDialog dlg;
dlg.setWindowTitle(“模态对话框”);
dlg.exec(); // Exec 为模态对话框显示,
// 启动一个新的消息循环, 会等待执行完毕才返回

栈中 非模态对话框
QDialog dlg;
dlg.setWindowTitle(“非模态对话框栈”);
dlg.show(); // 只是起到显示的作用, 代码会继续运行
// 因为是栈对象, 则函数退出则销毁
// 如果显示对话框之后, 没有代码, 则函数退出,
// 对话框对象销毁, 则会出现窗口一闪而过的状况

堆中 非模态对话框
QDialog * pDlg = new QDialog;
pDlg->setAttribute(Qt::WA_DeleteOnClose); // 设置 对话框关闭, 自动销毁对话框
pDlg->setWindowTitle(“非模态对话框堆”);
pDlg->show();


标准对话框
类 | 作用
QColorDialog | 选择颜色
QFileDialog | 选择文件或者目录
QFontDialog | 选择字体
QInputDialog | 允许用户输入一个值,并将其值返回
QMessageBox | 模态对话框,用于显示信息、询问问题等
QPageSetupDialog | 为打印机提供纸张相关的选项
QPrintDialog | 打印机配置
QPrintPreviewDialog | 打印预览
QProgressDialog | 显示操作过程

QString strPath = QFileDialog::getOpenFileName(); // 获取选中文件路径
QStringList strPathLst = QFileDialog::getOpenFileNames(); // 获取选中文件列表

QString 的 section 和 split

  1. Split 仅仅是分割, 通过一个标志(字符 字符串 正则字符串) 进行分割字符串, 返回一个字符串列表, 如果参数 behavior = SkipEmptyParts 则拆分出来的空白的列表元素, 则会被剔除
  2. Section 仅仅是分组, 通过一个标志(字符 字符串 正则字符串) 进行分组(标志不会体现), 得到一个字符串列表, 然后通过参数进行定位, 正向从0开始, 反向从-1开始, **相当于集成了Split之后的字符串列表操作,只是不返回这个列表**

QRegExp QT的正则编译组件

  1. QRegExp qregExp("([0-9a-zA-Z]{32})"); // 相当于编译正则表达式
  2. if(strMid.indexOf(qregExp) < 0){ //Error, No Match }; //返回值为负,则未匹配

QMessageBox
QMessageBox::aboutQt | 弹出QT环境说明
QMessageBox::about | 自定义关于说明
QMessageBox::question | 设置一个选择框, 可设置多个按钮

================================================================================
控件:

QPushButton
可设置按钮图标,但需注意, 设置按钮文字之后, 图标只会在文字之前, 如需仅显示图标, 则设置按钮无文字即可
UI设计器, 可以创建槽函数, 自动响应控件消息(绑定槽和信号), 相当于MFC的双击写代码.(暂未发现实现原理, 在UI.H 文件中 未见绑定, 不知道在何处绑定?)

容器:
在容器中可以存放其他控件, 一般用于窗口的多项展示
Tab-Widget
选页容器, 用于存放控件的容器
响应消息:void Widget::on_tabWidget_currentChanged(int index); index 为当前展示的Page
ui->tabWidget->currentIndex(); 可获取当前展示的Page
ui->tabWidget->count(); 获得当前容器中, 已经启用了多少个页面
ui->tabWidget->setCurrentIndex(0); 设置被选中的页面, 序号从0开始

Stacked-Widget
多层叠加容器,
此容器, 不支持控件内按钮翻页(暂未发现, 感觉可以监听鼠标双击,实现)
ui->stackedWidget->currentIndex(); 为获得当前展示的Page
ui->stackedWidget->count(); 获得当前容器中, 已经启用了多少个页面
ui->stackedWidget->setCurrentIndex(0); 设置被选中的页面, 序号从0开始

输入控件:
comBox:
选择输入, 多选项, 选择一项进行输入
ui->comboBox->currentIndex(); // 获取当前选中的选项序号, 序号从0开始
ui->comboBox->currentData(index); // 暂未知作何使用, 传入序号, 会传出一个Qvarient(Invalid)
ui->comboBox->currentText(); // 获取当前选中的选项文字内容

lineEdit:
单行文本输入
使用 ui->lineEdit->text(); 获得当前输入的内容

textEdit:
多行文本输入, 提供复制粘贴/字体颜色等选项, 相当于记事本的窗口
使用 ui->textEdit->document();; 获得当前内嵌的一个Document对象指针
pDoc->toPlainText(); 获得无格式的ASCII输入 (一般用此)
pDoc->toRawText(); 获得无转义的Ascii输入

显示控件:
QLabel:
一般用于显示信息(文本, 图片, 动图等)
objLabel1.setText(“这是一个显示框”); // 设置文字
objLabel1.text(); // 获得控件中的文字

  1. objLabel2.setText("<a href=\"https://www.baidu.com\">百度一下</a>"); //设置超链接, 设置HTML引用链接, 点击之后启动默认浏览器并跳转至链接
  2. objLabel2.setOpenExternalLinks(true); // 设置启用超链接
  3. objLabel3.setPixmap(*pMap); // 设置一个静态图,
  4. objLabel3.setScaledContents(true); // 设置图片自动适应控件大小
  5. objLabel4.setMovie(m_pMV); // 可设置一个动图

QLcdNumber:
用于显示数值(目前看起来没啥用, 不如显示时间日期啥的)
ui->lcdNumber->display(123); // 设置控件可显示数据
ui->lcdNumber->setDigitCount(3); // 设置数据显示位宽
ui->lcdNumber->value(); // 获得当前控件中的数据

QProgressBar:
进度条
ui->progressBar->maximum(); // 获得控件支持的最大值
ui->progressBar->minimum(); // 获得控件支持的最小值
ui->progressBar->value(); // 获得当前控件中记录的位置
ui->progressBar->setValue(int); // 设置进度条当前的数据位置

QTableView(二维列表框):
在QT中使用Model/View模式进行TableView等操作
即 在View中设置一个 Model, 其他时间这个Model只管数据集合, View只管同步显示

  1. 添加列表头
  2. // 单列多行添加
  3. QStringList lstLabel;
  4. lstLabel << "Test1" << "Test2" << "Test3" << "Test4" << "Test5";
  5. stdMod->setVerticalHeaderLabels(lstLabel);
  6. // 多列多行组合添加
  7. for(int i = 0; i < 5; i++)
  8. {
  9. QStandardItem* pStdItem = new QStandardItem();
  10. pStdItem->setText(QString("QStandardItem:%1").arg(i));
  11. stdMod->setVerticalHeaderItem(i, pStdItem);
  12. }
  13. 添加 行表头
  14. // 单行多列添加
  15. QStringList lstLabel;
  16. lstLabel << "Test1" << "Test2" << "Test3" << "Test4" << "Test5";
  17. stdMod->setHorizontalHeaderLabels(lstLabel);
  18. // 多列多行组合添加
  19. for(int i = 0; i < 5; i++)
  20. {
  21. QStandardItem* pStdItem = new QStandardItem();
  22. pStdItem->setText(QString("QStandardItem:%1").arg(i));
  23. stdMod->setHorizontalHeaderItem(i, pStdItem);
  24. }
  25. // 隐藏 列表头
  26. m_pTableView->horizontalHeader()->hide();
  27. // 隐藏 行表头
  28. m_pTableView->verticalHeader()->hide();
  29. // 添加行列数据( 设置某一行 某一列 的数据: 标准元素(可为其他控件) )
  30. stdMod->setItem(row, column, new QStandardItem(QString(""));
  31. // 增加一行数据
  32. QList<QStandardItem*> items;
  33. QStandardItem* pTmpStdItem = new QStandardItem();
  34. items.append(pTmpStdItem);
  35. stdMod->insertRow(index, items);
  36. // 增加一列数据
  37. QList<QStandardItem*> items;
  38. QStandardItem* pTmpStdItem = new QStandardItem();
  39. items.append(pTmpStdItem);
  40. stdMod->insertColumn(index, items);
  41. // 设置行列内容不可更改
  42. ui->m_tableViewShow->setEditTriggers(QAbstractItemView::NoEditTriggers);
  43. QAbstractItemView.NoEditTriggers No editing possible. 不能对表格内容进行修改
  44. QAbstractItemView.CurrentChanged Editing start whenever current item changes.任何时候都能对单元格修改
  45. QAbstractItemView.DoubleClicked Editing starts when an item is double clicked.双击单元格
  46. QAbstractItemView.SelectedClicked Editing starts when clicking on an already selected item.单击已选中的内容
  47. QAbstractItemView.EditKeyPressed Editing starts when the platform edit key has been pressed over an item.
  48. QAbstractItemView.AnyKeyPressed Editing starts when any key is pressed over an item.按下任意键就能修改
  49. QAbstractItemView.AllEditTriggers Editing starts for all above actions.以上条件全包括
  50. // 设置选中则整行选中
  51. ui->m_tableViewShow->setSelectionBehavior(QAbstractItemView::SelectRows);
  52. QAbstractItemView.SelectItems Selecting single items.选中单个单元格
  53. QAbstractItemView.SelectRows Selecting only rows.选中一行
  54. QAbstractItemView.SelectColumns Selecting only columns.选中一列
  55. // 设置单选多选模式
  56. ui->m_tableViewShow->setSelectionMode(QAbstractItemView::ExtendedSelection);
  57. QAbstractItemView.NoSelection 不能选择
  58. QAbstractItemView.SingleSelection 选中单个目标
  59. QAbstractItemView.MultiSelection 选中多个目标
  60. QAbstractItemView.ExtendedSelection QAbstractItemView.ContiguousSelection 的区别不明显,主要功能是正常情况下是单选,但按下CtrlShift键后,可以多选
  61. // 通过某个标题, 进行排序(升序)
  62. ui->m_tableViewShow->sortByColumn(0, Qt::SortOrder::AscendingOrder);
  63. // 设置是否 允许排序
  64. ui->m_tableViewShow->setSortingEnabled(true);
  65. //根据内容设置列宽
  66. TableView->resizeColumnToContents(0); // 某一列
  67. TableView->resizeColumnsToContents(); // 全部
  68. TableView->resizeRowsToContents(); // 某一行
  69. // 开启排序
  70. TableView->setSortingEnabled(true);
  71. // 从TableView 获取数据
  72. // 获得当前已选中的行
  73. `DWORD dwCurRowCount = ui->m_tableViewShow->currentIndex().row();`
  74. // 获取所有行0列的数据
  75. ```C++
  76. QTableView& refTable = *(ui->m_tableViewShow);
  77. QAbstractItemModel *pobjItemModel = refTable.model(); // 获得当前Model
  78. DWORD dwRowCount =pobjItemModel->rowCount();
  79. QStringList lstMd5;
  80. for(DWORD dwRow = 0; dwRow < dwRowCount; dwRow++)
  81. {
  82. // 遍历第 row 行的所有信息
  83. QModelIndex modelIndex = pobjItemModel->index(dwRow, 0);
  84. // 获得QModelIndex选中行的数据
  85. // QMap((0, QVariant(QString, "63b2fb27fb73923bfed158486b05d753"))(7, QVariant(int, 132)))
  86. QMap<int, QVariant>& refTmpMap = pobjItemModel->itemData(modelIndex);
  87. lstMd5 << refTmpMap[modelIndex.column()].toString() ;
  88. }

// 遍历获得TableView所有数据, 二维数据表

  1. QTableView& refTable = *(ui->m_tableViewShow);
  2. QAbstractItemModel* pObjItemMode = refTable.model();
  3. DWORD dwRowCount = pObjItemMode->rowCount(); // 得到最大行数
  4. DWORD dwColumnCount = pObjItemMode->columnCount(); // 得到最大列数
  5. QList<QStringList> lstStringLst; // 构建一个二维表
  6. for(DWORD dwRow = 0; dwRow < dwRowCount; dwRow++)
  7. {
  8. QStringList lstString ; // 一行中 每列的数据
  9. for(DWORD dwColumn = 0; dwColumn < dwColumnCount; dwColumn++)
  10. {
  11. // 依次获取某行的某列数据
  12. QModelIndex& objModeIndex = pObjItemMode->index(dwRow, dwColumn);
  13. lstString << pObjItemMode->itemData(objModeIndex)[0].toString();
  14. }
  15. lstStringLst << lstString;
  16. }
  17. foreach (auto var, lstStringLst) {
  18. qDebug() << var;
  19. }

Tips: 一定需要在最后使用 TableView.setModel(Q*Mod); 不然数据不会显示

  1. ---
  2. QT-Json:<br />(总体来说, qtJson 使用起来还行, 哈希表的使用没啥太大的区别)<br />使用QJsonDocument::fromJson(); 来序列化一个JSon字符串, 得到Json对象<br />使用QString(QJsonDocument(jsonObject).toJson()); 得到一Json格式的字符串

// QString >> QJson QJsonObject CMyHTTP::getJsonObjectFromString(const QString jsonString) { QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toLocal8Bit().data()); if( jsonDocument.isNull() ) { qDebug()<< “===> please check the string “<< jsonString.toLocal8Bit().data(); } QJsonObject jsonObject = jsonDocument.object(); return jsonObject; }

// QJson >> QString QString CMyHTTP::getStringFromJsonObject(const QJsonObject& jsonObject) { return QString(QJsonDocument(jsonObject).toJson()); }

// 然后 JsonObj 可以使用 json[‘Key’]方式获取对象, 然后获得对象使用 JsonObj[“key”].toInt() /toObject()/toQString()/toBool() 等 进行值转换

// 可以使用jsonObj.isInt(); 等函数, 获得当前键值对应的value的格式 // jsonObj 可以当作哈希表使用 // 使用JsonObj.contains(“?”); 判断当前jsonObj中 是否有此Key, 以防 访问时崩溃

  1. ---
  2. 事件响应:<br />鼠标事件:<br />均为预置虚函数, 进行虚函数覆盖, 从而响应消息.<br />protected:<br />virtual void mousePressEvent(QMouseEvent *event);<br />virtual void mouseReleaseEvent(QMouseEvent *event);<br />virtual void mouseDoubleClickEvent(QMouseEvent *event);<br />virtual void mouseMoveEvent(QMouseEvent *event);

//滚轮事件, event->orientation() 得到滚动方向 Qt::Vertical垂直方向 //QPoint point = event->angleDelta(); 得到滚动范围, 一般鼠标只有y轴在变(正负增减) virtual void Widget::wheelEvent(QWheelEvent *event);

键盘事件:

virtual void Widget::keyPressEvent(QKeyEvent *event) // 键盘按键按下 event->modifiers()// 获得当前按下的附加按键 比如 ALT SHIFT CTRL 使用Qt::ControlModifier, Qt::AltModifier, Qt::ShiftModifier等Modifier结尾的宏进行识别 event->key()// 获得具体的按键扫描码 使用Qt::Key_Left, KEY开头的扫描码别名进行识别

virtual void Widget::keyReleaseEvent(QKeyEvent *event) // 键盘按键抬起

窗口事件: virtual void Widget::enterEvent(QEvent event) // 鼠标进入窗口范围 virtual void Widget::leaveEvent(QEvent event) // 鼠标离开窗口范围

virtual void Widget::moveEvent(QMoveEvent *event) // 窗口移动 qDebug() << “OldPos: “ << event->oldPos(); // 改变之前的窗口位置 qDebug() << “CurPos: “ << event->pos(); // 当前的窗口位置

virtual void Widget::resizeEvent(QResizeEvent *event) // 窗口改变大小 qDebug() << “OldSize: “ << event->oldSize(); // 改变之前的窗口大小 qDebug() << “CurSize: “ << event->size(); // 当前的窗口大小

virtual void Widget::closeEvent(QCloseEvent *event) // 窗口关闭

窗口事件过滤器: 相当于设置了一个事件回调, 在主窗口响应子窗口的消息 public slots:
bool eventFilter(QObject ,QEvent ); //注意这里 bool Widget::eventFilter(QObject watched, QEvent event)
{
if (watched==ui->lineEdit1) //首先判断控件(这里指 lineEdit1)
{
if (event->type()==QEvent::FocusIn) //然后再判断控件的具体事件 (这里指获得焦点事件)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::green);
ui->lineEdit1->setPalette(p);
}
else if (event->type()==QEvent::FocusOut) // 这里指 lineEdit1 控件的失去焦点事件
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::white);
ui->lineEdit1->setPalette(p);
}
}
if (watched==ui->lineEdit2) //这里来处理 lineEdit2 , 和处理lineEdit1 是一样的
{
if (event->type()==QEvent::FocusIn)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::green);
ui->lineEdit2->setPalette(p);
}
else if (event->type()==QEvent::FocusOut)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::white);
ui->lineEdit2->setPalette(p);
}
}
return QWidget::eventFilter(watched,event); // 最后将事件交给上层对话框
}

随机数: qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); //设置随机种子 qrand(); // 获取随机数

相当于C语言的 srand(time(0)); rand();

  1. 不规则窗体, 且支持按键移动:<br />实现原理:<br />设置窗口背景为图片, 然后在鼠标按下时,记录当前的坐标, 在鼠标移动时,设置窗口位置
  1. 然后使用 下列代码 擦除指定颜色, 实现图片透明, 窗口边角透明.(但此行为会出现边角锯齿)
  2. QBitmap mask= QPixMap.createMaskFromColor(QColor(255,255,255),Qt::MaskInColor);
  3. PixMap.setMask(mask);
  4. 1. 在窗口创建时, 设置窗口的背景颜色为透明, 且设置窗口无标题
  5. 2. Paint事件中, 进行图片背景的重绘
  6. 3. 在鼠标按下事件中, 记录鼠标的位置
  7. 4. 在鼠标移动事件中, 设置窗口的位置
  1. 定时器:<br />使用定时器, 定时器需要 连接信号和槽,<br />connect(&m_timer, &QTimer::timeout, PFN_HandleTimer);<br />m_timer.isActive(); // 用于判断定时器是否已经启动<br />m_timer.start([nSec]); // 启动定时器, 可带参, 带参数为整形毫秒<br />m_timer.setInterval(1000); // 设置定时器超时时间, 即多少毫秒触发一次定时器<br />m_timer.stop(); // 停止定时器
  2. ---
  3. 文件操作:<br />QFile: 文件操作<br />封装了文件读写相关的API<br />QFileInfo: 文件信息<br />封装了文件信息相关的API

QDataStream: 数据流 相当于 STL::OFstream 和 STL::IFstream QTextStream: 文本流 文本流, setAutoDetectUnicode() //设置输出输入的时候, 自动识别UTF8编码 readLineInto(&QString); //输入流时, 得到一行一次读取文本流

  1. ---
  2. QT程序打包:<br />使用 QT自带的工具,进行工具库打包:执行命令`windeployqt` 应用程序名(qttext.exe)<br />工具路径在 "%QT%\Qt5.5.0\5.5\mingw492_32\bin\windeployqt" 路径下<br />在已经编译的程序目录运行 `windeployqt [DstFileName]` 则会自动拷贝库目录下的所需动态库到当前目录

原理: 解析导入表, 添加指定的库

  1. ---
  2. ---
  3. Tips:<br />1. QMouseEvent 获取按键触发, 使用的是 event->button() 并非 event->KeyPress()<br />2. 设置按钮透明 QPushButton.setFlat(true)<br />3. 解决中文乱码(网传代码, 暂未测试):
  1. #ifdef WIN32
  2. #pragma execution_character_set("utf-8")
  3. #endif
  1. // 以下部分解决中文乱码
  2. QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312"));
  3. QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312"));
  4. QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
  1. // 经过实际编码 仅找到一项
  2. QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312"));
  1. QString转STD::String (代码为Unicode转Ascii)

    1. QTextCodec *code = QTextCodec::codecForName("gb18030");
    2. std::string name = code->fromUnicode(pathname).data(); // pathname 为QString的中文路径名
  2. QT加载DLL 总结为: QLibrary对象加载DLL模块(相当于LoadLibrary()), 然后 QLibrary::resolve(QString); 得到函数指针, 然后进行正常的函数指针调用

    1. (resolve相当于 GetProcess();) 使用 QLibrary::unload(); 进行模块卸载(相当于FreeLibrary())
    1. #ifdef Q_OS_WIN
    2. typedef long ( *SHELLRUN)(long,const char*, const char*, const char* ,const char* , int );
    3. SHELLRUN test;
    4. QString str = "shell32.dll";
    5. QLibrary lib(str);
    6. test = (SHELLRUN)lib.resolve("ShellExecuteA");
    7. const char * te = "open";
    8. const char * te1 = ".\\help\\Guide.hlp";
    9. test(NULL,te,te1,NULL,NULL,5);
    10. lib.unload();
    11. #endif
  3. QMap 与 ‘QHash’ 均为哈希表结构, 只不过 QMapHash_Keys 会被排序 ``` ================================================================================
    QtWidgets-FAQ:
    Q: 在QT_Design 中 拖动控件, 然后响应信号, 自动生成槽函数, 此时这个编辑器的动作是什么? 在UI文件中, 并未看到具体的connect连接, 如何实现?
    A: (猜测: 在类申明中, 会在私有槽中, 添加槽函数, 是不是槽为虚函数? 虚表覆盖调用?) ???
    A2: 在看到事件处理时(WIN32 消息处理), 发现每个控件在基类都会定义很多事件响应函数,这些函数都是虚函数,则子类复写响应函数,则会自动多态调用到子类的相应代码.

Q: 在comBox中,
comboBox->currentData(int role = Qt::UserRole); 的作用是什么
A: 暂未知

Q: comBox 分组问题, 如何在代码中实现某一组comBox切换,响应消息
A: 暂未探讨

Q: QPicture 和 QPixmap 的区别是什么? QPicture的构造仅为一个int 为什么?
A: (暂更)
QPicture 相当于一个 画布(Win中的DC), QPicture 并不是指代常规的 Img文件, 需配合QPainter使用, QPainter在QPicture上进行”作画”
QPixmap 相当于抽象一个图像处理设备

Q: QMovie 的暂停如何操作?
A: 暂未探讨

Q: QLcdNumber 有没有 最低或最大的极限值?
A: 暂未探讨

Q: QProgressBar控件是否有 设置范围(SetRange?) 步长增长(AddStep?) 等
A: 暂未探讨

Q: QProgressBar控件,如果超过最小或最大极限值时, 会如何?
A: 暂未探讨

Q: 在窗口响应消息时, 会有键盘消息传来, 如何显式得到按键字符串?
A: Qt::Key 有对应的键盘码. EVENT.text() 可得到可显的 Unicode, 经不完全测试, F1~F12不可显, Shift不可显, Shift+a~z 会根据当前大小写, 显示对应的对立 大小写, 比如当前大写锁定(CapsLock选中) 输入A得到大写的A, 则Shift+A得到小写的a (且此问题暂未深究)

Q: mouseMoveEvent 在什么时候触发
A: 窗口响应mouseMoveEvent之后, 并不是鼠标在窗口滑过就有消息, 在mousePress触发之后, 鼠标按下,才会出现mouseMoveEvent消息触发
A: 窗口响应mouseMoveEvent, 需要设置窗口跟随鼠标, ‘setMouseTracking(true)’ 则无需任何操作 鼠标在窗口中移动,均会捕获 此选项默认为false ,只有在mousePress之后才会触发鼠标移动事件

Q: focusInEvent 与 focusOutEvent 从字面来理解 应该为窗口焦点的丢失和设置
A: 暂未探讨(在当前的操作中, 仅触发enterEvent和leaveEvent, 并不会触发焦点相关)

Q: 不规则窗体中, 在设置一张图片时, 图片的白边不会自动透明化处理
A: 使用以下代码, 擦除指定颜色即可(在擦除过程中, 在边角会出现锯齿)
QBitmap mask= QPixMap.createMaskFromColor(QColor(255,255,255),Qt::MaskInColor);
PixMap.setMask(mask);

Q: 在使用 windeployqt 命令进行QT环境打包时, 可能会出现错误信息: Cannot find GCC installation directory. g++.exe must be in the path.
A: 因为QT环境配置不完整, 可以从 系统菜单 -> QT[*] -> [对应的编译器版本, 当前使用MinGW] -> Qt 5.11.0 for Desktop(命令行BAT脚本文件) 进入QT工作环境

Q: Combox 的 信号 activated 和 currentIndexChanged 的区别是什么
A: 经查询, activated 信号 在点击combox时, 就会触发. 而 curIndexChange 则会在combox内容改变时触发
但经过简单的测试, 均为内容改变时触发(当前机器测试环境)

Q: 在使用Combox时, 自定义信号槽链接 connect时, 需要注意什么
因为activated 和 currentIndexChanged 均有重载, (int) 和 (const QString&) 的重载, 则在使用
connect(谁, 的什么消息, 被谁, 的什么函数响应); 这个模式会出错, 因为无法判断使用的是哪个重载, 则解决方法为:
定义一个函数指针, 然后跟connect 说明是哪个消息, 被哪个函数响应.
typedef void (QComboBox::*PFN_COMBOX_CUR_INDEX_CHANGED_STRING)(const QString&); // 定义函数指针
PFN_COMBOX_CUR_INDEX_CHANGED_STRING pfnCurChange = &(QComboBox::currentIndexChanged); // 获得函数指针
然后 connect(pObjCombox, pfnCurChange, pObjUnk, pObjUnk->pfnMsgHandle); // 连接信号槽

Q: 如何改变stackWidget的Page中的控件大小
A: 在QT_Design中设计的控件, 暂时未找到设置方法, (在设置时,设置expanding 无用, 但是通过addPage添加的属性依然为QSizePolicy::Policy(Expanding))
解决方案为: 调用stackWidget的addPage方法添加页面, 会自动重置一些属性, 然后会填充满stackWidget控件,并随着改变大小(代码添加)

Q: 如何使用Win32API
A: 头文件包含: #include “Windows.h” 静态库添加: LIBS += -lKernel32

A2: 因为Windows会出现重复包含的情况, 则需要调整Winsock2在windows之前, 或定义宏 WIN32_LEAN_AND_MEAN
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include
#include
#include “../../CommonLib/DownWrapper.h”
// #pragma comment(lib, “user32.lib”)
// #pragma comment(lib, “kernel32.lib”)
#endif

================================================================================
QT代码片段:

屏幕截图:

  1. #include <QPixmap>
  2. #include <QString>
  3. #include <QDebug>
  4. #include <QApplication>
  5. #include <QDesktopWidget>
  6. #include <QTextCodec>
  7. #include <QDir>
  8. #include <QScreen>
  9. #include <QDateTime>
  10. #include <QWindow>
  11. void Widget::on_pushButton_pressed()
  12. {
  13. qDebug() << "Widget::on_pushButton_pressed()" << "\r\n";
  14. qDebug() << "CurWorkPath: " << QDir::currentPath();
  15. QDesktopWidget& deskTop = *QApplication::desktop(); // 获取桌面
  16. QWindow * pobjWindow = deskTop.windowHandle(); // 获取桌面工具类
  17. QScreen* pobjScreen = pobjWindow->screen(); // 获取屏幕对象
  18. // 屏幕对象抓取屏幕Wnd, QT5 之后 不支持QPixMap::grabWindow()
  19. // 且 grabWindow() 不为静态函数
  20. QPixmap pixMap = pobjScreen->grabWindow(QApplication::desktop()->winId());
  21. QString strPicPath = "./%1_screenShot.jpg";
  22. qDebug() << "\r\nQDateTime::currentDateTimeUtc().toString(): " << QDateTime::currentDateTimeUtc().toString();
  23. strPicPath = strPicPath.arg(QDateTime::currentDateTime().toString("yyyy.MM.dd-hh.mm.ss")); // 格式化时间字符串
  24. qDebug() << "\r\nSavePicPath: " << strPicPath;
  25. pixMap.save(strPicPath, "JPG"); // 输出 屏幕截图
  26. QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); // 设置UTF-8支持
  27. }

================================================================================
QtQuick - QML

QtQuick 是QT开发团队开发的一款快速构建UI的项目
QML 是QtQuick支持的类JavaScript脚本 (暂时如此理解)

================================================================================
QtQuick - QML - QA:
Q:
A:

Q:
A:

================================================================================