cjtest

导航

QtStudy

Qt

容器&布局

QGridLayout

  • 网格布局
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
   ui->setupUi(this);
    qgride=new QGridLayout(this);
    button1=new QPushButton(this);
    button1->setText("区域一:顶部菜单栏");
    button1->setFixedHeight(40);
    button1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    button2=new QPushButton(this);
    button2->setText("区域二:侧边栏");
    button2->setFixedWidth(150);
    button2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    button3=new QPushButton(this);
    button3->setText("区域三:底部");
    button3->setFixedHeight(40);
     button2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    qgride->setContentsMargins(0,0,0,0);
    qgride->setSpacing(0);
    qgride->addWidget(button1,0,1);
    //占据第0行第0列,跨三行一列
    qgride->addWidget(button2,0,0,3,1);
    qgride->addWidget(button3,3,1);
    //如果需要grid在UI中生效,需要添加下面这段代码
    this->centralWidget()->setLayout(qgride);
}

MainWindow::~MainWindow()
{
    delete ui;
}

[!note]

在MainWindow窗体下,布局都需要在最后加上this,这样运行才能在ui上看见

PixPin_2026-06-02_15-17-11

QFormLayout

  • 表单格式
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
   form=new QFormLayout(this);
    name=new QLineEdit;
    name->setPlaceholderText("请输入名字");
    sex=new QLineEdit;
    sex->setPlaceholderText("随便");
    form->addRow("姓名:",name);
    form->addRow("年龄",sex);
}

Widget::~Widget() {}

[!warning]

创建的是Qwidget窗体而不是QMainWindow

formlayou

垂直布局

水平布局

命令按钮组控件

push button

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //设置窗体在做面起始位置,以及窗体大小
    this->setGeometry(300,150,500,400);
    p1=new QPushButton("按钮1",this);
    p2=new QPushButton("按钮2",this);
    //设置按钮位置与大小
    p1->setGeometry(20,20,150,50);
    p2->setGeometry(20,90,150,50);
    //与信号槽函数连接
    connect(p1,SIGNAL(clicked()),this,SLOT(button_add1()));
    connect(p2,SIGNAL(clicked()),this,SLOT(button_add2()));
}

MainWindow::~MainWindow() {}
void MainWindow::button_add1()
{
     this->setStyleSheet("QMainWindow {background-color:rgba(255,255,0,100%);}");

}
void MainWindow::button_add2()
{
   this->setStyleSheet("QMainWindow {background-color:rgb(255,26,33);}");
}

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QPushButton* p1,*p2;
//槽函数
private slots:
    void button_add1();
    void button_add2();
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H

ToolButton

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//菜单栏
#include <QToolBar>
#include <QToolButton>
//样式
#include <QStyle>
#include <QApplication>
#include<QIcon>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    QToolBar* tooBar;
    QToolButton* toolButton;
    QStyle* style;
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H

 //设置窗体位置与大小
    this->setGeometry(300,150,500,300);
    tooBar=new QToolBar(this);
    tooBar->setGeometry(20,20,200,50);
    //设置工具栏样式风格以及图标(系统自带图标)
    style=QApplication::style();
    QIcon ico=style->standardIcon(QStyle::SP_TitleBarContextHelpButton);
    //
    toolButton=new QToolButton;
    toolButton->setIcon(ico);
    toolButton->setText("文件");

    toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    tooBar->addWidget(toolButton);

radiobutton

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//引入单选按钮
#include<QRadioButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QRadioButton *radio,*radio2;
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H
this->setGeometry(300,150,500,400);

    radio=new QRadioButton(this);
    radio2=new QRadioButton(this);

    radio->setGeometry(20,20,150,40);
    radio2->setGeometry(20,80,150,40);

    radio->setText("单选1");
    radio2->setText("单选2");
//设置是否选中
    radio->setChecked(true);

checkbutton

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QCheckBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QCheckBox *ckbox1;
private slots:
    //声明槽函数,用于对事件的连接,当相应的事件被触发时调用与其连接
    //的槽函数
    void checkboxstatus(int);
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(300,150,500,400);
    this->setStyleSheet("QMainWindow {background-color:rgba(255,100,0,100%);}");

    ckbox1=new QCheckBox(this);
    ckbox1->setGeometry(20,20,200,50);
    ckbox1->setText("跑步");

    //设置复选框选中状态
    //ckbox1->setChecked(true) 也可以表示选中;
    ckbox1->setCheckState(Qt::Checked);
    //开启半选中状态
    ckbox1->setTristate();

    connect(ckbox1,SIGNAL(stateChanged(int)),this,SLOT(checkboxstatus(int)));
}

MainWindow::~MainWindow() = default;
void MainWindow::checkboxstatus(int status)
{
    switch(status)
    {
    case Qt::Checked:
        ckbox1->setCheckState(Qt::Checked);
        break;
    case Qt::Unchecked:
        ckbox1->setCheckState(Qt::Unchecked);
        break;
    case Qt::PartiallyChecked:
        ckbox1->setCheckable(Qt::PartiallyChecked);
        break;
    default:
        break;
    }
    // if (status==Qt::Unchecked)
    // {
    //     ckbox1->setCheckState(Qt::Unchecked);
    // }
    // else if(status==Qt::Checked)
    // {
    //     ckbox1->setCheckState(Qt::Checked);
    // }
    // else
    // {
    //     ckbox1->setCheckable(Qt::PartiallyChecked);
    // }
}

commandlinkbutton

#define MAINWINDOW_H

#include <QMainWindow>
#include <QCommandLinkButton>
//引入桌面服务
#include <QDesktopServices>
//引入url
#include <QUrl>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QCommandLinkButton* clb;
private slots:
    void mycommandlik_click();
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(300,150,500,300);
    //内容信息,描述信息,widget
    clb=new QCommandLinkButton("测试clb","点击测试clb",this);
    clb->setGeometry(50,100,250,60);

    connect(clb,SIGNAL(clicked()),this,SLOT(mycommandlik_click()));
}

MainWindow::~MainWindow() = default;
void MainWindow::mycommandlik_click()
{
    QDesktopServices::openUrl(QUrl("www.baid.com"));
}

dialogbuttonbox

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QDebug>

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
    QPushButton* btn;
    QDialogButtonBox* dilogbtn;
private slots:
    void open_the_dialogbtn_box(QAbstractButton*);

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(400,300,500,400);
    btn=new QPushButton("打开dialog",this);

    dilogbtn=new QDialogButtonBox(this);
    dilogbtn->setGeometry(100,50,200,30);
    //为dialogbuttonbox添加信息和按钮类别
    //dilogbtn->addButton(QDialogButtonBox::Cancel)->setText("取消");
    dilogbtn->addButton(QDialogButtonBox::Cancel);
    dilogbtn->button(QDialogButtonBox::Cancel)->setText("取消");
    //将pushbutton添加到dialobuttonbox中,并设定按钮角色为action role
    dilogbtn->addButton(btn,QDialogButtonBox::ActionRole);
    connect(dilogbtn,SIGNAL(clicked(QAbstractButton*)),this,SLOT(open_the_dialogbtn_box(QAbstractButton*)));
}

MainWindow::~MainWindow() = default;

void MainWindow::open_the_dialogbtn_box(QAbstractButton* bt)
{
    if(bt==dilogbtn->button(QDialogButtonBox::Cancel))
    {
        qDebug()<<"你已经点击【取消】按钮了";
    }else if(bt==btn)
    {
         qDebug()<<"你已经点击【自定义】按钮了";
    }
}

容器组控件

Group box 组合框

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QGroupBox>
#include <QPushButton>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QRadioButton>
#include <QGridLayout>

class Widget : public QWidget
{
    Q_OBJECT
private:
    QGroupBox *gb,*gb2;
    QRadioButton* rbtn1,*rbtn2,*rbtn3;
    QPushButton *btn;
    QCheckBox *ckb,*ckb2,*ckb3;
    QVBoxLayout *vbl,*vbl1;
    QGridLayout* gridlayou;

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
};
#endif // WIDGET_H

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    gridlayou=new QGridLayout(this);
    vbl=new QVBoxLayout;
    vbl1=new QVBoxLayout;
    gb=new QGroupBox("groub 按钮组");
    rbtn1=new QRadioButton("单选按钮1");
    rbtn2=new QRadioButton("单选按钮2");
    rbtn3=new QRadioButton("单选按钮3");


    vbl->addWidget(rbtn1);
    vbl->addWidget(rbtn2);
    vbl->addWidget(rbtn3);
    gb->setLayout(vbl);

    gb2=new QGroupBox("按钮组");
    //开启是否可选按钮组中所有按钮
    gb2->setCheckable(true);
    ckb=new QCheckBox("全选");
    ckb2=new QCheckBox("复选按钮2");
    ckb3=new QCheckBox("复选按钮3");


    vbl1->addWidget(ckb);
    vbl1->addWidget(ckb2);
    vbl1->addWidget(ckb3);
    gb2->setLayout(vbl1);
    gridlayou->addWidget(gb,0,0);
    gridlayou->addWidget(gb2,0,1);
    this->setLayout(gridlayou);
}

Widget::~Widget() = default;

SCroll Area 滚动区域

#include "widget.h"

#include <QApplication>
#include <QLabel>
#include <QScrollArea>
#include <QGridLayout>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    //设置窗口大小
    w.resize(500,400);
    QLabel *lb=new QLabel;
    lb->setText("ddd");
    //拉伸至全屏
    lb->setScaledContents(true);
    //获取照片
    QImage imag(":/img/image/1.jpeg");
    //将照片转化成pixmap并将其填充到lb中
    lb->setPixmap(QPixmap::fromImage(imag));
    QScrollArea *scroll=new QScrollArea;
    //设置跟随窗口大小变动而变动
    scroll->setWidgetResizable(true);
    //总是开启横向滚动条
    scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    //加载qlabel
    scroll->setWidget(lb);
    QGridLayout *grid=new QGridLayout;
    grid->addWidget(scroll);
    w.setLayout(grid);
    w.show();
    return QApplication::exec();
}

tab widget

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTabWidget>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QPushButton>

class Widget : public QWidget
{
    Q_OBJECT
private:
    QTabWidget* tbwidget;
    QGridLayout* grid;
    QLabel* lb;
    QLineEdit* edit;
    QPushButton* btn;
private slots:
    void mesBox();
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
};
#endif // WIDGET_H

#include "widget.h"



Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setGeometry(300,150,400,400);
    tbwidget=new QTabWidget(this);
    tbwidget->setGeometry(20,20,300,300);
    tbwidget->show();
    bool showtbwidget1=true;
    bool showtbwidget2=false;
    bool showtbwidget3=false;
    bool showtbwidget4=false;
    if(showtbwidget1)
    {
        QWidget *widg=new QWidget;
        tbwidget->addTab(widg,"控制面板");
        grid=new QGridLayout;
        lb=new QLabel("姓名");
        edit=new QLineEdit;
        btn=new QPushButton("发送消息");
        grid->addWidget(lb,0,0);
        grid->addWidget(edit,0,1);
        grid->addWidget(btn,0,2);
        tbwidget->setLayout(grid);
    }
    if(showtbwidget2)
    {
        QWidget *widg2=new QWidget;
        tbwidget->addTab(widg2,"控制面板2");
    }
    if(showtbwidget3)
    {
        QWidget *widg3=new QWidget;
        tbwidget->addTab(widg3,"控制面板3");
    }
    if(showtbwidget4)
    {
        QWidget *widg4=new QWidget;
        tbwidget->addTab(widg4,"控制面板4");
    }
    connect(btn,SIGNAL(clicked(bool)),this,SLOT(mesBox()));
}

Widget::~Widget() = default;
void Widget::mesBox()
{
    QMessageBox::information(this,"消息","发送成功");
}

Stacked Widget 堆叠控件

Fram 框架

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->frame->setStyleSheet("background-color:yellow");
    ui->frame_2->setStyleSheet("background-color:green");
    ui->frame->setLineWidth(2);
    ui->frame->setMidLineWidth(2);
    ui->frame->setFrameShape(QFrame::Box);
    ui->frame->setFrameShadow(QFrame::Plain);

    ui->frame_2->setLineWidth(2);
    ui->frame_2->setMidLineWidth(4);
    ui->frame_2->setFrameShape(QFrame::Box);
    ui->frame_2->setFrameShadow(QFrame::Sunken);
}

Widget::~Widget()
{
    delete ui;
}

Widget 小部件

MdiArea MDI区域

Dock Widget 停靠窗体部件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDockWidget>
//颜色
#include <QPalette>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QDockWidget* dw;
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    dw=new QDockWidget("停靠窗口",this);
    //颜色设置
    QPalette pt;
    pt.setColor(QPalette::Window,Qt::cyan);
    dw->setAutoFillBackground(true);
    dw->setPalette(pt);
    dw->setMaximumSize(300,300);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QAxWidget 封装Flash的ActiveX控件

qt项目视图

listview 清单视图

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
//清单试图
#include <QListView>
//字符串
#include <QStringListModel>
#include <QMessageBox>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;

private:
    Ui::Widget *ui;
private:
    QListView* listview1;
    QStringListModel* listmodel;
private slots:
    void Message(const QModelIndex &list);
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    resize(450,250);
    setWindowTitle("清单列表");
    listview1=new QListView(this);
    listview1->setGeometry(20,20,200,150);
    //创建内容
    QStringList list;
    list.append("运动元:篮球,足球");
    list.append("游戏类:switch,怪物猎人,觅仙");
    //实例话QStringListModel
    listmodel=new QStringListModel;
    //将list设置到QStringListModel
    listmodel->setStringList(list);
    //QListView设置显示的内容
    listview1->setModel(listmodel);

    connect(listview1,SIGNAL(clicked(QModelIndex)),this,SLOT(Message(QModelIndex)));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::Message(const QModelIndex &list)
{
    QMessageBox::information(NULL,"兴趣爱好","选中类型 \n"+list.data().toString());
}

image-20260609181525270

treeview 树视图

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//树试图
#include <QTreeView>
#include <QStringList>
#include <QStandardItemModel>


QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    void initTreeViewfn();
    QStandardItemModel* standmodel;
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initTreeViewfn();
}

MainWindow::~MainWindow()
{
    delete ui;
}
//初始化树
void MainWindow::initTreeViewfn()
{
    standmodel=new QStandardItemModel(ui->treeView);
    QStringList list;
    list.append("编号");
    list.append("初中部");
    standmodel->setHorizontalHeaderLabels(list);
    //创建一级节点
    QList<QStandardItem*> item;
    QStandardItem *it=new QStandardItem;
    QStandardItem *it2=new QStandardItem;
    it->setText("1");
    it2->setText("初中部");
    item.append(it);
    item.append(it2);
    //第一个二级节点
    QList<QStandardItem*> it_1;
    QStandardItem *ite=new QStandardItem;
    QStandardItem* ite2=new QStandardItem;
    ite->setText("3");
    ite2->setText("三年级");
    it_1.append(ite);
    it_1.append(ite2);
    it->appendRow(it_1);

    standmodel->appendRow(item);
    //第二个一级节点
    QList<QStandardItem*> item2;
    QStandardItem *its=new QStandardItem;
    QStandardItem *its2=new QStandardItem;
    its->setText("2");
    its2->setText("高中部");
    item2.append(its);
    item2.append(its2);
    standmodel->appendRow(item2);

    ui->treeView->setModel(standmodel);
}

image-20260609181830434

tableview 表视图

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
    void initTableView();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initTableView();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initTableView()
{
    QStandardItemModel* itemodel=new QStandardItemModel;
    QStandardItem* stdi=new QStandardItem;
    stdi->setText("学号");
    QStandardItem* stdi2=new QStandardItem;
    stdi2->setText("姓名");
    QStandardItem* stdi3=new QStandardItem;
    stdi3->setText("性别");
    itemodel->setHorizontalHeaderItem(0,stdi);
    itemodel->setHorizontalHeaderItem(1,stdi2);
    itemodel->setHorizontalHeaderItem(2,stdi3);
    itemodel->setHorizontalHeaderItem(3,new QStandardItem(QObject::tr("分数")));
    //tableview绑定数据模型
    ui->tableView->setModel(itemodel);
    ui->tableView->setColumnWidth(0,120);
    //禁止双击单元格进行修改
    ui->tableView->setEditTriggers(QTableView::NoEditTriggers);

    itemodel->setItem(0,0,new QStandardItem("30256"));
    itemodel->setItem(0,1,new QStandardItem("张山"));
    itemodel->setItem(0,2,new QStandardItem("男"));
    itemodel->setItem(0,3,new QStandardItem("120"));

    itemodel->setItem(1,0,new QStandardItem("30257"));
    itemodel->setItem(1,1,new QStandardItem("李斯"));
    itemodel->setItem(1,2,new QStandardItem("男"));
    itemodel->setItem(1,3,new QStandardItem("500"));
    //排序
    itemodel->sort(3,Qt::DescendingOrder);
}

image-20260609181709711

columnview 列视图

undo view 撤销命令视图

项目部件

list widget 清单控件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QListWidget>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QListWidget *listwid=new QListWidget(this);
    listwid->showFullScreen();
    QListWidgetItem *title=new QListWidgetItem("注意事项");
    title->setTextAlignment(Qt::AlignCenter);
    QStringList list;
    list<<"在线编译器适用于快速测试和调试代码,但对于大型项目,建议使用本地开发环境。";
    list<<"确保您的代码没有语法错误,否则编译将失败。";
    listwid->addItem(title);
    listwid->addItems(list);
}

Widget::~Widget()
{
    delete ui;
}

