前言:
以前 windows下做工具主要是MFC,趁有点空时间,研究了QT,感觉跟MFC 差不多,VS 比 QT CREATOR 还是强大,不过QT可以跨平台,功能更强大,MFC 只能在win平台下.;
1:环境
win10
Qt 6.8 LTS
Qt Creator 14.0.2
MINGW :13.1
download:https://download.qt.io/official_releases/online_installers/
选择 qt-unified-windows-x64-online.exe
2:安装
已经安装好了,真是吃硬盘, 最少准备40G,用QT一定要用ssd,最差是sata3,最好是m2 pcie3及以上,512G起吧,IOPS 差用起来难受,
3:常用控件
左边MFC(VS2022) 右边 为 qt的
常用控件都差不多,会MFC,只要稍微熟悉了基本用法就OK了,常用控件都这样;
4:qt跟MFC 对比,注意事项
1> 创建工程
qt 选择cmake(qmake,cmake,qbs) ,cmake 相对比较熟悉(linux下编译用到)
MFC 选择MFC应用
下面简单的做个DMO ,
几个button tableview menu dialog 等
直接上代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QButtonGroup>
#include <qitemselectionmodel.h>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QButtonGroup * m_group1;
public slots:
void ClickButton_previous(bool b);
void ClickButton_previous2();
void onBtnFunc(int n);
void btnToggled(int,bool);
void slotselectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void receiveData(QString data);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "dialog.h"
#include <QStandardItemModel>
#include <QStringListModel>
#include "mylistmodel.h"
#include "qlogging.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//查找名为label_2的QLabel对象,并返回
QLabel * re2= findChild<QLabel*>("label1");
re2->setText("test111");
// QAction * p = new QAction();
// connect(newAction, &QAction::triggered, this, &MainWindow::onNewFile);
//connect(action, SIGNAL(triggered()), this, SLOT(onFileNew()));
// QAction
// public Q_SLOTS:
// void trigger() { activate(Trigger); }
// void hover() { activate(Hover); }
// void setChecked(bool);
// void toggle();
// void setEnabled(bool);
// void resetEnabled();
// inline void setDisabled(bool b) { setEnabled(!b); }
// void setVisible(bool);
// Q_SIGNALS:
// void changed();
// void enabledChanged(bool enabled);
// void checkableChanged(bool checkable);
// void visibleChanged();
// void triggered(bool checked = false);
// void hovered();
// void toggled(bool);
//SIGNAL SLOT 带参数要统一,不然找不到
///ok1
// QMetaObject::Connection c1 = connect(ui->action111_111, SIGNAL(triggered(bool)), this, SLOT(ClickButton_previous(bool)));
// if(c1 != NULL){
// qDebug("3333");
// }
// QAction *newAction = new QAction(tr("&New"), this);
//connect(newAction, &QAction::triggered, this, &MainWindow::onNewFile);
///ok2
QMetaObject::Connection c1 = connect(ui->action111_111, &QAction::triggered, this, &MainWindow::ClickButton_previous);
if (c1 != NULL){
}
//button
// public Q_SLOTS:
// void setIconSize(const QSize &size);
// void animateClick();
// void click();
// void toggle();
// void setChecked(bool);
// Q_SIGNALS:
// void pressed();
// void released();
// void clicked(bool checked = false);
// void toggled(bool checked);
QMetaObject::Connection c2 = connect(ui->pushButton1, SIGNAL(clicked()), this, SLOT(ClickButton_previous2()));
if(c2 != NULL){
qDebug("3333");
}
connect(ui->pushButton2,&QPushButton::clicked,[=](){
re2->setText("pushButton2");
});
//qradiobutton
// 连接信号与槽函数
m_group1 = new QButtonGroup(this);
m_group1->addButton (ui->radioButton, 0);
m_group1->addButton (ui->radioButton_2, 1);
m_group1->setExclusive(true);
//connect (m_group1, SIGNAL (buttonClicked(int)), this, SLOT(onBtnFunc(int)));
connect (m_group1, SIGNAL(idToggled(int,bool)), this, SLOT(btnToggled(int,bool)));
// connect(ui->radioButton, SIGNAL(idToggled(int,bool)), this, SLOT(btnToggled(int,bool)));
// connect(ui->groupBox1, &QRadioButton::toggled, this, SLOT(btnToggled(int,bool)));
QStandardItemModel *model= new QStandardItemModel();
// 添加列头
model->setHorizontalHeaderLabels(QStringList() << "Column 1" << "Column 2" << "Column 3");
// 添加数据
for (int row = 0; row < 10; ++row) {
for (int col = 0; col < 3; ++col) {
QStandardItem *item = new QStandardItem(QString("Row %1, Column %2").arg(row).arg(col));
model->setItem(row, col, item);
}
}
QTableView *tableView= ui->tableView1;
tableView->setModel(model);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
// 显示窗口
// tableView->show();
//选择行事件
//ok_1
// QObject::connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
// [&](const QItemSelection &selected, const QItemSelection &deselected){
// QModelIndexList indexes = selected.indexes();
// if (!indexes.isEmpty()) {
// QModelIndex firstIndex = indexes.first();
// qDebug() << "Row" << firstIndex.row() << "selected.";
// }
// });
// public Q_SLOTS:
// virtual void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
// virtual void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
// virtual void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
// virtual void clear();
// virtual void reset();
// void clearSelection();
// virtual void clearCurrentIndex();
// Q_SIGNALS:
// void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
// void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
// void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous);
// void currentColumnChanged(const QModelIndex ¤t, const QModelIndex &previous);
// void modelChanged(QAbstractItemModel *model);
//ok_2///
connect(tableView->selectionModel(),&QItemSelectionModel::selectionChanged,this,&MainWindow::slotselectionChanged);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ClickButton_previous(bool b){
QLabel * re2= findChild<QLabel*>("label1");
re2->setText("test2221");
//click menu
qDebug()<<"dialog top";
Dialog dialog(this);
//子窗口给父窗口发送消息
//connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
connect(&dialog, &Dialog::sendData,this,&MainWindow::receiveData);//连接信号与槽
dialog.show(); //or connect(&child, &child::sendData,this,&MainWindow::receiveData);//连接信号与槽
dialog.exec(); //以模态方式打开对话框(打开主窗口时不能使用主窗口)
}
void MainWindow::ClickButton_previous2(){
QLabel * re2= findChild<QLabel*>("label1");
re2->setText("test3333");
}
void MainWindow::onBtnFunc(int n)
{
quint16 a = m_group1->checkedId();
QLabel * re2= findChild<QLabel*>("label1");
QString q= "onBtnFunc"+QString::number(n);
re2->setText(q);
}
void MainWindow::btnToggled(int n ,bool b){
qDebug()<<n<<b;
QLabel * re2= findChild<QLabel*>("label1");
QString q= QString::number(n)+"onBtnFunc";
re2->setText(q);
}
//
void MainWindow::slotselectionChanged(const QItemSelection &selected, const QItemSelection &deselected){
QModelIndexList indexes = selected.indexes();
if (!indexes.isEmpty()) {
QModelIndex firstIndex = indexes.first();
qDebug() << "Row" << firstIndex.row() << "selected.";
}
}
void MainWindow::receiveData(QString data)//接收子窗口发送的数据
{
qDebug()<<"recv dialog msg"<<data ;
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void on_pushButton_clicked();
public :
signals:
void sendData(QString data); //点击发送时发送的QString型data信号 给 主窗口
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QObject>
// #define SIGNAL(arg) #arg
// #define SLOT(arg) #arg
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButton, &QPushButton::clicked, this, &Dialog::on_pushButton_clicked);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
qDebug()<<"Dialog";
emit sendData("Dialog"); //
}
connect(button, SIGNAL(clicked()), this, SLOT(handleButtonClicked()));
connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
有重载函数时可以用 qOverload 指明
void do_click(bool b)
connect(sender, &SenderClass::signalName, this, qOverload(&Widget::do_click)); //函数里带参数bool b
void do_click()
connect(sender, &SenderClass::signalName, this, qOverload<>(&Widget::do_click));//函数里不带参数
一个信号可以连接多个slot
类试于 Observer Pattern(观察者模式)
connect(sender, &SenderClass::signalName, receiver1, &ReceiverClass1::slotName);
connect(sender, &SenderClass::signalName, receiver2, &ReceiverClass2::slotName);
5:测试结果
6:如果觉得有用,麻烦点个赞,加个收藏
下章讲述 qml,感觉跟lua 类试,都可以相互调用