treewidget 树形控件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->treeWidget->setWindowTitle("测试控件");

    QTreeWidgetItem *top=new QTreeWidgetItem(ui->treeWidget);
    top->setText(0,"北京大学");
    top->setCheckState(0,Qt::Checked);
    ui->treeWidget->addTopLevelItem(top);

    //隐藏表头
    ui->treeWidget->setHeaderHidden(true);
    //二级节点
    QTreeWidgetItem *sec=new QTreeWidgetItem(top);
    sec->setText(0,"南京大学");
    sec->setCheckState(0,Qt::Checked);

}

Widget::~Widget()
{
    delete ui;
}

tablewidget 表控件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->tableWidget->setRowCount(2);
    ui->tableWidget->setColumnCount(2);

    QStringList list;
    list<<"学号"<<"分数";
    ui->tableWidget->setHorizontalHeaderLabels(list);
    QList<QString> str;
    str<<"35642"<<"461368";
    QList<QString> str1;
    str1<<"550"<<"600";
    for(int i=0;i<2;i++)
    {
        int icol=0;
        QTableWidgetItem *item=new QTableWidgetItem(list.at(i));
        ui->tableWidget->setItem(i,icol++,item);
        ui->tableWidget->setItem(i,icol++,new QTableWidgetItem(str1.at(i)));
    }
}

Widget::~Widget()
{
    delete ui;
}

输入控件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//COMBO BOX
#include <QComboBox>
//Fontcombobox
#include <QFontComboBox>
#include <QLabel>
//lineEdit
#include <QLineEdit>
#include <QPushButton>

//
#include <QPlainTextEdit>
//文件
#include <QDir>
#include <QRadioButton>
//文本流
#include <QTextStream>
//核心应用
#include <QCoreApplication>
//
#include <QSpinBox>

//
#include <QTimeEdit>
#include <QDateTime>
#include <QDateTimeEdit>
//
#include <QScrollBar>
//
#include <QKeySequenceEdit>

#include <QMessageBox>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private:
    Ui::MainWindow *ui;
    QComboBox *box;
private:
    QFontComboBox* fontbox;
    QLabel* lb;
    //
    QLineEdit* lines;
    QPushButton* btn;
    QLabel* lableshow;
    //
    QPlainTextEdit* plaint;
    QRadioButton* rad;
    //
    QSpinBox* pinbox;
    //
    QDateTimeEdit* dte;
    QDateEdit* de;
    QTimeEdit* te;
    //
    QScrollBar* hscrbar,*vscrbar;
    //
    QKeySequenceEdit* keysequen;

private slots:
    void showCombox(int);
    void fontcomboshow(QFont);
    void pushbtnclicked();
    void enabledplain();
    void valuechangespinbox(int);
    void keysequenchange(const QKeySequence&);
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //1.QComboBox
    QStringList list;
    list<<"德阳"<<"什邡"<<"广汉";
    box=new QComboBox(this);
    box->addItems(list);

    connect(box,SIGNAL(currentIndexChanged(int)),this,SLOT(showCombox(int)));

    //2.fontcombobox
    fontbox=new QFontComboBox(this);
    lb=new QLabel(this);
    fontbox->setGeometry(10,50,200,30);
    lb->setGeometry(10,80,300,50);

    connect(fontbox,SIGNAL(currentFontChanged(QFont)),this,SLOT(fontcomboshow(QFont)));

    //3.lineedit
    lines=new QLineEdit(this);
    btn=new QPushButton(this);
    lines->setGeometry(10,90,200,30);
    btn->setGeometry(220,90,100,30);
    btn->setText("点击");
    lableshow=new QLabel(this);
    lableshow->setGeometry(10,100,200,100);
    connect(btn,SIGNAL(clicked(bool)),this,SLOT(pushbtnclicked()));

    //4.QPlainTextEdit
    rad=new QRadioButton(this);
    plaint=new QPlainTextEdit(this);
    rad->setGeometry(400,110,120,80);
    plaint->setGeometry(10,190,500,400);
    rad->setText("开启只读模式");
    //设置文件路径
    QDir::setCurrent(QCoreApplication::applicationDirPath());
    //打开文件名称
    QFile file("moc_mainwindow.cpp");
    //打开文件以只读模式读取文本信息
    file.open(QFile::ReadOnly|QFile::Text);
    //将文件内容读取到文本流中
    QTextStream stream(&file);
    //读取的文本内容添加到多行编辑文本框中
    plaint->setPlainText(stream.readAll());

    connect(rad,SIGNAL(clicked(bool)),this,SLOT(enabledplain()));

    //5.QSpinBox
    this->setStyleSheet("QMainWindow {background-color:rgba(255,255,0,100%);}");
    pinbox=new QSpinBox(this);
    pinbox->setGeometry(540,190,100,50);
    //设置数字范围
    pinbox->setRange(0,100);
    //设置默认值
    pinbox->setValue(100);
    //设置计数值
    pinbox->setSingleStep(10);
    pinbox->setSuffix("%透明度");

    connect(pinbox,SIGNAL(valueChanged(int)),this,SLOT(valuechangespinbox(int)));

    //6.
    dte=new QDateTimeEdit(QDateTime::currentDateTime(),this);
    dte->setGeometry(540,250,100,20);
    te=new QTimeEdit(QTime::currentTime(),this);
    te->setGeometry(540,280,100,20);
    de=new QDateEdit(QDate::currentDate(),this);
    de->setGeometry(540,310,100,20);

    //7.
    hscrbar=new QScrollBar(Qt::Horizontal,this);
    hscrbar->setGeometry(540,340,100,20);
    vscrbar=new QScrollBar(Qt::Vertical,this);
    vscrbar->setGeometry(650,250,20,100);

    keysequen=new QKeySequenceEdit(this);
    keysequen->setGeometry(540,370,100,20);

    //connect(keysequen,SIGNAL(keySequenceChanged(const QKeySequence&)),this,SLOT(keysequenchange(const QKeySequence&)));
//新写法
        connect(keysequen,&QKeySequenceEdit::keySequenceChanged,this,&MainWindow::keysequenchange);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showCombox(int index)
{
    QMessageBox mybo(QMessageBox::Question,"消息",box->itemText(index),QMessageBox::Yes|QMessageBox::No);
    mybo.exec();
}

void MainWindow::fontcomboshow(QFont font)
{
    lb->setFont(font);
    QString str="特色";
    lb->setText(str);
}

void MainWindow::pushbtnclicked()
{
    lableshow->setText(lines->text());
}

void MainWindow::enabledplain()
{
    if(rad->isChecked())
    {
        plaint->setReadOnly(true);
    }
    else
    {
        plaint->setReadOnly(false);
    }
}

void MainWindow::valuechangespinbox(int i)
{
    double dx=(double)i;
    this->setWindowOpacity(dx/100);
}

void MainWindow::keysequenchange(const QKeySequence &key)
{
    if(key==QKeySequence("Ctrl+Q"))
    {
        this->close();
    }else
    {
        qDebug()<<key.toString();
    }
}

槽函数

  • connect(object,signal(signal1),object,slot(method1))

  • 一个信号可以与另一个信号相连

    • connect(object,signal(signal1),object1,signal(signal2));
  • 同一个信号可以与多个槽相连

    • connect(object,signal(signal1),object1,slot(slot1))
    • connect(object,signal(signal1),object2,slot(slot1))
  • 同一个槽可以响应多个槽

    • connect(object,signal(signal1),object,slot(slot1))
    • connect(object2,signal(signal1),object,slot(slot1))

[!warning]

其中object表示对象,而object和object1表示不同的对象;如果您在使用 Qt Designer 时,槽函数命名遵循了 on_控件名_信号名() 的规则,Qt 会自动帮您建立连接。解决方案:遇到这种情况,可以加上 Qt::UniqueConnection 标志位,确保同一个信号-槽对只连接一次:如connect(btn, &QPushButton::clicked, this, &MyWidget::mySlot, Qt::UniqueConnection);

示例:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QGridLayout>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QLabel* lb,*showlb;
    QLineEdit* edit;
    QPushButton* btn;
    QGridLayout* gridlayout;
private slots:
    void calculate();

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"
const static double PI=3.1415;



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    gridlayout=new QGridLayout(this);
    lb=new QLabel;//(this);
    lb->setText("请输入半径");
    showlb=new QLabel;//(this);
    edit=new QLineEdit;//(this);
    edit->setPlaceholderText("半径值");
    btn=new QPushButton;//(this);
    btn->setText("计算圆球体积");
    // lb->setGeometry(10,10,80,20);
    // edit->setGeometry(90,10,100,20);
    // btn->setGeometry(200,10,100,20);
    // showlb->setGeometry(20,30,100,20);
    gridlayout->addWidget(lb,0,0);
    gridlayout->addWidget(edit,0,1);
    gridlayout->addWidget(btn,0,2);
    gridlayout->addWidget(showlb,1,0);
    connect(btn,&QPushButton::clicked,this,&Dialog::calculate);
}

Dialog::~Dialog() = default;
void Dialog::calculate()
{
    int r=edit->text().toInt();
    double tj=(r*r*r)*PI*(4.0/3.0);
    showlb->setText(QString::number(tj));
}

image-20260605183326270

Qstring

#include <QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // Set up code that uses the Qt event loop here.
    // Call QCoreApplication::quit() or QCoreApplication::exit() to quit the application.
    // A not very useful example would be including
    // #include <QTimer>
    // near the top of the file and calling
    // QTimer::singleShot(5000, &a, &QCoreApplication::quit);
    // which quits the application after 5 seconds.

    // If you do not need a running Qt event loop, remove the call
    // to QCoreApplication::exec() or use the Non-Qt Plain C++ Application template.

    int m=QString::compare("ABCD","abcd",Qt::CaseInsensitive);
    int l=QString::compare("ABCD","abcd",Qt::CaseSensitive);
    qDebug()<<"m="<<m<<","<<"l="<<l;

    return QCoreApplication::exec();
}

image-20260606101247511

map,hash,vector

map(有序)

  • 如果存在多个相同的键时,最后一个键会将前面的覆盖

  • foreach时,key,v需要提前声明

  • 插入方式有两种

  QMap<int,QString> map;
    map[0]="ddd";
//更新值,也可以理解成后一个覆盖前一个值
    map.insert(1,"kjlkj");
    map.insert(1,"555");
    qDebug()<<map;

image-20260606110547341

  • 遍历方式

    • stl标准类型迭代

    • 迭代器

 //迭代器
    QMapIterator<int,QString> itr(map);
    while(itr.hasNext())
    {
        itr.next();
        qDebug()<<itr.key()<<itr.value();
    }
    //stl标准类型迭代
    QMap<int,QString>::iterator it=map.begin();
    while(it!=map.end())
    {
        qDebug()<<it.key()<<":"<<it.value();
        it++;
    }

image-20260606122004351

[!warning]

如果你仅仅是为了查找某个键对应的值,强烈建议使用 map.value(key) 而不是 map[key]
因为如果在查找时误用了 map[key],且该键不存在,QMap 会偷偷帮你创建一个默认值(例如 QString 会创建一个空字符串,int 会创建一个 0)并塞进 map 里,这可能会导致你的 map 莫名其妙多出很多无效数据,甚至引发内存问题。

QMultiMap

  • 同一个键可拥有多个值
 QMultiMap<int,QString> multimap;
    multimap.insertMulti(0,"dd");
    multimap.insertMulti(0,"88");
	multimap.insert(1,"saf");
    multimap.insert(1,"erwe");
    qDebug()<<multimap;

image-20260606124604589

hash(无序)

  • 与map相同
    QHash<int,QString> hs;
    hs[0]="dd";
    hs.insert(1,"mlk");
    hs.insert(1,"sdfsd");
    qDebug()<<hs;
    //通过获取keys从而便利值
    QList<int> list=hs.keys();
    for(int i;i<list.length();i++)
    {
        qDebug()<<"key:"<<list[i]<<","<<"value:"<<hs.value(list[i]);
    }
    //stl迭代
    QHash<int,QString>::const_iterator constitr;
    for(constitr=hs.constBegin();constitr!=hs.constEnd();constitr++)
    {
        qDebug()<<"k:"<<constitr.key()<<","<<"v:"<<constitr.value();
    }

image-20260606130232577

vector

  • 插入操作
QVector<int> vec;
    vec.insert(0,2);
    vec<<3;
    vec.append(4);
    qDebug()<<vec;

image-20260606131753940

  • 遍历操作
 QVector<int> vec;
    vec.insert(0,2);
    vec<<3;
    vec.append(4);
    qDebug()<<vec;
    //遍历元素
    for(int i;i<vec.length();i++)
    {
        qDebug()<<vec[i];
    }

image-20260606132015700

list(顺序存储结构)

#include <QCoreApplication>
#include <QList>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QList<QString> ls;
    ls.append("1");
    ls.insert(0,"dsa");
    ls.insert(0,"fsasf");
    //普通遍历
    for(int i=0;i<ls.length();i++)
    {
        qDebug()<<ls.at(i);
    }
    qDebug()<<"===========";
    //迭代遍历(可读可写)
    QList<QString>::iterator listr;
    for(listr=ls.begin();listr!=ls.end();listr++)
    {
        //解引用
        qDebug()<<(*listr);
        *listr=(*listr)+"10";
    }
    qDebug()<<"===========";
    //只读
    QList<QString>::const_iterator constitr;
    for(constitr=ls.constBegin();constitr!=ls.constEnd();constitr++)
    {
        qDebug()<<(*constitr);
    }
     qDebug()<<"========";
    //查询值
    qDebug()<<ls.at(0);
    qDebug()<<ls.value(1);
    qDebug()<<ls.contains("110");
    qDebug()<<ls.contains("0");
     qDebug()<<"========";
    //修改
    ls.replace(2,"555");
    qDebug()<<ls;
     qDebug()<<"========";
    //删除
    ls.remove(0);
    qDebug()<<ls;
    return QCoreApplication::exec();

}

image-20260606153621572

link list(链式存储)

  • 顺序存储查询快,末尾插入快;而链式存储插/删除入快,查询慢;qt6去除了qlinkedlist

  • 改用std::list

  std::list<QString> ls;
    ls.push_back("dasz");
    ls.push_front("1");
    //插入数据尾部
    ls.insert(ls.end(),"dd");
    //插入指定位置数据
    auto index= std::next(ls.begin(),1);
    ls.insert(index,"mm");
    qDebug()<<ls;
    //stl标准类型迭代
    std::list<QString>::iterator litr;
    for(litr=ls.begin();litr!=ls.end();litr++)
    {
        qDebug()<<*litr;
    }

variant

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QVariant>
#include <QDebug>
#include <QMap>
#include <QColor>
#include <QString>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QVariant qvs("ddd");
    qDebug()<<qvs.toString();
    QVariant qint(125);
    qDebug()<<qint.toInt();
    qDebug()<<"============";
    QMap<QString,QVariant> map;
    map["1"]="dsd";
    map["2"]=123;
    map["3"]=123.5;
    map["4"]=QColor(255,255,100);
    qDebug()<<map["1"]<<map["1"].toString();
    qDebug()<<map["2"]<<map["2"].toInt();
    qDebug()<<map["3"]<<map["3"].toDouble();
    qDebug()<<map["4"]<<map["4"].value<QColor>();
    qDebug()<<"============";
    QStringList strlist;
    strlist.append("a");
    strlist.append("b");
    strlist.append("c");
    strlist.append("d");
    QVariant vstr(strlist);
    if(vstr.type()==QVariant::StringList)
    {
        for (int i = 0; i < vstr.toStringList().length(); ++i) {
            qDebug()<<vstr.toStringList().at(i);
        }
        //qDebug()<<vstr.toStringList();
    }
    qDebug()<<"============";
    struct student
    {
        QString name;
        int age;
        QString sex;
    };
    student stu;
    stu.name="张三";
    stu.age=8;
    stu.sex="男";
    QVariant qvstu=QVariant::fromValue(stu);

    qDebug()<<qvstu.canConvert<student>();
    if(qvstu.canConvert<student>())
    {
       student st= qvstu.value<student>();
       student te=qvariant_cast<student>(qvstu);
       qDebug()<<"name:"<<st.name<<"age:"<<te.age<<"sex:"<<st.sex;
    }
}

MainWindow::~MainWindow() = default;

image-20260606182439147

layout

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QTextEdit>
#include <QGridLayout>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
private:
    QGridLayout* grid,*algrid;
    QLabel* userid;
    QLabel* username;
    QLabel* usersex;
    QLabel* userdepart;
    QLabel* userage;
    QLineEdit* idedit;
    QLineEdit* nameeidt;
    QComboBox* sexcombox;
    QTextEdit* departedit;
    QLineEdit* ageedit;
    QLabel* indivatual_information;
    QTextEdit* infor;
    QHBoxLayout* horb,*hb;
    QVBoxLayout* vb;
    QPushButton* surebtn,*cancelbtn;

};
#endif // DIALOG_H

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle("消息表");
    grid=new QGridLayout;
    userid=new QLabel("用户编号:");
    username=new QLabel("用户名");
    userage=new QLabel("用户年龄");
    usersex=new QLabel("用户性别");
    userdepart=new QLabel("用户部门");
    idedit=new QLineEdit;
    nameeidt=new QLineEdit;
    ageedit=new  QLineEdit;
    sexcombox=new QComboBox;
    sexcombox->addItem("男");
    sexcombox->addItem("女");
    departedit=new QTextEdit;
    ageedit=new QLineEdit;
    grid->addWidget(userid,0,0);
    grid->addWidget(idedit,0,1);
    grid->addWidget(username,1,0);
    grid->addWidget(nameeidt,1,1);
    grid->addWidget(userage,2,0);
    grid->addWidget(ageedit,2,1);
    grid->addWidget(usersex,3,0);
    grid->addWidget(sexcombox,3,1);
    grid->addWidget(userdepart,4,0);
    grid->addWidget(departedit,4,1);

    //个人简历
    indivatual_information=new QLabel("个人简历");
    infor=new QTextEdit;
    vb=new QVBoxLayout;
    vb->addWidget(indivatual_information);
    vb->addWidget(infor);
    //按钮
    surebtn=new QPushButton("ok");
    cancelbtn=new QPushButton("cancel");
    hb=new QHBoxLayout;
    hb->addStretch();
    hb->addWidget(cancelbtn);
    hb->addWidget(surebtn);
    //
    algrid=new QGridLayout(this);
    algrid->addLayout(grid,0,0);
    algrid->addLayout(vb,0,1);
    algrid->addLayout(hb,1,0,1,2);

}

Dialog::~Dialog() = default;

image-20260607123557668

stackwidget

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QListWidget>
#include <QStackedWidget>
#include <QLabel>
#include <QHBoxLayout>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QListWidget* list;
    QStackedWidget* stack;
    QLabel* lb1,*lb2,*lb3,*lb4;
    QHBoxLayout* hb;
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle("堆栈窗口");
    list=new QListWidget;
    list->addItem("linux1");
    list->addItem("linux2");
    list->addItem("linux3");
    list->addItem("linux4");
    list->addItem("linux5");

    lb1=new QLabel("linux1 qt");

    stack=new QStackedWidget;
    stack->addWidget(lb1);

    hb=new  QHBoxLayout;
    hb->addWidget(list);
    hb->addWidget(stack,0,Qt::AlignCenter);
    hb->setStretchFactor(list,1);
    hb->setStretchFactor(stack,5);
    setLayout(hb);
}

Dialog::~Dialog() = default;

[!warning]

stackedwidget一次只能显示一个控件

image-20260607125117295

splitter

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSplitter>
#include <QTextEdit>

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
    QSplitter *split,*righsplit;
    QTextEdit* leftedit,*righteditup,*righteditdown;
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    split=new QSplitter(Qt::Horizontal,0);
    leftedit=new QTextEdit("左窗口",split);

    righsplit=new QSplitter(Qt::Vertical,split);
    righteditup=new QTextEdit("有上窗口",righsplit);
    righteditdown=new QTextEdit("有下窗口",righsplit);
    split->show();
}

MainWindow::~MainWindow() = default;

image-20260607131640254

dockWidget 停靠窗口

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextEdit>
#include <QDockWidget>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
    void DockWidgetFn();
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    DockWidgetFn();
}

MainWindow::~MainWindow() = default;

void MainWindow::DockWidgetFn()
{
    setWindowTitle("widget测试");
    QTextEdit *maintext=new QTextEdit;
    maintext->setAlignment(Qt::AlignCenter);
    //将maintext设置为主窗体的中央窗体
    setCentralWidget(maintext);
    QDockWidget* dwt1=new QDockWidget("停靠窗口1",this);
    dwt1->setFeatures(QDockWidget::DockWidgetMovable);
    dwt1->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
    QTextEdit* edit=new QTextEdit;
    dwt1->setWidget(edit);

    addDockWidget(Qt::RightDockWidgetArea,dwt1);
    QDockWidget * dwt2=new QDockWidget("停靠窗口2",this);
    QTextEdit* ed=new QTextEdit;
    dwt2->setWidget(ed);
    dwt2->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable);
     addDockWidget(Qt::RightDockWidgetArea,dwt2);
}

image-20260607134012234

QDialog

QFileDialog

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFileDialog>

class Dialog : public QDialog
{
    Q_OBJECT

private:
    QPushButton *openfile,*getsize;
    QLabel* filename,*lb2;
    QHBoxLayout* hb,*hb2;
    QVBoxLayout* vb;
    QLineEdit* edit,*filesize;
private slots:
    void openfilepath();
    void getsizefile();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    hb=new QHBoxLayout;
    hb2=new QHBoxLayout;
    vb=new QVBoxLayout(this);

    filename=new QLabel("文件名称");
    edit=new QLineEdit;
    openfile=new QPushButton("选择..");

    lb2=new QLabel("文件大小");
    filesize=new QLineEdit;

    getsize=new QPushButton("获取文件大小");

    hb->addWidget(filename);
    hb->addWidget(edit);
    hb->addWidget(openfile);

    hb2->addWidget(lb2);
    hb2->addWidget(filesize);
    vb->addLayout(hb);
    vb->addLayout(hb2);
    vb->addWidget(getsize);
    connect(openfile,&QPushButton::clicked,this,&Dialog::openfilepath,Qt::UniqueConnection);
    connect(getsize,&QPushButton::clicked,this,&Dialog::getsizefile);
}

Dialog::~Dialog() = default;
void Dialog::openfilepath()
{
    //打开文件
    QString strfile=QFileDialog::getOpenFileName(this,"打开文件","/","Files(*)");
    edit->setText(strfile);
}

void Dialog::getsizefile()
{
    QString strpath=edit->text();
    //获取文件信息
    QFileInfo fileinfo(strpath);
    qint64 filesizes=fileinfo.size();
    filesize->setText(QString::number(filesizes));
}

image-20260607144210483

colordialog

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QColorDialog>
#include <QFrame>
#include <QGridLayout>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QGridLayout* grid;
    QPushButton* btn;
    QFrame* colorFrame;
private slots:
    void displaycolor();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"


Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    grid=new QGridLayout(this);
    btn=new QPushButton("打开颜色对话框");
    colorFrame=new QFrame;
    colorFrame->setFrameShape(QFrame::Box);
    colorFrame->setAutoFillBackground(true);
    grid->addWidget(btn,0,0);
    grid->addWidget(colorFrame,1,0);
    connect(btn,&QPushButton::clicked,this,&Dialog::displaycolor);
}

Dialog::~Dialog() = default;
void Dialog::displaycolor()
{
    QColor color=QColorDialog::getColor(Qt::blue);
    if(color.isValid())
    {
        colorFrame->setPalette(QPalette(color));
    }
}

image-20260607145701062

fontdialog

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QLineEdit>
#include <QFontDialog>
#include <QGridLayout>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QPushButton* fontbtn;
    QLineEdit* fontedit;
    QGridLayout* grid;
private slots:
    void displayfont();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H


#include "dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    grid=new QGridLayout(this);
    fontbtn=new QPushButton("打开字体对话框");
    fontedit=new QLineEdit;
    fontedit->setText("测试");

    grid->addWidget(fontbtn,0,0);
    grid->addWidget(fontedit,0,1);
    connect(fontbtn,&QPushButton::clicked,this,&Dialog::displayfont);
}

Dialog::~Dialog() = default;
void Dialog::displayfont()
{
    bool flag;
    QFont font=QFontDialog::getFont(&flag);
    if(flag)
    {
        fontedit->setFont(font);
    }
}

image-20260607151644928

inputdialog

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
//输入框
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
#include <QGridLayout>
#include <QPushButton>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QGridLayout* grid;
    QPushButton* namebtn,*numberbtn,*sexbtn,*agebtn;
    QLineEdit* nameedit,*numberedit,*sexedit,*ageedit;
private slots:
    void showname();
    void shownumber();
    void showsex();
    void showage();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    grid=new QGridLayout(this);
    namebtn=new QPushButton("学生名称");
    nameedit=new QLineEdit("张三");

    numberbtn=new QPushButton("学生编号");
    numberedit=new QLineEdit("135465");

    sexbtn=new QPushButton("学生性别");
    sexedit=new QLineEdit("男");

    agebtn=new QPushButton("学生年龄");
    ageedit=new QLineEdit("18");
    grid->addWidget(namebtn,0,0);
    grid->addWidget(nameedit,0,1);
    grid->addWidget(numberbtn,1,0);
    grid->addWidget(numberedit,1,1);
    grid->addWidget(sexbtn,2,0);
    grid->addWidget(sexedit,2,1);
    grid->addWidget(agebtn,3,0);
    grid->addWidget(ageedit,3,1);
    connect(namebtn,&QPushButton::clicked,this,&Dialog::showname);
    connect(numberbtn,&QPushButton::clicked,this,&Dialog::shownumber);
    connect(sexbtn,&QPushButton::clicked,this,&Dialog::showsex);
    connect(agebtn,&QPushButton::clicked,this,&Dialog::showage);
}

Dialog::~Dialog() = default;
void Dialog::showname()
{
    bool flag;
   QString str= QInputDialog::getText(this,"输入对话框","请输入姓名",QLineEdit::Normal,nameedit->text(),&flag);
    if(!str.isEmpty()&&flag)
   {
        nameedit->setText(str);
   }
}

void Dialog::shownumber()
{
    bool flag;
    QString nu=QInputDialog::getText(this,"输入对话框","请输入编号",QLineEdit::Normal,numberedit->text(),&flag);
    if(flag&&!nu.isEmpty())
    {
        numberedit->setText(nu);
    }
}

void Dialog::showsex()
{
    QStringList sexlist;
    sexlist<<"男"<<"女";
    bool flag;
    QString nu=QInputDialog::getItem(this,"输入对话框","请输入性别", sexlist,0,false,&flag);
    if(flag&&!nu.isEmpty())
    {
        sexedit->setText(nu);
    }
}

void Dialog::showage()
{
    bool flag;
    QString nu=QInputDialog::getText(this,"输入对话框","请输入年龄",QLineEdit::Normal,ageedit->text(),&flag);
    if(flag&&!nu.isEmpty())
    {
        ageedit->setText(nu);
    }
}

image-20260607203633311

messagebox

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QGridLayout>
#include <QMessageBox>
#include <QLabel>

QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QLabel* mess;
    QGridLayout* grid;
    QPushButton* questbtn,*inforbtn,*warningbtn,*criticlbtn,*aboutbtn,*aboutqtbtn;

private slots:
    void showquest();
    void showinfor();
    void showwarning();
    void showcriticl();
    void showabout();
    void showaboutqt();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;

private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

#include "dialog.h"
#include "ui_dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    resize(300,200);
    grid=new QGridLayout(this);
    mess=new QLabel("请选择一个消息框");
    questbtn=new QPushButton("问题消息框");
    inforbtn=new QPushButton("信息消息框");
    warningbtn=new QPushButton("警告消息框");
    criticlbtn=new QPushButton("错误消息框");
    aboutbtn=new QPushButton("关于消息框");
    aboutqtbtn=new QPushButton("关于qt消息框");
    grid->addWidget(mess,0,0);
    grid->addWidget(questbtn,1,0);
    grid->addWidget(inforbtn,2,0);
    grid->addWidget(warningbtn,3,0);
    grid->addWidget(criticlbtn,4,0);
    grid->addWidget(aboutbtn,5,0);
    grid->addWidget(aboutqtbtn,6,0);
    connect(questbtn,&QPushButton::clicked,this,&Dialog::showquest);
    connect(inforbtn,&QPushButton::clicked,this,&Dialog::showinfor);
    connect(warningbtn,&QPushButton::clicked,this,&Dialog::showwarning);
    connect(criticlbtn,&QPushButton::clicked,this,&Dialog::showcriticl);
    connect(aboutbtn,&QPushButton::clicked,this,&Dialog::showabout);
    connect(aboutqtbtn,&QPushButton::clicked,this,&Dialog::showaboutqt);
}

Dialog::~Dialog()
{
    delete ui;
}
void Dialog::showquest()
{
    mess->setText("问题消息框");
    switch(QMessageBox::question(this,"问题消息","是否退出应用程序?",QMessageBox::Ok|QMessageBox::Cancel))
    {
    case QMessageBox::Ok:
        mess->setText("你选择了问题消息框");
        break;
    case QMessageBox::Cancel:
        mess->setText("你选择退出问题消息框");
        break;
    default:
        break;
    }
}

void Dialog::showinfor()
{
    mess->setText("信息消息框");
    switch(QMessageBox::information(this,"信息消息","是否退出应用程序?",QMessageBox::Ok|QMessageBox::Cancel))
    {
    case QMessageBox::Ok:
        mess->setText("你选择了信息消息框");
        break;
    case QMessageBox::Cancel:
        mess->setText("你选择退出信息消息框");
        break;
    default:
        break;
    }
}

void Dialog::showwarning()
{
    mess->setText("警告消息框");
    switch(QMessageBox::warning(this,"警告消息","是否退出应用程序?",QMessageBox::Ok|QMessageBox::Cancel))
    {
    case QMessageBox::Ok:
        mess->setText("你选择了警告消息框");
        break;
    case QMessageBox::Cancel:
        mess->setText("你选择退出问题警告框");
        break;
    default:
        break;
    }
}

void Dialog::showcriticl()
{
    mess->setText("错误消息框");
    switch(QMessageBox::critical(this,"错误消息","是否退出应用程序?",QMessageBox::Ok|QMessageBox::Cancel))
    {
    case QMessageBox::Ok:
        mess->setText("你选择了错误消息框");
        break;
    case QMessageBox::Cancel:
        mess->setText("你选择退出错误消息框");
        break;
    default:
        break;
    }
}

void Dialog::showabout()
{
    mess->setText("关于消息框");
    QMessageBox::about(this,"关于消息","是否退出应用程序?");
}

void Dialog::showaboutqt()
{
    mess->setText("关于qt消息框");
    QMessageBox::aboutQt(this,"关于qt消息");
}

image-20260607210832658

自定义消息框

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QGridLayout>
#include <QMessageBox>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QLabel*lb,*disp;
    QPushButton*btn;
    QGridLayout*grid;
private slots:
    void custommes();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    grid=new QGridLayout(this);
    lb=new QLabel("自定义消息框");
    btn=new QPushButton("测试操作");
    disp=new QLabel("未测试状态");
    grid->addWidget(lb,0,0);
    grid->addWidget(btn,0,1);
    grid->addWidget(disp,1,0,1,1);
    connect(btn,&QPushButton::clicked,this,&Dialog::custommes);
}

Dialog::~Dialog() = default;
void Dialog::custommes()
{
    QMessageBox mymesbo;
    mymesbo.setWindowTitle("自定义");
    QPushButton* mybtn=mymesbo.addButton("YES",QMessageBox::ActionRole);
    QPushButton* no=mymesbo.addButton("NO",QMessageBox::ActionRole);

    mymesbo.setIconPixmap(QPixmap("/home/study/Pictures/图片/3.jpeg"));
    mymesbo.exec();
    if(mymesbo.clickedButton()==mybtn)
    {
        disp->setText("点击yes");
    }else if(mymesbo.clickedButton()==no)
    {
        disp->setText("点击no");
    }
}

image-20260608092608734

绘图原理双缓存机制

常用窗口api函数

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QGridLayout>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QGridLayout* grid;
    QLabel*geometrylb,*geometry_value;
    QLabel*geometry_width,*geometry_val_width,*geometry_height,*geometry_val_height;
    QLabel*geometry_rect,*geometry_val_rect,*geometry_size,*geometry_val_size;
private slots:
    void resizeEvent(QResizeEvent*);
    void moveEvent(QMoveEvent*);
public:
    void updatedata();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(300,160);
    grid=new QGridLayout(this);
    geometrylb=new QLabel("Geometry():");
    geometry_value=new QLabel;

    geometry_width=new QLabel("宽度:");
    geometry_val_width=new QLabel;
    geometry_height=new QLabel("高度");
    geometry_val_height=new QLabel;

    geometry_rect=new QLabel("rect():");
    geometry_val_rect=new QLabel;
    geometry_size=new QLabel("size:");
    geometry_val_size=new QLabel;

    grid->addWidget(geometrylb,0,0);
    grid->addWidget(geometry_value,0,1);
    grid->addWidget(geometry_width,1,0);
    grid->addWidget(geometry_val_width,1,1);
    grid->addWidget(geometry_height,2,0);
    grid->addWidget(geometry_val_height,2,1);
    grid->addWidget(geometry_rect,3,0);
    grid->addWidget(geometry_val_rect,3,1);
    grid->addWidget(geometry_size,4,0);
    grid->addWidget(geometry_val_size,4,1);
    updatedata();

}

Dialog::~Dialog() = default;
void Dialog::resizeEvent(QResizeEvent *)
{
    updatedata();
}

void Dialog::moveEvent(QMoveEvent *)
{
     updatedata();
}

void Dialog::updatedata()
{
    QString Geometry,str1,str2,str3,str4;
    Geometry=str1.setNum(geometry().x())+","+str2.setNum(geometry().y())+","+
                           str3.setNum(geometry().width())+","+str4.setNum(geometry().height());
    geometry_value->setText(Geometry);

    QString rects,strrect1,strrect2,strrect3,strrect4;
    rects=strrect1.setNum(rect().x())+","+strrect2.setNum(rect().y())+","+
               strrect3.setNum(rect().width())+","+strrect4.setNum(rect().height());
    geometry_val_width->setText(QString::number(geometry().width()));
    geometry_val_height->setText(QString::number(geometry().height()));
    geometry_val_rect->setText(rects);
    geometry_val_size->setText(QString::number(size().width())+","+QString::number(size().height()));

}

image-20260608110352221

Painter

#ifndef PAINTERAREA_H
#define PAINTERAREA_H

#include <QWidget>
#include <QPainter>
//画笔(基本的图形对象,如直线,矩形,多边形等)
#include <QPen>
//画刷(基本的图形对象,如直线,矩形,多边形等)主要用于填充对象
#include <QBrush>

class PainterArea : public QWidget
{
    Q_OBJECT
public:
    explicit PainterArea(QWidget *parent = nullptr);
    enum shape
    {
        Line,rectangle,circle
    };
    void setShap(shape);
    void setPen(QPen);
    void setBrush(QBrush);
    void paintEvent(QPaintEvent*);
    void setfillrule(Qt::FillRule);

private:
    shape sh;
    QPen pen;
    QBrush brs;
    Qt::FillRule fillrule;

signals:
};

#endif // PAINTERAREA_H

#include "painterarea.h"

PainterArea::PainterArea(QWidget *parent)
    : QWidget{parent}
{
    setPalette(QPalette(Qt::white));
    setAutoFillBackground(true);
    setMinimumSize(410,410);
}

void PainterArea::setShap(shape s)
{
    sh=s;
    update();
}

void PainterArea::setPen(QPen p)
{
    pen=p;
    update();
}

void PainterArea::setBrush(QBrush b)
{
    brs=b;
    update();
}

void PainterArea::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    //pen.setBrush(brs);
    p.setPen(pen);
    p.setBrush(brs);

    QRect rec(55,110,290,180);
    switch (sh) {
    case Line:
        p.drawLine(rec.topLeft(),rec.bottomRight());
        break;
    case rectangle:
        p.drawRect(rec);
        break;
    case circle:
        p.drawEllipse(rec);
    default:
        break;
    }

}

void PainterArea::setfillrule(Qt::FillRule f)
{
    fillrule=f;
    update();
}

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QGridLayout>
#include <QComboBox>
#include "painterarea.h"
#include <QColorDialog>
#include <QDebug>
#include <QHBoxLayout>

class Widget : public QWidget
{
    Q_OBJECT
private:
    PainterArea *paintare;
    QLabel *shlb;
    QComboBox* shapecommbox;
    QGridLayout* grid;
    QHBoxLayout* hb;
private slots:
   void displayShape(int);
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
};
#endif // WIDGET_H

#include "widget.h"



Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    grid=new QGridLayout;
    paintare=new PainterArea;
    shlb=new QLabel("形状");
    shapecommbox=new QComboBox;
    shapecommbox->addItem("Line",PainterArea::Line);
    shapecommbox->addItem("Rectangle",PainterArea::rectangle);
    shapecommbox->addItem("Circle",PainterArea::circle);
    grid->addWidget(shapecommbox,0,1);
    grid->addWidget(shlb,0,0);
    hb=new QHBoxLayout(this);
    hb->addWidget(paintare);
    hb->addLayout(grid);
    connect(shapecommbox,&QComboBox::currentIndexChanged,this,&Widget::displayShape);
}

Widget::~Widget() = default;
void Widget::displayShape(int indx)
{

    PainterArea::shape sh=PainterArea::shape(shapecommbox->itemData(indx).toInt());
    paintare->setShap(sh);
    QColor color=QColorDialog::getColor(Qt::blue);
    QBrush brsh(color);
    // paintare->setBrush(static_cast<QBrush>(color));
    paintare->setBrush(brsh);

}

image-20260608140443756

双缓存机制

#ifndef DRAWWIDGETS_H
#define DRAWWIDGETS_H

#include <QWidget>
#include <QtGui>
//鼠标事件
#include <QMouseEvent>
//绘画事件
#include <QPaintEvent>
//窗体大小改变重绘设置
#include <QResizeEvent>
//显示图像
#include <QPixmap>
#include <QColor>
//画笔
#include <QPainter>
#include <QPen>
//颜色相关
#include <QPalette>
#include <QDebug>
class DrawWidgetS : public QWidget
{
    Q_OBJECT
public:
    explicit DrawWidgetS(QWidget *parent = nullptr);

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    //绘制事件
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
signals:
private:
    //用于显示图像而设计和优化的
    QPixmap* pix;
    QPoint startPoint,endPoint;
    int style,widths;
    QColor color;
public slots:
    void setStyle(int);
    void setWidth(int);
    void setColor(QColor);
    void clearAll();
};

#endif // DRAWWIDGETS_H

#include "drawwidgets.h"

DrawWidgetS::DrawWidgetS(QWidget *parent)
    : QWidget{parent}
{
    setPalette(QPalette(Qt::white));
    setAutoFillBackground(true);
    pix=new QPixmap(size());
    pix->fill(Qt::white);
    //设置绘制区域大小
    setMinimumSize(600,400);
}

void DrawWidgetS::mousePressEvent(QMouseEvent *event)
{
    //开始位置为鼠标当前位置
    // 【关键修复】必须判断是鼠标左键才记录起点
    if (event->button() == Qt::LeftButton) {
        startPoint = event->pos();
    }
}

void DrawWidgetS::mouseMoveEvent(QMouseEvent *event)
{
    // 【关键修复】必须检查左键是否处于按下状态
    // Linux 下如果不加这个,鼠标划过都会触发逻辑,导致 startPoint 被错误更新
    if (!(event->buttons() & Qt::LeftButton)) {
        return;
    }

    //初始化绘画
    QPainter painter(pix);
    //初始化画笔
    QPen pen;
    Qt::PenStyle currentStyle = static_cast<Qt::PenStyle>(style);
    qDebug()<<currentStyle;
    if (currentStyle == Qt::NoPen && widths > 0) {
        // 如果设置了宽度但样式是 NoPen,强制改为 SolidLine
        // 或者根据你的业务逻辑处理,这里假设 0 是误操作
        currentStyle = Qt::SolidLine;
    }
    //设置画笔样式
    pen.setStyle(currentStyle);
    //设置画笔宽度
    pen.setWidth(widths);
    //设置画笔颜色
    pen.setColor(color);
    //设置绘画以图片开始或者说是填充开始绘画设备
    // painter->begin(pix);
    // 4. 优化线条连接处,避免快速移动时出现断点或锯齿
    pen.setCapStyle(Qt::RoundCap);
    pen.setJoinStyle(Qt::RoundJoin);
    //设置绘画的画笔
    painter.setPen(pen);
    //画横线,从鼠标点击处开始,一直到鼠标移动到的位置
    painter.drawLine(startPoint,event->pos());
    //绘画结束
    painter.end();
    //鼠标位置更新为当前鼠标结束位置
    startPoint=event->pos();
    //重新渲染
    update();
}

void DrawWidgetS::paintEvent(QPaintEvent *event)
{
    //绘画事件,绘画位置为当前类
    QPainter painter(this);
    if (pix && !pix->isNull()) {
        painter.drawPixmap(0, 0, *pix);
    } else {
        // 如果 pix 丢失,填充背景防止花屏
        painter.fillRect(rect(), Qt::white);
    }
    // //以pixmap坐标为0,0开始绘画
    // painter.drawPixmap(QPoint(0,0),*pix);
}

void DrawWidgetS::resizeEvent(QResizeEvent *event)
{
    if(height()>pix->height()||width()>pix->width())
    {
        QPixmap *newPix=new QPixmap(size());
        newPix->fill(Qt::white);
        QPainter ps(newPix);
        ps.drawPixmap(QPoint(0,0),*pix);
        pix=newPix;
    }
    QWidget::resizeEvent(event);
}

void DrawWidgetS::setStyle(int st)
{
    style=st;
}

void DrawWidgetS::setWidth(int wid)
{
    widths=wid;
}

void DrawWidgetS::setColor(QColor colr)
{
    color=colr;
}

void DrawWidgetS::clearAll()
{
    QPixmap *pi=new QPixmap(size());
    pi->fill(Qt::white);
    pix=pi;
    update();
}

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "drawwidgets.h"
#include <QToolBar>
#include <QLabel>
#include <QComboBox>
#include <QSpinBox>
#include <QToolButton>
#include <QGridLayout>
#include <QColorDialog>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    DrawWidgetS* draww;
    QGridLayout* grid;
    QColorDialog* colodialog;
    QLabel* lbstyle,*lbwidth,lbcolor;
    QToolButton* colorbtn;
    QToolButton* clearbtn;
    QComboBox* comb;
    QSpinBox* spin;
private slots:
    void displaystyle();
    void displaycolor();
public:
    void CreatTooBar();

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    draww=new DrawWidgetS;
    draww->setColor(Qt::blue);
    setMinimumSize(600,400);
    setCentralWidget(draww);
    CreatTooBar();

}

MainWindow::~MainWindow() = default;
void MainWindow::displaystyle()
{
    draww->setStyle(comb->itemData(comb->currentIndex(),Qt::UserRole).toInt());
}

void MainWindow::displaycolor()
{
  QColor color= QColorDialog::getColor(Qt::black,this);
  if(color.isValid())
  {
      draww->setColor(color);
      QPixmap pix(20,20);
      pix.fill(color);
      colorbtn->setPalette(QPalette(color));
 }

}

void MainWindow::CreatTooBar()
{
    QToolBar *toolb=addToolBar("Tool");
    lbstyle=new QLabel("线形风格");
    comb=new QComboBox;
    comb->addItem("SolidLIne",static_cast<int>(Qt::SolidLine));
    comb->addItem("DotLine",static_cast<int>(Qt::DotLine));
    connect(comb,&QComboBox::activated,this,&MainWindow::displaystyle);
    lbwidth=new QLabel("线宽");
    spin=new QSpinBox;
    spin->setValue(5);
    spin->setSingleStep(1);
    spin->setRange(1,100);
    draww->setWidth(spin->value());
    connect(spin,&QSpinBox::valueChanged,draww,&DrawWidgetS::setWidth);
    colorbtn=new QToolButton;
    colorbtn->setAutoFillBackground(true);
    colorbtn->setPalette(QPalette(Qt::blue));
    QPixmap pixmap(20,20);
    pixmap.fill(Qt::black);
    connect(colorbtn,&QToolButton::clicked,this,&MainWindow::displaycolor);

    clearbtn=new QToolButton;
    clearbtn->setText("清除配置");
    connect(clearbtn,&QToolButton::clicked,draww,&DrawWidgetS::clearAll);
    toolb->addWidget(lbstyle);
    toolb->addWidget(comb);
    toolb->addWidget(lbwidth);
    toolb->addWidget(spin);
    toolb->addWidget(colorbtn);
    toolb->addWidget(clearbtn);

}

image-20260609071418624

graphicsview

#ifndef MYGRAPHICSITEM_H
#define MYGRAPHICSITEM_H

#include <QGraphicsItem>
//用于显示图像
#include <QPixmap>
//引入颜色
#include <QPainter>
class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(QPixmap *pixm);
private:
    QPixmap pix;
public:
    //只刷新固定区域,用于返回调整实际物体所在位置包含区域
    QRectF boundingRect() const;
    //绘图操作
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

#endif // MYGRAPHICSITEM_H

#include "mygraphicsitem.h"

MyGraphicsItem::MyGraphicsItem(QPixmap *pixm):pix(*pixm)
{

}
/**
 * @brief MyGraphicsItem::boundingRect
 * @return
 */
QRectF MyGraphicsItem::boundingRect() const
{
    return QRectF(-2-pix.width()/2,-2-pix.height()/2,pix.width()+4,pix.height()+4);
}
/**
 * @brief MyGraphicsItem::paint
 * @param painter
 * @param option
 * @param widget
 */
void MyGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawPixmap(-pix.width()/2,-pix.height()/2,pix);
}

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QFrame>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QSlider>

#include "mygraphicsitem.h"
#include <math.h>
#include <QDebug>

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
public:
    void creatControl();
private:
    int angle;
    qreal scalevalue;
    MyGraphicsItem* mygraphicsitem;
    //倾斜
    qreal leanvalue;
    QGraphicsView* view;
    QFrame* fram;
    QPixmap* pixmap;
    QSlider *angles,*scaling,*leans;
private slots:
    void rotalangle(int);
    void scaleproportion(qreal);
    void leanfn(qreal);
};
#endif // WIDGET_H

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("图形视图框架");
    angle=0;
    scalevalue=2;
    leanvalue=2;
    QGraphicsScene *scene=new QGraphicsScene;
    scene->setSceneRect(-200,-200,380,380);
    QPixmap *pixm=new QPixmap("/home/study/Pictures/图片/4.webp");
    //将图片添加到图源中
    mygraphicsitem=new  MyGraphicsItem(pixm);
    //将图源添加到场景中
    scene->addItem(mygraphicsitem);
    //设置坐标
    mygraphicsitem->setPos(0,0);
    //创建视图
    view=new QGraphicsView;
    //将场景添加到视图中
    view->setScene(scene);
    //设置视图大小
    view->setMinimumSize(800,600);

    fram=new QFrame;
    creatControl();

    QHBoxLayout *hb=new QHBoxLayout;
    hb->addWidget(view);
    hb->addWidget(fram);
    setLayout(hb);

}

Widget::~Widget() = default;

void Widget::creatControl()
{
    angles=new QSlider;
    angles->setOrientation(Qt::Horizontal);
    angles->setRange(0,360);

    QHBoxLayout *rotatel=new QHBoxLayout;
    rotatel->addWidget(angles);

    QGroupBox *rotateg=new QGroupBox("图形旋转");
    rotateg->setLayout(rotatel);
    connect(angles,&QSlider::valueChanged,this,&Widget::rotalangle);

    //
    scaling=new QSlider;
    scaling->setOrientation(Qt::Horizontal);
    scaling->setRange(0,2*scalevalue);
    scaling->setValue(scalevalue);

    QHBoxLayout *scalel=new QHBoxLayout;
    scalel->addWidget(scaling);

    QGroupBox *scaleg=new QGroupBox("图形缩放");
    scaleg->setLayout(scalel);
    connect(scaling,&QSlider::valueChanged,this,&Widget::scaleproportion);

    //
    leans=new QSlider;
    leans->setOrientation(Qt::Horizontal);
    leans->setRange(0,2*leanvalue);
    leans->setValue(leanvalue);

    QHBoxLayout *leansl=new QHBoxLayout;
    leansl->addWidget(leans);

    QGroupBox *leansg=new QGroupBox("图形倾斜");
    leansg->setLayout(leansl);
    connect(leans,&QSlider::valueChanged,this,&Widget::leanfn);

    QVBoxLayout *vb=new QVBoxLayout;
    vb->addWidget(rotateg);
    vb->addWidget(scaleg);
    vb->addWidget(leansg);
    fram->setLayout(vb);
}

void Widget::rotalangle(int val)
{
    view->rotate(val-angle);
    angle=val;
}

void Widget::scaleproportion(qreal val)
{
    qreal qs;
    if(val>scalevalue)
    {
        qs=pow(1.1,(val-scalevalue));
    }
    else
    {
        qs=pow(1/1.1,(scalevalue-val));
    }
    view->scale(qs,qs);
    scalevalue=val;
}

void Widget::leanfn(qreal val)
{
    view->shear((val-leanvalue)/2,0);
    leanvalue=val;
}

image-20260609110443674

Model_View_Delegate

Model

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QAbstractItemModel>
#include <QAbstractItemView>

#include <QSplitter>
#include <QFileSystemModel>
#include <QTreeView>
#include <QListView>
#include <QTableView>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // MainWindow w;
    // w.show();

    QFileSystemModel model;
    model.setRootPath(QDir::currentPath());
    QTreeView treeview;
    QListView listview;
    QTableView tableview;
    //设置模型数据
    treeview.setModel(&model);
    listview.setModel(&model);
    tableview.setModel(&model);

    treeview.setSelectionMode(QAbstractItemView::MultiSelection);
    listview.setSelectionModel(treeview.selectionModel());
    tableview.setSelectionModel(treeview.selectionModel());

    QObject::connect(&treeview,&QTreeView::doubleClicked,&listview,&QListView::setRootIndex);
    QObject::connect(&treeview,&QTreeView::doubleClicked,&tableview,&QTableView::setRootIndex);

    QSplitter * sp=new QSplitter;
    sp->addWidget(&treeview);
    sp->addWidget(&listview);
    sp->addWidget(&tableview);
    sp->show();
    return QApplication::exec();
}

image-20260609191010434

#ifndef MODEEXPEND_TABLE_H
#define MODEEXPEND_TABLE_H

#include <QAbstractTableModel>
#include <QVector>
#include <QStringList>
#include <QMap>


class modeexpend_table : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit modeexpend_table(QObject *parent = nullptr);
private:
    QVector<short> empindex;
    QVector<short> empnameindex;
    QVector<short> emppartindex;
    QStringList list;
    QMap<short,QString> empid;
    QMap<short,QString> empname;
    QMap<short,QString> emppart;

private slots:
    void Modelfn();

    // QAbstractItemModel interface
public:
    virtual int rowCount(const QModelIndex &parent=QModelIndex()) const;
    virtual int columnCount(const QModelIndex &parent=QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
};

#endif // MODEEXPEND_TABLE_H

#include "modeexpend_table.h"

modeexpend_table::modeexpend_table(QObject *parent)
    : QAbstractTableModel{parent}
{
    empid[1]="202201";
    empid[2]="202202";
    empid[3]="202203";
    empid[4]="202204";
    empid[5]="202205";
    empname[1]="张三";
    empname[2]="李四";
    empname[3]="王五";
    empname[4]="赵六";
    empname[5]="孙犁";
    emppart[1]="研发部";
    emppart[2]="财务部";
    emppart[3]="后情部";
    emppart[4]="销售部";
    emppart[5]="管理部";
    Modelfn();

}

void modeexpend_table::Modelfn()
{
    list<<"员工编号"<<"员工姓名"<<"部门";
    empindex<<1<<2<<3<<4<<5;
    empnameindex<<1<<2<<3<<4<<5;
    emppartindex<<1<<2<<3<<4<<5;
}

int modeexpend_table::rowCount(const QModelIndex &parent) const
{
    return empindex.size();
}

int modeexpend_table::columnCount(const QModelIndex &parent) const
{
    return 3;
}

QVariant modeexpend_table::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
    {
        return QVariant();
    }
    if(role==Qt::DisplayRole)
    {
        switch(index.column())
        {
        case 0:
            return empid[empindex[index.row()]];
            break;
        case 1:
            return empname[empnameindex[index.row()]];
            break;
        case 2:
            return emppart[emppartindex[index.row()]];
            break;
        default:
            return QVariant();
        }
    }
    return QVariant();
}

QVariant modeexpend_table::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role==Qt::DisplayRole&&orientation==Qt::Horizontal)
    {
        return list[section];
    }
    return QAbstractTableModel::headerData(section,orientation,role);
}

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "modeexpend_table.h"
#include <QTableView>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //MainWindow w;
    //w.show();
    modeexpend_table expendtable;
    QTableView view;
    view.setModel(&expendtable);
    view.setWindowTitle("model类型扩展测试");
    view.resize(500,300);
    view.show();
    return QApplication::exec();
}

image-20260609203313169

文件操作

读写文本文件(QFile)

#include <QCoreApplication>
#include <QFile>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //打开相应文件
    QFile file("/home/study/test.txt");
    //设置文件打开后的方式是只读还是能写以及是文本还是其他类型
    bool flag=file.open(QIODevice::Text|QIODevice::WriteOnly);
    if(!flag)
    {
        qDebug()<<"打开文件失败!";
    }
    else {
        qDebug()<<"打开文件成功!";
        file.write("测试文本");
        file.close();
    }
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        qDebug()<<"打开文件失败!";
    }
    else{
    //设置缓存
    char* byte=new char[1024];
    //将文件内容读取到缓冲区域中,并返回剩余的字节数
    qint64 count=file.readLine(byte,1024);
    while((count!=0)&&(count!=-1))
    {
        qDebug()<<byte;
        count=file.readLine(byte,1024);
    }
    file.close();
    }
    return QCoreApplication::exec();
}

image-20260610120939683

读写二进制

#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //一维数组
    qint32 qnumb[3]={1,2,3};
    //创建字节数组
    QByteArray byte;
    //设置字节数组大小,大小由要写入的内容决定
    byte.resize(sizeof(qnumb));

    for(int i=0;i<3;i++)
    {
        memcpy(byte.data()+i*sizeof(qint32),&qnumb[i],sizeof(qint32));
    }
    //打开test文件
    QFile file("/home/study/test.dat");
    //设置设备模式

    bool flag=file.open(QIODevice::WriteOnly);
    if(!flag)
    {
        qDebug()<<"打开文件失败!";
    }
    else {
        qDebug()<<"打开文件成功!";
        file.write(byte);
        file.close();
    }
    //读取数据
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"打开势必";
    }else
    {
        QByteArray readbyte;
        readbyte=file.readAll();
        qDebug()<<"byte:"<<readbyte;

        //将二进制数据转换成char字符类型
        const char* cha=readbyte.constData();
        while(*cha)
        {
            //将char转换成qint32指针并解引用将值输出
            qDebug()<<*(qint32*)cha;
            cha=cha+sizeof(qint32);
        }
        file.close();
    }

    return QCoreApplication::exec();
}

image-20260610121144531

读写二进文本文件

  • QTextSteam:用于读取文本文件
  • QDataSteam:用于读取二进字文件

TextStream


#include <QCoreApplication>

#include <QFile>
#include <QDebug>
#include <QTextStream>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file("/home/study/test.txt");
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug()<<"打开文件是失败";
    }
    else
    {
        qDebug()<<"打开文件成功";
        //将文本以文本文件流形式打开
        QTextStream stream(&file);
        stream<<"QTextStream学习";
        file.close();
    }
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"打开文件是失败";
    }
    else
    {
        qDebug()<<"打开文件成功";
        //将文本以文本文件流形式打开
        QTextStream stream(&file);
        while(!stream.atEnd())
        {
            qDebug()<<stream.readLine();
        }
        file.close();
    }
    return QCoreApplication::exec();
}

image-20260610122139476

DataStream


#include <QCoreApplication>
#include <QFile>
#include <QDebug>
#include <QDataStream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qint64 numb64[3]={1,2,3};
    QFile file("/home/study/binary.dat");
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug()<<"打开二进制文件失败";
    }
    else
    {
        qDebug()<<"打开二进制文件成功,正在写入数据。。。";
        QByteArray byte;
        byte.resize(sizeof(numb64));
        for(int i=0;i<3;i++)
        {
            memcpy(byte.data()+i*sizeof(qint64),&numb64[i],sizeof(qint64));
        }
        file.write(byte);
        file.close();
    }
    //读取二进制文件
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"打开二进制文件失败";
    }
    else
    {
        qDebug()<<"打开二进制文件成功,正在读取数据。。。";
        //将二进制文件内容读取到数据流中
        QDataStream dstream(&file);
         qint64 readArray[3];
        dstream.readRawData(reinterpret_cast<char*>(readArray),sizeof(readArray));
         for(int i=0;i<3;i++)
        {
            qDebug()<<readArray[i];
         }
        file.close();
    }
    return QCoreApplication::exec();
}

image-20260610132755724

Dir

#include <QCoreApplication>

#include <QDir>
#include <QStringList>
#include <QtDebug>
qint64 GetDirFileInfo(const QString &path);
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString path;
    path=QDir::currentPath();
    qDebug()<<"当前目录"<<path;
    GetDirFileInfo(path);
    return QCoreApplication::exec();
}
qint64 GetDirFileInfo(const QString &path)
{
    QDir dir(path);
    qint64 size=0;
    foreach (QFileInfo info, dir.entryInfoList(QDir::Files)) {
        size=size+info.size();
    }
    foreach (QString di, dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot)) {
        size=size+GetDirFileInfo(path+QDir::separator()+di);
    }
    char uint='B';
    qint64 currentdirsize=size;
    if(currentdirsize>1024)
    {
        currentdirsize=currentdirsize/1024;
        uint='K';
        if(currentdirsize>1024)
        {
             currentdirsize=currentdirsize/1024;
             uint='M';
             if(currentdirsize>1024)
             {
                 currentdirsize=currentdirsize/1024;
                 uint='G';
                 if(currentdirsize>1024)
                 {
                     currentdirsize=currentdirsize/1024;
                     uint='T';
                 }
             }
        }
    }
    qDebug()<<"目录空间大小:"<<currentdirsize<<uint<<"\t"<<qPrintable(path);
    return size;

}

image-20260610150037819

综合实践

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QListWidget>
#include <QLineEdit>
#include <QDir>
#include <QListWidgetItem>
#include <QVBoxLayout>
//用于获取文件信息
#include <QFileInfoList>

class Dialog : public QDialog
{
    Q_OBJECT

private:
    QLineEdit *edit;
    QVBoxLayout* vb;
    QListWidget* listw;
public:
    void showFileInforList(QFileInfoList list);
public slots:
    void showDir(QDir dir);
    void showDirall(QListWidgetItem* listwi);
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"


Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(500,500);
    setWindowTitle("文件dir控件综合应用");
    edit=new QLineEdit("/");
    listw=new QListWidget;

    vb=new QVBoxLayout(this);
    vb->addWidget(edit);
    vb->addWidget(listw);

    //connect(edit,SIGNAL(returnPressed()),this,SLOT(showDir(QDir)));
    connect(edit,&QLineEdit::returnPressed,this,[this](){QDir dir;showDir(dir);});
    connect(listw,&QListWidget::itemDoubleClicked,this,&Dialog::showDirall);
    QString path="/";
    QDir rootPath(path);
    QStringList strlist;
    strlist<<"*";
    //过滤所有文件
    QFileInfoList info=rootPath.entryInfoList(strlist);
    showFileInforList(info);
}

Dialog::~Dialog() = default;
void Dialog::showFileInforList(QFileInfoList list)
{
    listw->clear();
    for(unsigned int i=0;i<list.count();i++)
    {
        QFileInfo tempfile=list.at(i);
        //判断是否是文件夹
        if(tempfile.isDir())
        {
            QIcon icon("/home/study/Pictures/图片/dir.png");
            QString filename=tempfile.fileName();
            QListWidgetItem *temp=new QListWidgetItem(icon,filename);
            listw->addItem(temp);
        }
        else if(tempfile.isFile())
        {
            QIcon icon("/home/study/Pictures/图片/text.png");
            QString name=tempfile.fileName();
            QListWidgetItem *tm=new QListWidgetItem(icon,name);
            listw->addItem(tm);
        }
    }

}

void Dialog::showDir(QDir dir)
{
    QStringList pathlist;
    pathlist<<"*";
    QFileInfoList info=dir.entryInfoList(pathlist,QDir::AllEntries,QDir::DirsFirst);
    showFileInforList(info);
}

void Dialog::showDirall(QListWidgetItem *listwi)
{
    QDir dir;
    QString str=listwi->text();
    dir.setPath(edit->text());
    dir.cd(str);
    edit->setText(dir.absolutePath());
    showDir(dir);
}

image-20260610155938298

fileinfo 获取文件信息

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
#include <QFileDialog>
#include <QDateTime>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QLabel* filepath,*filesize,*filecreatetime,*filemodifytime,*fileusetime,*filemanage;
    QLineEdit* pathedit,*sizeedit,*timeedit,*modifyedit,*useedit,*manageeddit;
    QPushButton *openfilebtn,*getfileallproperty;
    QCheckBox* file,*hiddenproperty,*readonlypower,*writeonlypower,*exepower;
    QGridLayout* grid;
    QVBoxLayout* vb;
    QHBoxLayout* hb;
private slots:
    void openfile();
    void getallproperty();
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
};
#endif // DIALOG_H

#include "dialog.h"



Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    filepath=new QLabel("文件路径:");
    pathedit=new QLineEdit;
    openfilebtn=new QPushButton("打开文件夹");

    filesize=new QLabel("文件大小");
    filecreatetime=new QLabel("文件创建时间");
    filemodifytime=new QLabel("文件修改时间");
    fileusetime=new QLabel("最后使用时间");
    filemanage=new QLabel("文件管理");
    sizeedit=new QLineEdit;
    timeedit=new QLineEdit;
    modifyedit=new QLineEdit;
    useedit=new QLineEdit;
    //manageeddit=new QLineEdit;
    getfileallproperty=new QPushButton("获取文件所有信息和属性");
    file=new QCheckBox("文件");
    hiddenproperty=new QCheckBox("隐藏属性");
    readonlypower=new QCheckBox("只读权限");
    writeonlypower=new QCheckBox("只写权限");
    exepower=new QCheckBox("执行权限");

    hb=new QHBoxLayout;
    grid=new QGridLayout;
    grid->addWidget(filepath,0,0);
    grid->addWidget(pathedit,0,1);
    grid->addWidget(openfilebtn,0,2);
    grid->addWidget(filesize,1,0);
    grid->addWidget(sizeedit,1,1,1,2);
    grid->addWidget(filecreatetime,2,0);
    grid->addWidget(timeedit,2,1,1,2);
    grid->addWidget(filemodifytime,3,0);
    grid->addWidget(modifyedit,3,1,1,2);
    grid->addWidget(fileusetime,4,0);
    grid->addWidget(useedit,4,1,1,2);
    grid->addWidget(filemanage,5,0);
    hb->addWidget(file);
    hb->addWidget(hiddenproperty);
    hb->addWidget(readonlypower);
    hb->addWidget(writeonlypower);
    hb->addWidget(exepower);

    vb=new QVBoxLayout(this);
    vb->addLayout(grid);
    vb->addLayout(hb);
    vb->addWidget(getfileallproperty);
    connect(openfilebtn,&QPushButton::clicked,this,&Dialog::openfile);
    connect(getfileallproperty,&QPushButton::clicked,this,&Dialog::getallproperty);
}

Dialog::~Dialog() = default;
void Dialog::openfile()
{
    QString file=QFileDialog::getOpenFileName(this,"打开文件","/","Files(*.*)");
    pathedit->setText(file);

}

void Dialog::getallproperty()
{
    QString path=pathedit->text();

    QFileInfo list(path);
    sizeedit->setText(QString::number(list.size()));
    timeedit->setText(list.birthTime().toString());
    modifyedit->setText(list.lastModified().toString());
    useedit->setText(list.lastRead().toString());
    file->setChecked(list.isFile());
    hiddenproperty->setChecked(list.isHidden());
    readonlypower->setChecked(list.isReadable());
    writeonlypower->setChecked(list.isWritable());
    exepower->setChecked(list.isExecutable());

}

image-20260610181940710

mouseevent 鼠标事件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QMouseEvent>
//窗口状态栏
#include <QStatusBar>
#include <QImage>
#include <QMessageBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QLabel* showMousePointerlb,*statuslb;
    void displayimage();

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

    // QWidget interface
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

void MainWindow::displayimage()
{
    QString path("/home/study/Pictures/图片/3.jpeg");
    QLabel *imagelabel=new QLabel(this);
    QImage *imag=new QImage;
    imagelabel->move(20,20);
    imagelabel->setFixedSize(200,200);
    if(!(imag->load(path)))
    {
        QMessageBox::information(this,"消息","加载图片失败,请检查图片",QMessageBox::Ok|QMessageBox::Cancel);
        delete imag;
        return;
    }
    imagelabel->setPixmap(QPixmap::fromImage(*imag));
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle("鼠标事件");
    showMousePointerlb=new QLabel("");
    showMousePointerlb->setFixedWidth(200);
    statuslb=new QLabel("鼠标在当前坐标");
    statuslb->setFixedWidth(200);

    statusBar()->addPermanentWidget(statuslb);
    statusBar()->addPermanentWidget(showMousePointerlb);
    this->setMouseTracking(true);
    resize(900,600);
    displayimage();
}

MainWindow::~MainWindow() = default;

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    QString xpoint=QString::number(event->x());
    QString ypoint=QString::number(event->y());
    QString str="("+xpoint+","+ypoint+")";
    if(event->button()==Qt::LeftButton)
    {
        statusBar()->showMessage("用户已按下鼠标【左键】,坐标为"+str,2000);
    }
    if(event->button()==Qt::RightButton)
    {
        statusBar()->showMessage("用户已按下鼠标【右键】,坐标为"+str,2000);
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    QString xpoint=QString::number(event->x());
    QString ypoint=QString::number(event->y());
    showMousePointerlb->setText("("+xpoint+","+ypoint+")");
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    QString xpoint=QString::number(event->x());
    QString ypoint=QString::number(event->y());
    QString str="("+xpoint+","+ypoint+")";
    statusBar()->showMessage("用户以释放鼠标坐标"+str,2000);
    showMousePointerlb->setText("("+xpoint+","+ypoint+")");
}

image-20260611070427440

keyEvent


#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QKeyEvent>
#include <QPixmap>
#include <QImage>
#include <QPen>
#include <QPalette>
#include <QPainter>
class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
    void drawpix();
private:
    QPixmap* pix;
    QImage image;
    int startx,starty,widths,heights,step;
    // QWidget interface
protected:
    void paintEvent(QPaintEvent *event);
    void keyPressEvent(QKeyEvent *event);
};
#endif // WIDGET_H


#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("键盘操作事件");
    setAutoFillBackground(true);
    QPalette palet=this->palette();
    palet.setColor(QPalette::Window,Qt::white);
    setPalette(palet);
    setMinimumSize(800,600);
    setMaximumSize(800,600);
    widths=size().width();
    heights=size().height();

    pix=new QPixmap(widths,heights);
    pix->fill(Qt::white);

    startx=60;
    starty=60;
    step=30;
    image.load("/home/study/Pictures/图片/text.png");
    drawpix();
    resize(800,600);
}

Widget::~Widget() = default;

void Widget::drawpix()
{
    pix->fill(Qt::green);
    QPainter *pal=new QPainter;
    QPen pen(Qt::DashDotDotLine);

    for(int i=0;i<widths;i+=step)
    {
        pal->begin(pix);
        pal->setPen(pen);
        pal->drawLine(QPoint(i,0),QPoint(i,heights));
        pal->end();
    }
    for(int j=0;j<heights;j+=step)
    {
        pal->begin(pix);
        pal->setPen(pen);
        pal->drawLine(QPoint(0,j),QPoint(widths,j));
        pal->end();
    }
    pal->begin(pix);
    pal->drawImage(QPoint(startx,starty),image);
    pal->end();
}

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter pt;
    pt.begin(this);
    pt.drawPixmap(QPoint(0,0),*pix);
    pt.end();
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    startx=startx-startx%step;
    starty=starty-starty%step;
    if(event->key()==Qt::Key_Left)
    {
        startx=(startx-step<0)?startx:startx-step;
    }
    if(event->key()==Qt::Key_Right)
    {
        startx=(startx+step+image.width()>widths)?startx:startx+step;
    }
    if(event->key()==Qt::Key_Up)
    {
        starty=(starty-step<0)?starty:starty-step;
    }
    if(event->key()==Qt::Key_Down)
    {
        starty=(starty+step+image.height()>heights)?starty:starty+step;
    }
    drawpix();
    update();
}

image-20260611074830351

事件过滤器

eventfilter

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>
#include <QEvent>
#include <QImage>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QLabel* lb1,*lb2,*lb3,*lbinfor;
    QImage imag1,imag2,image3;
    QHBoxLayout *hb;
    QVBoxLayout *vb;


public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

    // QObject interface
public:
    bool eventFilter(QObject *watched, QEvent *event);
};
#endif // MAINWINDOW_H

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    lb1=new QLabel;
    lb2=new QLabel;
    lb3=new QLabel;
    lbinfor=new QLabel("鼠标按键提示信息");
    lbinfor->setAlignment(Qt::AlignCenter);
    imag1.load("/home/study/Pictures/图片/5.jpg");
    lb1->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    lb1->setPixmap(QPixmap::fromImage(imag1));

    imag2.load("/home/study/Pictures/图片/6.jpg");
    lb2->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    lb2->setPixmap(QPixmap::fromImage(imag2));

    image3.load("/home/study/Pictures/图片/7.jpg");
    lb3->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    lb3->setPixmap(QPixmap::fromImage(image3));
    hb=new QHBoxLayout;
    QWidget *wg=new QWidget(this);
    vb=new QVBoxLayout(wg);
    hb->addWidget(lb1);
    hb->addWidget(lb2);
    hb->addWidget(lb3);

    vb->addLayout(hb);
    vb->addWidget(lbinfor);
    setCentralWidget(wg);
    //事件过滤
    lb1->installEventFilter(this);
    lb2->installEventFilter(this);
    lb3->installEventFilter(this);

}

MainWindow::~MainWindow() = default;

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(watched==lb1)
    {
        if(event->type()==QEvent::MouseButtonPress)
        {
            QMouseEvent *mouse=(QMouseEvent*)event;
            if(mouse->buttons()&Qt::LeftButton)
            {
                lbinfor->setText("鼠标左键被按下,【左边图表】");
            }
            if(mouse->buttons()&Qt::MiddleButton)
            {
                lbinfor->setText("鼠标中键被按下,【中间图表】");
            }
            if(mouse->buttons()&Qt::RightButton)
            {
                lbinfor->setText("鼠标右键被按下,【右边图表】");
            }
            QTransform trans;
            trans.scale(1.5,1.5);
            QImage tempim=imag1.transformed(trans);
            lb1->setPixmap(QPixmap::fromImage(tempim));
        }
        if(event->type()==QEvent::MouseButtonRelease)
        {
            lbinfor->setText("鼠标按钮以释放");
            lb1->setPixmap(QPixmap::fromImage(imag1));
        }
    }
    if(watched==lb2)
    {
        if(event->type()==QEvent::MouseButtonPress)
        {
            QMouseEvent *mou=(QMouseEvent*)event;
            if(mou->buttons()&Qt::LeftButton)
            {
                 lbinfor->setText("鼠标左键被按下,【左边图表】");
            }
            if(mou->buttons()&Qt::MiddleButton)
            {
                lbinfor->setText("鼠标中键被按下,【中间图表】");
            }
            if(mou->buttons()&Qt::RightButton)
            {
                lbinfor->setText("鼠标右键被按下,【右边图表】");
            }
            QTransform tras;
            tras.scale(1.5,1.5);
            QImage temp=imag2.transformed(tras);
            lb2->setPixmap(QPixmap::fromImage(temp));
        }
        if(event->type()==QEvent::MouseButtonRelease)
        {
            lbinfor->setText("鼠标按钮以释放");
            lb2->setPixmap(QPixmap::fromImage(imag2));
        }
    }
    if(watched==lb3)
    {
        if(event->type()==QEvent::MouseButtonPress)
        {
            QMouseEvent *mous=(QMouseEvent*)event;
            if(mous->buttons()&Qt::LeftButton)
            {
                 lbinfor->setText("鼠标左键被按下,【左边图表】");
            }
            if(mous->buttons()&Qt::MiddleButton)
            {
                lbinfor->setText("鼠标中键被按下,【中间图表】");
            }
            if(mous->buttons()&Qt::RightButton)
            {
                lbinfor->setText("鼠标右键被按下,【右边图表】");
            }
            QTransform trs;
            trs.scale(1.5,1.5);
            QImage temp=image3.transformed(trs);
            lb3->setPixmap(QPixmap::fromImage(temp));
        }
        if(event->type()==QEvent::MouseButtonRelease)
        {
            lbinfor->setText("鼠标按钮以释放");
            lb3->setPixmap(QPixmap::fromImage(image3));
        }
    }

    return QMainWindow::eventFilter(watched,event);
}

image-20260611113437892

ini文件操作

#ifndef WRINI_H
#define WRINI_H
#include <QSettings>
#include <QtDebug>
void WritIniFile();
void ReadIniFile();
#endif // WRINI_H

#include "wrini.h"
void WritIniFile()
{
    //使用qsetting读写ini
    QSettings *set=new QSettings("MyConfig.ini",QSettings::IniFormat);
    //向文件写入信息
    set->setValue("MySQL/ip","127.0.0.1");
    set->setValue("MySQL/port","3306");
    set->setValue("MySQL/username","root");
    set->setValue("MySQL/password","123");
    delete set;
}

void ReadIniFile()
{
    QSettings *readset=new QSettings("MyConfig.ini",QSettings::IniFormat);
    QString strip=readset->value("MySQL/ip").toString();
    int port=readset->value("MySQL/port").toInt();
    QString strname=readset->value("MySQL/username").toString();
    QString strpassw=readset->value("MySQL/password").toString();

    qDebug()<<"ip地址:"<<strip.toUtf8().data()<<"\n"<<"端口号:"<<port<<"\n"<<"用户名:"<<strname.toUtf8().data()<<"\n"<<"用户密码:"<<strpassw.toUtf8().data();
    delete readset;
}

#include <QCoreApplication>
#include "wrini.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //调用写入
    WritIniFile();
    //读取ini
    ReadIniFile();

    return QCoreApplication::exec();
}

image-20260611121321176

json 文件读取

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QMessageBox>
#include <QFile>
//json文档
#include <QJsonDocument>
//json对象
#include <QJsonObject>
//json错误
#include <QJsonParseError>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::on_pushButton_clicked()
{
    //创建json对象
    QJsonObject MySqlJson;
    MySqlJson.insert("ip","127.0.0.1");
    MySqlJson.insert("port",3306);
    MySqlJson.insert("user","root");
    MySqlJson.insert("passw","123");

    QJsonObject jsoninfo;
    jsoninfo.insert("code",1);
    jsoninfo.insert("mesg","数据库配置信息");
    jsoninfo.insert("data",MySqlJson);
    //创建文档
    QJsonDocument jsondoc;
    jsondoc.setObject(jsoninfo);
    //写入文件中
    QFile file("./jsonfile.json");
    if(file.open(QIODevice::WriteOnly))
    {
        file.write(jsondoc.toJson());
        file.close();
        qDebug()<<"json写入成功";
    }
    QMessageBox::information(this,"信息","json写入成功");
}


void Dialog::on_pushButton_2_clicked()
{
    QString strjson;
    QFile files("./jsonfile.json");
    if(files.open(QIODevice::ReadOnly))
    {
        strjson=files.readAll();
        files.close();
    }
    QJsonParseError parseerr;
    //将字符串转成json文档
    QJsonDocument doc=QJsonDocument::fromJson(strjson.toUtf8(),&parseerr);

    QString tem;
    //判断文档是否为空以及是否转换时有无错误
    if(!doc.isEmpty()&&parseerr.error==QJsonParseError::NoError)
    {
        //将文档转换成对象
        QJsonObject json=doc.object();
        QJsonValue codes=json.value("code");
        QJsonValue data=json.value("data");

        if(codes.isUndefined()||codes.toInt()!=1||data.isUndefined()||!data.isObject())
        {
            qDebug()<<"转换json数据错误,请检查";
            QMessageBox::critical(this,"错误","转换json数据错误,请检查");
            exit(100);
        }
        QJsonObject datainfo=data.toObject();
        QJsonValue ip=datainfo.value("ip");
        QJsonValue port=datainfo.value("port");
        QJsonValue user=datainfo.value("user");
        QJsonValue passw=datainfo.value("passw");
        if(ip.isUndefined()||port.isUndefined()||user.isUndefined()||passw.isUndefined())
        {
            qDebug()<<"ip,port,user,passworld不能为空,请检查";
            QMessageBox::critical(this,"错误","ip,port,user,passworld不能为空,请检查");
            exit(100);
        }
        QString strip=ip.toString().toUtf8().data();
        int ports=port.toInt();
        QString struser=user.toString().toUtf8().data();
        QString strpassw=passw.toString().toUtf8().data();
        if(strip.isEmpty()||struser.isEmpty()||strpassw.isEmpty())
        {
            qDebug()<<"ip,user,passworld不能为空,请检查";
            QMessageBox::critical(this,"错误","ip,user,passworld不能为空,请检查");
            exit(100);
        }
        qDebug()<<"数据库ip:"<<strip<<"\n"<<"数据库接口:"<<ports<<"\n"<<"用户名:"<<struser<<"\n"<<"密码:"<<strpassw;
    }
}


image-20260611133417026

xml读取写入

  • 添加额外引入在pro文件中
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
//xml
#include <QDomDocument>
#include <QDir>
#include <QFile>
#include <QDebug>#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
//xml
#include <QDomDocument>
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QFile file;
    QString currentpathfile;
    QString currentfilename;
    QDir dirs;
public:
    bool openxmlfile(QString filepath);
    void readxml();
    void writexml();
    //读取xml节点
    void readrootxml(QDomNodeList nodelist);
private slots:
    void on_writexmlbtn_clicked();
    void on_readxmlbtn_clicked();
};
#endif // DIALOG_H


#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QFile file;
    QString currentpathfile;
    QString currentfilename;
    QDir dirs;
public:
    bool openxmlfile(QString filepath);
    void readxml();
    void writexml();
    //读取xml节点
    void readrootxml(QDomNodeList nodelist);
private slots:
    void on_writexmlbtn_clicked();
    void on_readxmlbtn_clicked();
};
#endif // DIALOG_H


#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);

    currentpathfile="/home/study/xmlfiles";
    currentfilename="/test.xml";
}

Dialog::~Dialog()
{
    delete ui;
}

bool Dialog::openxmlfile(QString filepath)
{

    dirs.setPath(filepath);
    if(!dirs.exists())
    {
        dirs.mkpath(filepath);
        qDebug()<<filepath;
    }
    file.setFileName(filepath+currentfilename);
    return file.open(QIODevice::ReadWrite|QFile::Text);
}

void Dialog::readxml()
{
    if(!openxmlfile(currentpathfile))
    {
        qDebug()<<"读取xml文档失败";
        return;
    }
    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        qDebug()<<"读取xml内容失败";
        return;
    }
    //读取第一个元素节点
    QDomElement rootnodel=doc.documentElement();
    //获取根节点得一个元素节点(worke)
    QDomNode node=rootnodel.firstChild();
    while(!node.isNull())
    {
        //获取所有子节点元素
        QDomNodeList list=node.childNodes();
        //读取父节点名称
        QString rootname=node.toElement().tagName();

        if(rootname.compare("worke")==0)
        {
            readrootxml(list);
        }
        //读取下一个父节点

        node=node.nextSibling();
    }
}

void Dialog::writexml()
{
    if(!openxmlfile(currentpathfile))
    {
        qDebug()<<"打开xml文件是失败";
        return;
    }
    else
    {
        qDebug()<<"打开xml成功,请写入xml内容";
        QDomDocument domdoc;
        //写入xml的头部
        QDomProcessingInstruction version;
        //头部xml内容
        version=domdoc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
        //追加到xml文档中
        domdoc.appendChild(version);
        //创建根节点
        QDomElement domel=domdoc.createElement("factory");
        //
        domdoc.appendChild(domel);
        QDomElement itemparent=domdoc.createElement("worke");
        {
            //创建子节点
            QDomElement node1=domdoc.createElement("WNo");
            //创建文本节点
            QDomText domtext1=domdoc.createTextNode("WNo");
            //将输入框中内容填充到文本节点中
            domtext1.setData(ui->numberid->text());
            //将文本节点添加到子节点中
            node1.appendChild(domtext1);
            //子节点添加到父节点中
            itemparent.appendChild(node1);

            //创建子节点
            QDomElement node2=domdoc.createElement("WName");
            //创建文本节点
            QDomText domtext2=domdoc.createTextNode("WName");
            //将输入框中内容填充到文本节点中
            domtext2.setData(ui->nameedit->text());
            //将文本节点添加到子节点中
            node2.appendChild(domtext2);
            //子节点添加到父节点中
            itemparent.appendChild(node2);

            //创建子节点
            QDomElement node3=domdoc.createElement("WSex");
            //创建文本节点
            QDomText domtext3=domdoc.createTextNode("WSex");
            //将输入框中内容填充到文本节点中
            domtext3.setData(ui->sexedit->text());
            //将文本节点添加到子节点中
            node3.appendChild(domtext3);
            //子节点添加到父节点中
            itemparent.appendChild(node3);

            //创建子节点
            QDomElement node4=domdoc.createElement("WEducation");
            //创建文本节点
            QDomText domtext4=domdoc.createTextNode("WEducation");
            //将输入框中内容填充到文本节点中
            domtext4.setData(ui->studyedit->text());
            //将文本节点添加到子节点中
            node4.appendChild(domtext4);
            //子节点添加到父节点中
            itemparent.appendChild(node4);

            //创建子节点
            QDomElement node5=domdoc.createElement("WDepartment");
            //创建文本节点
            QDomText domtext5=domdoc.createTextNode("WDepartment");
            //将输入框中内容填充到文本节点中
            domtext5.setData(ui->departedit->text());
            //将文本节点添加到子节点中
            node5.appendChild(domtext5);
            //子节点添加到父节点中
            itemparent.appendChild(node5);

            //创建子节点
            QDomElement node6=domdoc.createElement("WSalary");
            //创建文本节点
            QDomText domtext6=domdoc.createTextNode("WSalary");
            //将输入框中内容填充到文本节点中
            domtext6.setData(ui->salaryedit->text());
            //将文本节点添加到子节点中
            node6.appendChild(domtext6);
            //子节点添加到父节点中
            itemparent.appendChild(node6);
        }
        domel.appendChild(itemparent);
        file.write(domdoc.toString().toUtf8().data());
        file.close();
        QMessageBox::information(this,"提示","写入xml文件成功,请在文件按中查看");
    }
}

void Dialog::readrootxml(QDomNodeList nodelist)
{
    for(int nod=0;nod<nodelist.size();nod++)
    {
        QDomElement sonel=nodelist.at(nod).toElement();

        if(sonel.toElement().tagName().compare("WNo")==0&&ui->numbrerid->text().isEmpty())
        {
            ui->numbrerid->setText(sonel.text());
        }
        else if(sonel.toElement().tagName().compare("WName")==0&&ui->rnameedit->text().isEmpty())
        {
            ui->rnameedit->setText(sonel.text());
        }
        else if(sonel.toElement().tagName().compare("WSex")==0&&ui->rsexedit->text().isEmpty())
        {
            ui->rsexedit->setText(sonel.text());
        }
        else if(sonel.toElement().tagName().compare("WEducation")==0&&ui->rstudyedit->text().isEmpty())
        {
            ui->rstudyedit->setText(sonel.text());
        }
        else if(sonel.toElement().tagName().compare("WDepartment")==0&&ui->rdepartedit->text().isEmpty())
        {
            ui->rdepartedit->setText(sonel.text());
        }
        else if(sonel.toElement().tagName().compare("WSalary")==0&&ui->rsalaryedit->text().isEmpty())
        {
            ui->rsalaryedit->setText(sonel.text());
        }
    }
}


void Dialog::on_writexmlbtn_clicked()
{
    writexml();
}


void Dialog::on_readxmlbtn_clicked()
{
    readxml();
}


image-20260612082842438

网络协议

  • 需要额外添加network如
QT += widgets network
  • 获取主机名称和ip
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
//主机信息
#include <QHostInfo>
//主机网络接口
#include <QNetworkInterface>
#include <QList>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
    void gethostNameAndip();
    void writehostinfo(const QString&);

private slots:
    void on_gethostnamebtn_clicked();
    void on_gethostallbtn_clicked();

private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::gethostNameAndip()
{
    //获取主机名称
    QString hostnames=QHostInfo::localHostName();
    ui->hostname->setText(hostnames);
    //获取主机地址
    QString localipadress="";
    //通过主机名称获取相应的所有主机信息
    QHostInfo host=QHostInfo::fromName(hostnames);
    //获取主机所有地址信息
    QList<QHostAddress> listadress=host.addresses();
    //判断地址是否为空
    if(!listadress.isEmpty())
    {
        //循环遍历所有主机地址信息
        foreach (QHostAddress add, listadress) {
            //判断主机地址类型是否是ipv4类型
            if(QAbstractSocket::IPv4Protocol==add.protocol())
            {
                //获得的主机信息赋值给主机地址变量并跳出循环
                localipadress=add.toString();
                break;
            }
        }
    }
    ui->hostip->setText(localipadress);
}

void Dialog::writehostinfo(const QString& info)
{
    //QList<QString> list=info.split("\n");
    QFile file("./hostinfor.txt");
    if(file.open(QIODevice::WriteOnly))
    {
        //1.种写法存在冗余问题
        /*QByteArray byte;
        byte.resize(info.length());
        memcpy(byte.data(),info.toUtf8().data(),info.length());
        file.write(byte);
        file.close();*/
        file.write(info.toUtf8());
        file.close();
    }
}
void Dialog::on_gethostnamebtn_clicked()
{
    gethostNameAndip();
}
void Dialog::on_gethostallbtn_clicked()
{
    QString strTem="";
    //获取主机所有网络接口列表
    QList<QNetworkInterface> netlist=QNetworkInterface::allInterfaces();

    foreach (QNetworkInterface intface, netlist)
    {
        strTem=strTem+"设备名称:"+intface.name()+"\n";
        strTem=strTem+"硬件地址:"+intface.hardwareAddress()+"\n";
        //获取所有ip地址
        QList<QNetworkAddressEntry> entrylistaddress=intface.addressEntries();
        foreach(QNetworkAddressEntry address,entrylistaddress)
        {
            strTem=strTem+"ip地址:"+address.ip().toString()+"\n";
            strTem=strTem+"子网掩码:"+address.netmask().toString()+"\n";
            strTem=strTem+"广播地址:"+address.broadcast().toString()+"\n";
        }
    }
    writehostinfo(strTem);
    QMessageBox::information(this,"主机信息",strTem,QMessageBox::Yes);
}



image-20260612101504024

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QHostInfo>

QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT
public:
    QString protocalTypeName(QAbstractSocket::NetworkLayerProtocol pro);
    void LookUpHostInfor(const QHostInfo&);
public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;

private slots:
    void on_getdomainipbtn_clicked();

    void on_cleaninforbtn_clicked();

private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

#include "dialog.h"
#include "ui_dialog.h"


Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    ui->lineEdit->setText("www.baidu.com");
}

Dialog::~Dialog()
{
    delete ui;
}
QString Dialog::protocalTypeName(QAbstractSocket::NetworkLayerProtocol pro)
{
    switch (pro) {
    case QAbstractSocket::IPv4Protocol:
        return "IPv4 protocol";
        break;
    case QAbstractSocket::IPv6Protocol:
        return "IPv6 protocol";
        break;
    case QAbstractSocket::AnyIPProtocol:
        return "any protocol";
        break;
    default:
        return "unknow ip protocol";
        break;
    }
}

void Dialog::LookUpHostInfor(const QHostInfo &hostinfo)
{
    QList<QHostAddress> list=hostinfo.addresses();
    foreach (QHostAddress address, list) {
        ui->plaineditdomian->appendPlainText("协议类型:"+protocalTypeName(address.protocol()));
        ui->plaineditdomian->appendPlainText("本地ip地址:"+address.toString());
    }
}

void Dialog::on_getdomainipbtn_clicked()
{
    QString hostname=ui->lineEdit->text();
    ui->plaineditdomian->appendPlainText("你查询的主机信息:"+hostname);
    QHostInfo::lookupHost(hostname,this,&Dialog::LookUpHostInfor);
}


void Dialog::on_cleaninforbtn_clicked()
{
    ui->lineEdit->clear();
}


image-20260612105212637

Tcp协议

TcpSocker

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QHostInfo>
#include <QHostAddress>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
    QTcpSocket* tcpsocket;
    QString getlocalip();
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private slots:
    void on_clientconnectserversbtn_clicked();

    void on_clientdisconnectserver_clicked();

    void on_sendmesbtn_clicked();

private:
    Ui::MainWindow *ui;

private slots:
    void connectserver();
    void disconnectserver();
    void socketreaddata();
    // QWidget interface
protected:
    void closeEvent(QCloseEvent *event);
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    tcpsocket=new QTcpSocket(this);
    QString ip=getlocalip();
    ui->clientcombox->addItem(ip);
    connect(tcpsocket,&QTcpSocket::connected,this,&MainWindow::connectserver);
    connect(tcpsocket,&QTcpSocket::disconnected,this,&MainWindow::disconnectserver);
    connect(tcpsocket,&QTcpSocket::readyRead,this,&MainWindow::socketreaddata);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QString MainWindow::getlocalip()
{
    QString hostname=QHostInfo::localHostName();
    QHostInfo infor=QHostInfo::fromName(hostname);
    QList<QHostAddress> list=infor.addresses();
    QString strip="";
    if(!list.isEmpty())
    {
        foreach (QHostAddress address, list) {
            if(address.protocol()==QAbstractSocket::IPv4Protocol)
            {
                strip=address.toString();
                break;
            }

        }
    }
    return strip;
}

void MainWindow::on_clientconnectserversbtn_clicked()
{
    QString strip=ui->clientcombox->currentText();
    quint16 port=ui->clientspinBox->value();
    tcpsocket->connectToHost(strip,port);
}


void MainWindow::on_clientdisconnectserver_clicked()
{
    if(tcpsocket->state()==QAbstractSocket::ConnectedState)
    {
        tcpsocket->disconnectFromHost();
    }
}


void MainWindow::on_sendmesbtn_clicked()
{
    QString mesg=ui->lineEdit->text();
    ui->plainTextEdit->appendPlainText("[out]:"+mesg);
    ui->lineEdit->clear();
    QByteArray byte=mesg.toUtf8();
    byte.append("\n");
    tcpsocket->write(byte);
}

void MainWindow::connectserver()
{
    ui->plainTextEdit->appendPlainText("****已经连接到服务器****");
    ui->plainTextEdit->appendPlainText("****地址:"+tcpsocket->peerAddress().toString());
    ui->plainTextEdit->appendHtml("****端口:"+QString::number(tcpsocket->peerPort()));
    ui->clientconnectserversbtn->setEnabled(false);
    ui->clientdisconnectserver->setEnabled(true);
}

void MainWindow::disconnectserver()
{
    if(tcpsocket->state()==QAbstractSocket::UnconnectedState)
    {
        ui->plainTextEdit->appendPlainText("****服务器已断开****");
        ui->clientconnectserversbtn->setEnabled(true);
        ui->clientdisconnectserver->setEnabled(false);
    }
}



void MainWindow::socketreaddata()
{
    while(tcpsocket->canReadLine())
    {
        ui->plainTextEdit->appendPlainText("[in]:"+tcpsocket->readLine());
    }
}



void MainWindow::closeEvent(QCloseEvent *event)
{
    if(tcpsocket->state()==QAbstractSocket::ConnectedState)
    {
        tcpsocket->disconnectFromHost();
    }
    event->accept();
}


image-20260612153747356

TcpServer

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//tcp服务连接,用于建立连接和传输数据
#include <QTcpServer>
//提供客户端与服务端的类
#include<QtNetwork>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private:
    Ui::MainWindow *ui;

private:
    QTcpServer *tcpservers;
    QTcpSocket* tcpsockets;
    QString getlocalIpAddress();
private slots:
    void clientconnect();
    void clientdisconnect();
    void socketreaddata();
    void newconnect();
    void on_startbtn_clicked();
    void on_stopbtn_clicked();
    void on_sendmessage_clicked();
protected:
    void closeEvent(QCloseEvent  *event);
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QString ips=getlocalIpAddress();
    ui->ipcombox->addItem(ips);
    tcpservers=new QTcpServer(this);
    connect(tcpservers,&QTcpServer::newConnection,this,&MainWindow::newconnect);

}

MainWindow::~MainWindow()
{
    delete ui;
}

QString MainWindow::getlocalIpAddress()
{
    //获取主机名称
    QString hostname=QHostInfo::localHostName();
    //通过主机名称获取主机所有信息
    QHostInfo hostinfo=QHostInfo::fromName(hostname);
    QString ipstr="";
    //获取主机所有地址
    QList<QHostAddress> address=hostinfo.addresses();
    if(!address.isEmpty())
    {
        //遍历主机地址
        foreach (QHostAddress hostaddress, address) {
            //判断主机地址协议类型是否ipv4协议类型
            if(hostaddress.protocol()==QAbstractSocket::IPv4Protocol)
            {
                ipstr=hostaddress.toString();
                break;
            }
        }
    }
    return ipstr;
}

void MainWindow::clientconnect()
{
    ui->messsageplain->appendPlainText("****客户端socket连接*****");
    ui->messsageplain->appendPlainText("****客户端连接地址"+tcpsockets->peerAddress().toString());
    ui->messsageplain->appendPlainText("****客户端连接端口"+tcpsockets->peerPort());

}

void MainWindow::clientdisconnect()
{
    ui->messsageplain->appendPlainText("****客户端socket断开连接*****");
    tcpsockets->deleteLater();
}

void MainWindow::socketreaddata()
{
    while(tcpsockets->canReadLine())
    {
        ui->messsageplain->appendPlainText("[in]:"+tcpsockets->readLine());
    }
}

void MainWindow::newconnect()
{
    tcpsockets=tcpservers->nextPendingConnection();
    connect(tcpsockets,&QTcpSocket::connected,this,&MainWindow::clientconnect);
    connect(tcpsockets,&QTcpSocket::disconnected,this,&MainWindow::clientdisconnect);

    connect(tcpsockets,&QTcpSocket::readyRead,this,&MainWindow::socketreaddata);

    //connect(tcpsockets,&QTcpSocket::stateChanged,this,[this](QAbstractSocket::SocketState state){OnSocketStateChanged(state)});
}

void MainWindow::on_startbtn_clicked()
{
    QString ip=ui->ipcombox->currentText();
    quint16 port=ui->portspli->value();
    QHostAddress address(ip);
    tcpservers->listen(address,port);

    ui->messsageplain->appendPlainText("$$$开始监听$$$");
    ui->messsageplain->appendPlainText("$$$服务器地址$$$:"+tcpservers->serverAddress().toString());
    ui->messsageplain->appendPlainText("$$$服务器端口:$$$"+QString::number(tcpservers->serverPort()));
    ui->startbtn->setEnabled(false);
    ui->stopbtn->setEnabled(true);

}

void MainWindow::on_stopbtn_clicked()
{
    if(tcpservers->isListening())
    {
        tcpservers->close();
        ui->startbtn->setEnabled(true);
        ui->stopbtn->setEnabled(false);
    }
}


void MainWindow::on_sendmessage_clicked()
{
    QString strmesg=ui->messageedit->text();
    ui->messsageplain->appendPlainText("[out]:"+strmesg);
    ui->messageedit->clear();

    QByteArray strm=strmesg.toUtf8();
    strm.append("\n");
    tcpsockets->write(strm);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(tcpservers->isListening())
    {
        tcpservers->close();
    }
    event->accept();
}


image-20260612153904542

udpsocket

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUdpSocket>
#include <QtNetwork>
#include <QHostInfo>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
    QUdpSocket* udpserver;
public:
    QString gethostip();
private:
    void connecttarget();
    void disconnecttarget();
    void readtargetdata();
private slots:
    void on_startbtn_server_clicked();

    void on_stopbtn_server_clicked();

    void on_sendmessagebtn_server_clicked();

    void on_broadcastbtn_server_clicked();

private:
    Ui::MainWindow *ui;

    // QWidget interface
protected:
    void closeEvent(QCloseEvent *event);
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QString ip=gethostip();
    ui->comboBox_server->addItem(ip);
    udpserver=new QUdpSocket(this);
    connect(udpserver,&QUdpSocket::readyRead,this,&MainWindow::readtargetdata);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QString MainWindow::gethostip()
{
    QString hostname=QHostInfo::localHostName();
    QHostInfo hostinfo=QHostInfo::fromName(hostname);
    QString strip="";
    QList<QHostAddress> list=hostinfo.addresses();
    if(!list.isEmpty())
    {
        foreach (QHostAddress address, list)
        {
            if(address.protocol()==QAbstractSocket::IPv4Protocol)
            {
                strip=address.toString();
                break;
            }

        }
    }
    return strip;
}

void MainWindow::connecttarget()
{
    quint16 ports=ui->spinBox_server->value();
    if( udpserver->bind(ports))
    {

        //qDebug() << "Socket state before bind:" << udpserver->state();
        ui->plainTextEdit->appendPlainText("***绑定成功!***");
        ui->plainTextEdit->appendPlainText("***地址:"+QString::number(udpserver->localPort()));
        ui->startbtn_server->setEnabled(false);
        ui->stopbtn_server->setEnabled(true);
    }
    else
        ui->plainTextEdit->appendPlainText("***绑定失败!***");



}

void MainWindow::disconnecttarget()
{
    udpserver->abort();
    ui->startbtn_server->setEnabled(true);
    ui->stopbtn_server->setEnabled(false);
    ui->plainTextEdit->appendPlainText("***已停止服务***");
}

void MainWindow::readtargetdata()
{
    while(udpserver->hasPendingDatagrams())
    {
        QByteArray byte;
        byte.resize(udpserver->pendingDatagramSize());
        QHostAddress adr;
        quint16 pport;
        udpserver->readDatagram(byte.data(),byte.size(),&adr,&pport);

        QString str=byte.data();
        QString peer="[来自于:"+adr.toString()+":"+QString::number(pport)+"]";
        ui->plainTextEdit->appendPlainText(peer+str);
    }
}

void MainWindow::on_startbtn_server_clicked()
{
    connecttarget();
}


void MainWindow::on_stopbtn_server_clicked()
{
    disconnecttarget();
}


void MainWindow::on_sendmessagebtn_server_clicked()
{
    //获取ip地址
    QString targetip=ui->comboBox_server->currentText();
    //将字符串转换成QhostAddress
    QHostAddress hostaddress(targetip);
    quint16 port=ui->spinBox_taget_server->value();
    //连接目标服务器
    qDebug()<<udpserver->localPort();
    if(udpserver->localPort()!=port&&udpserver->peerAddress()!=hostaddress)
        udpserver->bind(hostaddress,port);
    //读取发送消息
    QString msg=ui->lineEdit->text();
    QByteArray sendm=msg.toUtf8();
    //写入到udpsocket中
    udpserver->writeDatagram(sendm,hostaddress,port);
    ui->plainTextEdit->appendPlainText("[out]:"+msg);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();
}


void MainWindow::on_broadcastbtn_server_clicked()
{
    quint16 targetports=ui->spinBox_taget_server->value();
    QString msg=ui->lineEdit->text();
    qDebug()<<udpserver->peerPort();
    if(udpserver->peerPort()!=targetports)
        udpserver->bind(targetports);
    QByteArray broadcast=msg.toUtf8();
    udpserver->writeDatagram(broadcast.data(),QHostAddress::Broadcast,targetports);
    ui->plainTextEdit->appendPlainText("[broadcast]:"+msg);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(udpserver->state()==QAbstractSocket::ConnectedState)
    {
        udpserver->abort();
    }
    event->accept();
}



image-20260612205808787

[!warning]

上面代码存在重复绑定问题

线程

thread

#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>
#include <QDebug>

class WorkThread : public QThread
{
    Q_OBJECT
public:
    WorkThread();
    void stop();
private:
    std::atomic<bool> m_run{false};
    // QThread interface
protected:
    void run();
};

#endif // WORKTHREAD_H

#include "workthread.h"

WorkThread::WorkThread() {}

void WorkThread::stop()
{
    m_run=false;
}


void WorkThread::run()
{
    m_run=true;
    while(m_run)
    {
        for(int i=1;i<=5;i++)
        {
            qDebug()<<i<<i<<i<<i<<i;
        }
        QThread::msleep(10);
    }
}

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include "workthread.h"
#include <QPushButton>
#include <QHBoxLayout>

#define MAXSIZE 5

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;

private:
    QPushButton* startbtn;
    QPushButton* stopbtn;
    QPushButton* exitbtn;

    WorkThread* workThread[MAXSIZE];
public slots:
    void onSlotStart();
    void onSLotStop();
};
#endif // DIALOG_H

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle("线程测试班");

    startbtn=new QPushButton;
    startbtn->setText("开始");
    stopbtn=new QPushButton("停止");
    exitbtn=new QPushButton("退出");

    QHBoxLayout *hb=new QHBoxLayout(this);
    hb->addWidget(startbtn);
    hb->addWidget(stopbtn);
    hb->addWidget(exitbtn);

    connect(startbtn,&QPushButton::clicked,this,&Dialog::onSlotStart);
    connect(stopbtn,&QPushButton::clicked,this,&Dialog::onSLotStop);
    connect(exitbtn,&QPushButton::clicked,this,&Dialog::close);
}

Dialog::~Dialog() = default;

void Dialog::onSlotStart()
{
    for (int i = 0; i < MAXSIZE; i++) {
        workThread[i]=new WorkThread;
    }
    for (int i = 0; i < MAXSIZE; i++) {
        workThread[i]->start();
    }
    startbtn->setEnabled(false);
    stopbtn->setEnabled(true);
}

void Dialog::onSLotStop()
{
    for (int i = 0; i < MAXSIZE; i++) {
        workThread[i]->stop();
        workThread[i]->wait();
    }
    startbtn->setEnabled(true);
    stopbtn->setEnabled(false);
}

信号量Semaphore

#include <QCoreApplication>

#include <QThread>
//信号量
#include <QSemaphore>
#include <QTime>
#include <QRandomGenerator>
#include <iostream>

const int datasize=10;
const int buffersize=1;
QSemaphore freespace(buffersize);
QSemaphore usedspace(0);

class producer:public QThread
{
protected:
    void run()
    {
        //生成随机数
        QRandomGenerator::global()->bounded(QTime(0,0,0,0).secsTo(QTime::currentTime()));
        QRandomGenerator rands(NULL);
        for(int i=0;i<datasize;i++)
        {
            //获取资源
            freespace.acquire();
            std::cerr<<i<<":producer->";
            //释放资源
            usedspace.release();
        }
    }
};
class consumers:public QThread
{


    // QThread interface
protected:
    void run()
    {
        for(int i=0;i<datasize;++i)
        {
            usedspace.acquire();
            std::cerr<<i<<":consumer->";
            freespace.release();
        }
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    producer p;
    consumers c;
    p.start();
    c.start();
    p.wait();
    c.wait();

    return QCoreApplication::exec();
}

互斥量Mutex\Mutexlocker

#include <QCoreApplication>
#include <iostream>
//互斥量
#include <QMutex>
//
#include <QThread>
#include <QObject>
class ticketsallers:public QObject
{
public:
    ticketsallers();
    ~ticketsallers();
public slots:
    void salefn();
public:
    //票数
    int *tickets;
    //互斥量
    QMutex* metx;
    //销售员名称
    std::string sellername;
};
ticketsallers::ticketsallers()
{
    metx=NULL;
    tickets=0;
}
ticketsallers::~ticketsallers()
{

}
void ticketsallers::salefn()
{
    //判断票数是否大于0
    while((*tickets)>0)
    {
        metx->lock();
        if((*tickets<=0))
        {
            metx->unlock();
            break;
        }
        std::cout<<sellername<<":"<<(*tickets)--<<std::endl;
        metx->unlock();
        QThread::msleep(100);
    }

}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int tickets=20;
    QMutex mtx;
    //创建线程
    QThread thread1;
    ticketsallers seller1;
    //设置线程
    seller1.tickets=&tickets;
    seller1.metx=&mtx;
    seller1.sellername="张三";

    //将对象移动到线程中
    seller1.moveToThread(&thread1);

    QThread thread2;
    ticketsallers seller2;
    seller2.tickets=&tickets;
    seller2.metx=&mtx;
    seller2.sellername="李四";

    seller2.moveToThread(&thread2);


    QThread thread3;
    ticketsallers seller3;
    seller3.tickets=&tickets;
    seller3.metx=&mtx;
    seller3.sellername="王五";

    seller3.moveToThread(&thread3);
    QObject::connect(&thread1,&QThread::started,&seller1,&ticketsallers::salefn);
    QObject::connect(&thread2,&QThread::started,&seller2,&ticketsallers::salefn);
    QObject::connect(&thread3,&QThread::started,&seller3,&ticketsallers::salefn);
    thread1.start();
    thread2.start();
    thread3.start();
    return QCoreApplication::exec();
}

image-20260613131229542

多线程cs模拟

#ifndef HANDERTHREAD_H
#define HANDERTHREAD_H

#include <QThread>
//建立tcp连接并传输数据流
#include <QTcpSocket>
//TCP/IP客户端和服务器的类
#include <QtNetwork>
//tcp、udp发送和接收数据都是通过二进制字节数组QByteArray
#include <QByteArray>

class handerThread : public QThread
{
    Q_OBJECT
public:
    handerThread(int socketdescriptor,QObject *parent=nullptr);

signals:
    void error(QTcpSocket::SocketError socketerror);
private:
    int socketdescriptor;
    // QThread interface
protected:
    void run();
};

#endif // HANDERTHREAD_H

#include "handerthread.h"

handerThread::handerThread(int socketdescriptor,QObject *parent):
    QThread(parent),
    socketdescriptor(socketdescriptor)
{

}

void handerThread::run()
{
    QTcpSocket socket;
    if(!socket.setSocketDescriptor(socketdescriptor))
    {
        emit error(socket.error());
        return;
    }
    QByteArray byte;
    QDataStream out(&byte,QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_6_5);

    socket.write(byte);
    socket.disconnectFromHost();
}

#ifndef CLIENTSERVER_H
#define CLIENTSERVER_H

#include <QTcpServer>
//前向声明;用于 减少编译依赖,加快编译速度
class Dialog;
#include "handerthread.h"


//第二步
class ClientServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit ClientServer(QObject *parent = nullptr);

    // QTcpServer interface
protected:
    void incomingConnection(int socketdescriptor);
    Dialog* dlog;
};

#endif // CLIENTSERVER_H

#include "clientserver.h"
//需要知道所有细节
#include "dialog.h"
ClientServer::ClientServer(QObject *parent)
    : QTcpServer{parent}
{
    dlog=(Dialog*)parent;
}

void ClientServer::incomingConnection(int socketdescriptor)
{
    handerThread* thread=new handerThread(socketdescriptor,0);
    //显示客户端访问次数
    connect(thread,&handerThread::finished,dlog,&Dialog::showfn);
    connect(thread,&handerThread::finished,thread,&handerThread::deleteLater,Qt::DirectConnection);
    thread->start();
}

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

#include <QMessageBox>
class ClientServer;

QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;

private:
    Ui::Dialog *ui;
private:
    int icount;
    ClientServer* tcpserver;
public slots:
    void showfn();
};
#endif // DIALOG_H

#include "dialog.h"
#include "ui_dialog.h"
#include "clientserver.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    icount=0;
    tcpserver=new ClientServer(this);
    if(!tcpserver->listen())
    {
        QMessageBox::critical(this,"错误",tr("多线程服务无法启动").arg(tcpserver->errorString()));
        close();
        return;
    }
    ui->serveredit->setText(tr("%1").arg(tcpserver->serverPort()));
    connect(ui->exitbtn,&QPushButton::clicked,this,&Dialog::close);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::showfn()
{
    ui->countclient->setText(tr("客户端请求%1次").arg(++icount));
}

客户端

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QTcpSocket>
#include <QMessageBox>
#include <QAbstractSocket>
#include <QDataStream>

QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog() override;
private:
    QTcpSocket* socket;
private slots:
    void on_applicatantserverbtn_clicked();

public slots:
    void showError(QAbstractSocket::SocketError error);
    void operatorexc();
private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    socket=new QTcpSocket(this);
    connect(ui->applicatantserverbtn,&QPushButton::clicked,this,&Dialog::operatorexc);
    connect(ui->exitbtn,&QPushButton::clicked,this,&Dialog::close);
    connect(socket,&QTcpSocket::errorOccurred,this,&Dialog::showError);
    ui->serverport->setFocus();
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::on_applicatantserverbtn_clicked()
{
    ui->applicatantserverbtn->setEnabled(!ui->servername->text().isEmpty()&&ui->serverport->text().isEmpty());
}

void Dialog::showError(QAbstractSocket::SocketError error)
{
    switch(error)
    {
    case QAbstractSocket::RemoteHostClosedError:
        QMessageBox::information(this,"提示","远程主机关闭连接",QMessageBox::Yes);
        break;
    case QAbstractSocket::HostNotFoundError:
        QMessageBox::information(this,"提示","找不到远程主机",QMessageBox::Yes);
        break;
    case QAbstractSocket::ConnectionRefusedError:
        QMessageBox::information(this,"提示","连接主机拒绝连接(或超时)",QMessageBox::Yes);
        break;
    default:
        QMessageBox::information(this,"错误",tr("致命错误:%1").arg(socket->errorString()));
        break;
    }
    ui->applicatantserverbtn->setEnabled(true);
}

void Dialog::operatorexc()
{
    ui->servername->setEnabled(false);
    //取消已有的所有连接
    socket->abort();
    socket->connectToHost(ui->servername->text(),ui->serverport->text().toInt());
    if(socket->state()==QAbstractSocket::ConnectedState)
    {
        QMessageBox::information(this,"提示","为连接成功");
    }
}




image-20260613172543574

[!note]

服务端run中改成 // while(socket.state()==QAbstractSocket::ConnectedState)
// {
// if(socket.waitForReadyRead(10000))
// {
// byte=socket.readAll();
// socket.write(byte);
// }
// }并注销 socket.disconnectFromHost();可以实现一直保持连接,但存在延迟,只有等待waitForReadyRead秒数结束后才能写入

Http

  • 流程
    • 客户端要与服务端建立连接
    • 客户端要想服务器请求数据
    • 服务端返回相应的数据报
    • 客户端与服务端要断开连接
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//提供TCP/IP客户端和服务器类型
#include <QtNetwork>
#include <QUrl>
class QNetworkAccessManager;
//是QIODevice的子类,封装QNetworkAccessManager信息
class QNetworkReply;

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;

private:
    Ui::MainWindow *ui;

    QNetworkAccessManager* mgr;
private slots:
    void replayFinishedfn(QNetworkReply *);
    void on_getinforbtn_clicked();
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mgr=new QNetworkAccessManager(this);
    connect(mgr,&QNetworkAccessManager::finished,this,&MainWindow::replayFinishedfn);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::replayFinishedfn(QNetworkReply *reply)
{
    QString strall=reply->readAll();
    ui->textBrowser->setText(strall);
    reply->deleteLater();
}

void MainWindow::on_getinforbtn_clicked()
{
    mgr->get(QNetworkRequest(QUrl("http://www.baidu.com")));
}


image-20260613191310166

#ifndef MYHTTPSERVER_H
#define MYHTTPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QObject>
class MyHttpServer:public QObject
{
    Q_OBJECT
public:
    explicit MyHttpServer(QObject* parent=nullptr);
    ~MyHttpServer();

public:
    QTcpSocket* socket;
private:
    QTcpServer* tcpserver;
    qint64 byteAvailable()const;
public slots:
    void connect();
};

#endif // MYHTTPSERVER_H

#include "myhttpserver.h"

MyHttpServer::MyHttpServer(QObject *parent):QObject(parent)
{
    tcpserver=new QTcpServer(this);
    QObject::connect(tcpserver,&QTcpServer::newConnection,this,&MyHttpServer::connect);
    if(!tcpserver->listen(QHostAddress::Any,8085))
    {
        qDebug()<<"致命错误,web服务器没有实现";
    }
    else
    {
        qDebug()<<"启动成功";
    }
}

MyHttpServer::~MyHttpServer()
{
    socket->close();
}

void MyHttpServer::connect()
{
    socket=tcpserver->nextPendingConnection();
    while(!(socket->waitForReadyRead(100)));
    char webdata[1000];
    int sv=socket->read(webdata,1000);
    qDebug()<<"正常运行:读取信息。。"<<QString(webdata);
    socket->write("HTTP/1.1 200 OK\r\n");
    socket->write("Content-Type:text/html\r\n");
    socket->write("Connection:close\r\n");
    socket->write("Refresh:1\r\n\r\n");
    socket->write("<!DOCTYPE html>"
                  "<html>"
                  "<head>"
                  "<meta http-equiv=\"content-Type\" content=\"text/html; charset=utf-8\">"
                  "<title>httpserver</title>"
                  "</head>"
                  "<body>客户端已经连接到httpserver服务器秒数为:");
    QByteArray bytesary;
    static qint16 icount;
    bytesary.setNum(icount++);
    socket->write(bytesary);
    socket->write("</body></html>");

    socket->flush();
    QObject::connect(socket,&QTcpSocket::disconnected,socket,&QTcpSocket::deleteLater);
    socket->disconnectFromHost();
}

image-20260613202056105

websocket

  • 需要引入websockets

websocketserver

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QAbstractSocket>

//
#include <QWebSocket>
#include <QWebSocketServer>
//读取和写入json相关方法
#include <QJsonDocument>
//json对象
#include <QJsonObject>
#include <QListWidgetItem>
//前向声明
class QWebSocket;
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;

private:
    Ui::Widget *ui;
    class QWebSocketServer *websocketserver;
    QList<QWebSocket*> websocketlist;

    void getNewConnect();
    void receiveMsg(const QString&);
public slots:
    void onerrrofn(QAbstractSocket::SocketError error);
private slots:
    void on_sendbtn_clicked();
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //ws(服务器非安全模式)
    //wss (服务器安全模式)
    websocketserver=new QWebSocketServer(QStringLiteral("testServer"),QWebSocketServer::NonSecureMode,this);
    connect(websocketserver,&QWebSocketServer::newConnection,this,&Widget::getNewConnect);
    websocketserver->listen(QHostAddress::Any,8808);
}

Widget::~Widget()
{
    delete ui;
    for(auto socket:websocketlist)
    {
        socket->close();
    }
    websocketserver->close();
}

void Widget::getNewConnect()
{
    //判断服务器是否有挂起连接
    if(websocketserver->hasPendingConnections())
    {
        //将挂起的下一个对象作为已连接的对象返回
        QWebSocket *websockets=websocketserver->nextPendingConnection();
        ui->meslistedit->append(websockets->origin()+"客户端已连接到服务器");
        websocketlist<<websockets;

        QListWidgetItem *items=new QListWidgetItem;
        items->setText(websockets->origin());
        ui->ClientlistWidget->addItem(items);

        connect(websockets,&QWebSocket::disconnected,this,[websockets,this]()
                {
            ui->meslistedit->append(websockets->origin()+"客户端已经断开服务器");
            websocketlist.removeOne(websockets);
            for (int i = 0; i < ui->ClientlistWidget->count(); ++i) {
                QListWidgetItem *item=ui->ClientlistWidget->item(i);
                if(item->text()==websockets->origin())
                {
                    ui->ClientlistWidget->removeItemWidget(item);
                    delete item;
                    break;
                }
            }
            websockets->deleteLater();
        });
        connect(websockets,&QWebSocket::textMessageReceived,this,&Widget::receiveMsg);
        connect(websockets,&QWebSocket::errorOccurred,this,&Widget::onerrrofn);

    }
}

void Widget::receiveMsg(const QString &msg)
{
    QJsonDocument doc=QJsonDocument::fromJson(msg.toLatin1().data());
    if(doc.isNull())
    {
        QWebSocket *websocket=qobject_cast<QWebSocket*>(sender());
        ui->meslistedit->append("接收到客户端信息["+websocket->origin()+"]-->"+msg);
    }else
    {
        QJsonObject jdo=doc.object();
        QString dst=jdo["dst:"].toString();
        for(auto socket:websocketlist)
        {
            if(dst==socket->origin())
            {
                socket->sendTextMessage(msg);
            }
        }
    }
}

void Widget::onerrrofn(QAbstractSocket::SocketError error)
{
    QWebSocket *websocket=qobject_cast<QWebSocket*>(sender());
    ui->meslistedit->append(websocket->origin()+"出错"+websocket->errorString());
}

void Widget::on_sendbtn_clicked()
{
    QString msg=ui->sendmsgedit->toPlainText().trimmed();
    if(msg.isEmpty())
    {
        return;
    }
    if(ui->sendallmsgbtn->isChecked())
    {
        if(websocketlist.size()==0)
        {
            return;
        }
        for(auto socket:websocketlist)
        {
            socket->sendTextMessage(msg);
        }
        ui->meslistedit->append("服务器给所有连接发送:"+msg);
    }else
    {
        if(!ui->ClientlistWidget->currentItem())
        {
            return;
        }
        QString current=ui->ClientlistWidget->currentItem()->text();
        QWebSocket *websocket=nullptr;
        for(auto socket:websocketlist)
        {
            if(socket->origin()==current)
            {
                websocket=socket;
                break;
            }
        }
        if(websocket)
        {
            websocket->sendTextMessage(current);
            ui->meslistedit->append("服务器给["+websocket->origin()+"信息]"+msg);
        }
    }
}


websocketclient

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QAbstractSocket>
#include <QWebSocket>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>

class QWebSocket;
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;

private:
    Ui::Widget *ui;

    QWebSocket* websocket;
    void receviedMsg(const QString&);
    bool isConnect=false;
private slots:
    void onErrorFn(QAbstractSocket::SocketError error);
    void on_connectserverbtn_clicked();
    void on_sendmsgbtn_clicked();
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    websocket=nullptr;
}

Widget::~Widget()
{
    delete ui;
    if(websocket)
        websocket->close();
}

void Widget::receviedMsg(const QString &msg)
{
    QJsonDocument doc=QJsonDocument::fromJson(msg.toLatin1().data());
    if(doc.isNull())
    {
        ui->sendmsglistedit->append("接收消息:"+msg);
    }
    else
    {
        QJsonObject json=doc.object();
        ui->sendmsglistedit->append("收到来自"+json["SRC"].toString()+"的消息:"+json["MSG"].toString());
    }
}

void Widget::onErrorFn(QAbstractSocket::SocketError error)
{
    ui->sendmsglistedit->append(websocket->origin()+"出错"+websocket->errorString());
}

void Widget::on_connectserverbtn_clicked()
{
    if(!websocket)
    {
        if(ui->servernameedit->text().trimmed().isEmpty())
        {
            QMessageBox::information(this,"提示","服务器名称不能为空",QMessageBox::Yes);
            return;
        }
        websocket=new QWebSocket(ui->servernameedit->text().trimmed(),QWebSocketProtocol::VersionLatest,this);
        connect(websocket,&QWebSocket::connected,this,[this]
                {
            ui->sendmsglistedit->append("已连接上"+websocket->peerAddress().toString());
            isConnect=true;
            ui->connectserverbtn->setText("断开服务器");
        });
        connect(websocket,&QWebSocket::disconnected,this,[this]
                {
            ui->sendmsglistedit->append(websocket->peerAddress().toString()+"已断开连接");
            isConnect=false ;
            ui->connectserverbtn->setText("连接服务器");
        });
        connect(websocket,&QWebSocket::errorOccurred,this,&Widget::onErrorFn);
        connect(websocket,&QWebSocket::textMessageReceived,this,&Widget::receviedMsg);
    }
    if(!isConnect)
    {
        websocket->open(QUrl(ui->serveraddressedit->text().trimmed()));
    }
    else
    {
        websocket->close();
        websocket->deleteLater();
        websocket=nullptr;
    }
}


void Widget::on_sendmsgbtn_clicked()
{
    if(!websocket||!websocket->isValid())
    {
        return;
    }
    QString str=ui->sendmsgedit->toPlainText().trimmed();
    if(str.isEmpty())
    {
        return;
    }
    QString strclient=ui->lineEdit->text().trimmed();
    if(strclient.isEmpty())
    {
        websocket->sendTextMessage(str);
        ui->sendmsglistedit->append("发送消息:"+str);
    }
    else
    {
        QJsonObject json;
        json["src"]=websocket->origin();
        json["dst"]=strclient;
        json["msg"]=str;
        websocket->sendTextMessage(QString(QJsonDocument(json).toJson(QJsonDocument::Compact)));
        ui->sendmsglistedit->append("给客户端"+strclient+"发送消息:"+str);
    }
    ui->sendmsgedit->clear();
}


image-20260614105531408

posted on 2026-06-17 17:50  菜鸟-~  阅读(8)  评论(0)    收藏  举报