Qt的复杂代理使用总结

简介: Qt的复杂代理使用总结

代理的基本使用


一般代理只需要继承QStyledItemDelegate类,然后重写createEditor,setEditorData和setModelData接口即可。

// COpratorDelegate.h
class COpratorDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit COpratorDelegate(QObject *parent = nullptr, const ColType &type=STRING);
    QWidget *createEditor(QWidget *parent,  const QStyleOptionViewItem &option,
                                   const QModelIndex &index) const override;
    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    void setModelData(QWidget *editor,  QAbstractItemModel *model,
                              const QModelIndex &index) const override;
private:
    CModel *_pModel = nullptr;
};


在createEditor中创建控件,然后返回,在setEditorData中从模型中获取数据,然后填充到控件中,setModelData从控件中获取数据设置到model中。


在view中使用代理,如下:

COpratorDelegate *pCOD = new COpratorDelegate(_pTableView, COpratorDelegate::MULBTN);
_pTableView->setItemDelegateForColumn(1, pCOD);


在代理中使用复杂控件


在代理中使用复杂控件,比如使用布局添加多个控件,如下:

// 创建一个多按键的QWidget页面, MulBtnWiget.h
class MulBtnWiget : public QWidget
{
    Q_OBJECT
public:
    explicit MulBtnWiget(const QModelIndex &index, QWidget *parent = nullptr);
    void setBtnData(const QVariant &data);
signals:
    void btnColor(const QString &color, const int &row);
private:
    QPushButton *_pButton1;
    QPushButton *_pButton2;
    QPushButton *_pButton3;
    QModelIndex _index;
};


此页面包含三个按钮,分别为红色,绿色和重置,用来改变颜色,如下:

MulBtnWiget::MulBtnWiget(const QModelIndex &index, QWidget *parent/* = nullptr*/)
    : QWidget(parent), _index(index)
{
    QHBoxLayout *pLayout = new QHBoxLayout();
    _pButton1 = new QPushButton("red");
    pLayout->addWidget(_pButton1);
    _pButton2 = new QPushButton("green");
    pLayout->addWidget(_pButton2);
    _pButton3 = new QPushButton("reset");
    pLayout->addWidget(_pButton3);
    pLayout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(pLayout);
    this->setContentsMargins(0, 0, 0, 0);
    _pButton1->setEnabled(false);
    _pButton2->setEnabled(false);
    _pButton3->setEnabled(false);
    _pButton1->setStyleSheet("color: red;");
    _pButton2->setStyleSheet("color: green;");
    _pButton3->setStyleSheet("color: black;");
    connect(_pButton1, &QPushButton::clicked, this, [this](){
        emit btnColor("red", _index.row());
    });
    connect(_pButton2, &QPushButton::clicked, this, [this](){
        emit btnColor("green", _index.row());
    });
    connect(_pButton3, &QPushButton::clicked, this, [this](){
        emit btnColor("black", _index.row());
    });
}


创建了这个页面之后,可以使用这个页面作为代理,使用的方式非常简单,直接new出来,然后返回即可:

QWidget *COpratorDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &option,
                                        const QModelIndex &index) const
{
    MulBtnWiget *pMulBtnWidget = new MulBtnWiget(index, parent);
    return pMulBtnWidget;
}


使用这种方式既可以使用复杂的控件代理,如果需要使用数据进行设置,只需要定义一个数据类,然后注册,如下:

struct Person
{
    int id;
    QString name;
    qint8 age;
 };
 Q_DECLARE_METATYPE(Person)


但是这种情况只有在双击的时候代理才会显示,如果需要一直显示,或者在标题栏中是无法实现的。


让代理一直显示


使用自绘的方式


使用自绘的方式主要是paint和editorEvent两个接口,自己手动绘制,这种方式最原始的方案,但是面对复杂的布局和多个控件的时候就比较麻烦。如下:


还可以参考Qt的例子: Star Delegate example 的实现,网上大部分添加一直显示的控件就是使用此方式实现的。


使用View的接口设置一直显示


针对代理一直显示,Qt的View中三个接口能完成此事,分别为: openPersistentEditor(), closePersistentEditor() 和 isPersistentEditorOpen()方法。使用方法非常简单:

_pTableView->openPersistentEditor(pModel->index(1, 1));


比如需要给某一列进行设置就可以使用循环遍历所有列进行设置即可。但是,在使用排序过滤QSortFilterProxyModel会导致设置的一直显示失效, 主要原因在于通过_pTableView->model()获取的model已经是QSortFilterProxyModel,因此设置的索引不对,排序过滤后导致,需要将真正的数据类模型指针传递到代理中,并且过滤时手动调用openPersistentEditor接口。


最终实现的结果展示



至于自定义QHeaderView参考: https://blog.csdn.net/beichen_yx/article/details/105599995


示例代码


// CDelegate.h
#ifndef CDELEGATE_H
#define CDELEGATE_H
#include <QObject>
#include <QStyledItemDelegate>
#include <QWidget>
#include <QComboBox>
#include <QProgressBar>
class QWidget;
class QVariant;
class QPushButton;
class CModel;
class MulBtnWiget : public QWidget
{
    Q_OBJECT
public:
    explicit MulBtnWiget(const QModelIndex &index, QWidget *parent = nullptr);
    void setBtnData(const QVariant &data);
signals:
    void btnColor(const QString &color, const int &row);
private:
    QPushButton *_pButton1;
    QPushButton *_pButton2;
    QPushButton *_pButton3;
    QModelIndex _index;
};
class COpratorDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    enum ColType {
        STRING,
        COMBOBOX,
        PROGRESSBAR,
        MULBTN
    };
    explicit COpratorDelegate(QObject *parent = nullptr, const ColType &type=STRING);
    QWidget *createEditor(QWidget *parent,
                          const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;
    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    void setModelData(QWidget *editor,
                      QAbstractItemModel *model,
                      const QModelIndex &index) const override;
    void setCModel(CModel * const pModel) { _pModel = pModel; }
signals:
    void btnColor(const QString &color, const QModelIndex &index);
private:
    CModel *_pModel = nullptr;
    ColType _colType = STRING;
};
#endif // CDELEGATE_H
#include "CDelegate.h"
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVariant>
#include "CModel/CModel.h"
MulBtnWiget::MulBtnWiget(const QModelIndex &index, QWidget *parent/* = nullptr*/)
    : QWidget(parent), _index(index)
{
    QHBoxLayout *pLayout = new QHBoxLayout();
    _pButton1 = new QPushButton("red");
    pLayout->addWidget(_pButton1);
    _pButton2 = new QPushButton("green");
    pLayout->addWidget(_pButton2);
    _pButton3 = new QPushButton("reset");
    pLayout->addWidget(_pButton3);
    pLayout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(pLayout);
    this->setContentsMargins(0, 0, 0, 0);
    _pButton1->setEnabled(false);
    _pButton2->setEnabled(false);
    _pButton3->setEnabled(false);
    _pButton1->setStyleSheet("color: red;");
    _pButton2->setStyleSheet("color: green;");
    _pButton3->setStyleSheet("color: black;");
    connect(_pButton1, &QPushButton::clicked, this, [this](){
        emit btnColor("red", _index.row());
    });
    connect(_pButton2, &QPushButton::clicked, this, [this](){
        emit btnColor("green", _index.row());
    });
    connect(_pButton3, &QPushButton::clicked, this, [this](){
        emit btnColor("black", _index.row());
    });
}
void MulBtnWiget::setBtnData(const QVariant &data)
{
    int type = qvariant_cast<int>(data);
    if (type <= 3) {
        _pButton1->setEnabled(true);
        _pButton2->setEnabled(true);
        _pButton3->setEnabled(true);
        _pButton1->setStyleSheet("color: red;");
        _pButton2->setStyleSheet("color: green;");
    } else if (type >3 && type <=4) {
        _pButton1->setEnabled(false);
        _pButton1->setStyleSheet("color: black;");
        _pButton2->setEnabled(true);
        _pButton3->setEnabled(true);
    } else {
        _pButton1->setEnabled(true);
        _pButton2->setEnabled(false);
        _pButton2->setStyleSheet("color: black;");
        _pButton3->setEnabled(true);
    }
}
COpratorDelegate::COpratorDelegate(QObject *parent/* = nullptr*/,
                                   const ColType &type/*=STRING*/)
    : QStyledItemDelegate(parent),
      _colType(type)
{
}
QWidget *COpratorDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &option,
                                        const QModelIndex &index) const
{
    if (_colType == STRING) {
        return QStyledItemDelegate::createEditor(parent, option, index);
    } else if (_colType == COMBOBOX) {
        auto *pCbx = new QComboBox(parent);
        pCbx->addItems({"test1", "test1", "test2", "test3"});
        return pCbx;
    } else if (_colType == PROGRESSBAR) {
        auto *pProgressbar = new QProgressBar(parent);
        pProgressbar->setRange(0, 10);
        return pProgressbar;
    } else if (_colType == MULBTN) {
        MulBtnWiget *pMulBtnWidget = new MulBtnWiget(index, parent);
        connect(pMulBtnWidget, &MulBtnWiget::btnColor, this,
                [this](const QString &color, const int &row){
            // index.model()返回的模型不一定是自定义的数据模型,可能是代理模型
            if (_pModel == nullptr) { return; }
            _pModel->setRowColor(row, color);
        });
        return pMulBtnWidget;
    } else {
        return QStyledItemDelegate::createEditor(parent, option, index);
    }
}
void COpratorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if (_colType == STRING) {
    } else if (_colType == COMBOBOX) {
        QComboBox *pWidget = qobject_cast<QComboBox*>(editor);
        auto tmp = QString::number(index.data().toInt());
        if (pWidget->findText(tmp) < 0) {
            pWidget->addItem(tmp);
        }
        pWidget->setCurrentText(tmp);
    } else if (_colType == PROGRESSBAR) {
        QProgressBar *pWidget = qobject_cast<QProgressBar*>(editor);
        pWidget->setValue(index.data().toInt());
    } else if (_colType == MULBTN) {
        MulBtnWiget *pWidget = qobject_cast<MulBtnWiget*>(editor);
        pWidget->setBtnData(index.data());
    } else {
    }
}
void COpratorDelegate::setModelData(QWidget *editor,
                                    QAbstractItemModel *model,
                                    const QModelIndex &index) const
{
    QStyledItemDelegate::setModelData(editor, model, index);
}
#include "CDelegate.h"
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVariant>
#include "CModel/CModel.h"
MulBtnWiget::MulBtnWiget(const QModelIndex &index, QWidget *parent/* = nullptr*/)
    : QWidget(parent), _index(index)
{
    QHBoxLayout *pLayout = new QHBoxLayout();
    _pButton1 = new QPushButton("red");
    pLayout->addWidget(_pButton1);
    _pButton2 = new QPushButton("green");
    pLayout->addWidget(_pButton2);
    _pButton3 = new QPushButton("reset");
    pLayout->addWidget(_pButton3);
    pLayout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(pLayout);
    this->setContentsMargins(0, 0, 0, 0);
    _pButton1->setEnabled(false);
    _pButton2->setEnabled(false);
    _pButton3->setEnabled(false);
    _pButton1->setStyleSheet("color: red;");
    _pButton2->setStyleSheet("color: green;");
    _pButton3->setStyleSheet("color: black;");
    connect(_pButton1, &QPushButton::clicked, this, [this](){
        emit btnColor("red", _index.row());
    });
    connect(_pButton2, &QPushButton::clicked, this, [this](){
        emit btnColor("green", _index.row());
    });
    connect(_pButton3, &QPushButton::clicked, this, [this](){
        emit btnColor("black", _index.row());
    });
}
void MulBtnWiget::setBtnData(const QVariant &data)
{
    int type = qvariant_cast<int>(data);
    if (type <= 3) {
        _pButton1->setEnabled(true);
        _pButton2->setEnabled(true);
        _pButton3->setEnabled(true);
        _pButton1->setStyleSheet("color: red;");
        _pButton2->setStyleSheet("color: green;");
    } else if (type >3 && type <=4) {
        _pButton1->setEnabled(false);
        _pButton1->setStyleSheet("color: black;");
        _pButton2->setEnabled(true);
        _pButton3->setEnabled(true);
    } else {
        _pButton1->setEnabled(true);
        _pButton2->setEnabled(false);
        _pButton2->setStyleSheet("color: black;");
        _pButton3->setEnabled(true);
    }
}
COpratorDelegate::COpratorDelegate(QObject *parent/* = nullptr*/,
                                   const ColType &type/*=STRING*/)
    : QStyledItemDelegate(parent),
      _colType(type)
{
}
QWidget *COpratorDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &option,
                                        const QModelIndex &index) const
{
    if (_colType == STRING) {
        return QStyledItemDelegate::createEditor(parent, option, index);
    } else if (_colType == COMBOBOX) {
        auto *pCbx = new QComboBox(parent);
        pCbx->addItems({"test1", "test1", "test2", "test3"});
        return pCbx;
    } else if (_colType == PROGRESSBAR) {
        auto *pProgressbar = new QProgressBar(parent);
        pProgressbar->setRange(0, 10);
        return pProgressbar;
    } else if (_colType == MULBTN) {
        MulBtnWiget *pMulBtnWidget = new MulBtnWiget(index, parent);
        connect(pMulBtnWidget, &MulBtnWiget::btnColor, this,
                [this](const QString &color, const int &row){
            // index.model()返回的模型不一定是自定义的数据模型,可能是代理模型
            if (_pModel == nullptr) { return; }
            _pModel->setRowColor(row, color);
        });
        return pMulBtnWidget;
    } else {
        return QStyledItemDelegate::createEditor(parent, option, index);
    }
}
void COpratorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if (_colType == STRING) {
    } else if (_colType == COMBOBOX) {
        QComboBox *pWidget = qobject_cast<QComboBox*>(editor);
        auto tmp = QString::number(index.data().toInt());
        if (pWidget->findText(tmp) < 0) {
            pWidget->addItem(tmp);
        }
        pWidget->setCurrentText(tmp);
    } else if (_colType == PROGRESSBAR) {
        QProgressBar *pWidget = qobject_cast<QProgressBar*>(editor);
        pWidget->setValue(index.data().toInt());
    } else if (_colType == MULBTN) {
        MulBtnWiget *pWidget = qobject_cast<MulBtnWiget*>(editor);
        pWidget->setBtnData(index.data());
    } else {
    }
}
void COpratorDelegate::setModelData(QWidget *editor,
                                    QAbstractItemModel *model,
                                    const QModelIndex &index) const
{
    QStyledItemDelegate::setModelData(editor, model, index);
}
#include "CModel/CModel.h"
#include <ctime>
#include <algorithm>
#include <QDebug>
CModel::CModel(QAbstractItemModel *parent) : QAbstractItemModel(parent)
{
    for (int i=0; i<10; ++i) {
        m_stocks.append({i, i*100, rand() % 100, rand() % 300, i, i});
        _colors.append(QColor(Qt::black));
    }
}
void CModel::setRowColor(const int &row, const QString &color)
{
    QColor txtColor;
    if (color == "red") {
        txtColor = Qt::red;
    } else if (color == "green") {
        txtColor = Qt::green;
    } else {
        txtColor = Qt::black;
    }
    _colors[row] = txtColor;
    auto start = this->index(row, 0);
    auto end = this->index(row, this->columnCount(QModelIndex()) - 1);
    emit dataChanged(start, end);
}
int CModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_stocks.length();
}
int CModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_names.length();
}
QVariant CModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid()){
        qDebug() << "index is valid: " << index.row() << ":" << index.column();
        return QVariant();
    }
    if(index.row() > m_stocks.length() || index.column() > m_names.length()){
        qDebug() << "m_stocks len: " << m_stocks.length() << " " << index.row() << ":" << index.column();
        return QVariant();
    }
    if(role == Qt::DisplayRole){
        auto stock = m_stocks.at(index.row());
        return (index.column() > stock.length() || index.column() < 0) ? QVariant() : stock.at(index.column());
    } else if(role == Qt::EditRole){
        auto stock = m_stocks.at(index.row());
        return (index.column() > stock.length() || index.column() < 0) ? QVariant() : stock.at(index.column());
    } else if (role == Qt::TextColorRole) {
        return QVariant(_colors.at(index.row()));
    } else if (role == Qt::TextAlignmentRole) {
        return QVariant(Qt::AlignCenter|Qt::AlignVCenter);
    }
    return QVariant();
}
bool CModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid()){
        qDebug() << "index is valid: " << index.row() << ":" << index.column();
        return false;
    }
    if(role == Qt::EditRole){
        auto stock = m_stocks.at(index.row());
        stock[index.column()] = value;
        emit dataChanged(index, index);
        return true;
    }
    return false;
}
QVariant CModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//    if(role != Qt::DisplayRole){
//        return QVariant();
//    }
//    if(orientation == Qt::Horizontal){
//        if(section < 0 || section > m_names.length()){return  QVariant();}
//        return QVariant(m_names.at(section));
//    }else {
//        return QVariant(QString::number(section));
//    }
    if(orientation == Qt::Horizontal){
        if (role == Qt::DisplayRole) {
            return QVariant(m_names.at(section));
        } else {
           qDebug() << role;
        }
    } else if (orientation == Qt::Vertical) {
        if (role == Qt::DisplayRole) {
            return QVariant(QString::number(section));
        }
    }
    return QVariant();
}
bool CModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
    if(role != Qt::EditRole){
        return false;
    }
    if(orientation == Qt::Horizontal){
        m_names.replace(section, value.toString());
        emit headerDataChanged(Qt::Horizontal, section, section);
        return true;
    }else{
        return false;
    }
}
Qt::ItemFlags CModel::flags(const QModelIndex &index) const
{
//    if(index.isValid()){
//         Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren | Qt::ItemIsEditable;
//         return flags;
//    }
//    return QAbstractItemModel::flags(index);
    if(index.isValid()){
        Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable
                | Qt::ItemNeverHasChildren | Qt::ItemIsEditable;
        return flags | QAbstractItemModel::flags(index);
    }
    return QAbstractItemModel::flags(index);
}
QModelIndex CModel::index(int row, int column, const QModelIndex &parent) const
{
    if (row < 0 || column < 0 || column >= columnCount(parent) || column > m_names.length())
        return QModelIndex();
    return createIndex(row,column);
}
QModelIndex CModel::parent(const QModelIndex &child) const
{
    Q_UNUSED(child);
    return QModelIndex();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "CView/CTableView.h"
#include "CModel/CModel.h"
#include "CDelegate/CDelegate.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    _pTableView(new CTableView(this)),
    _pModel(new CModel())
{
    ui->setupUi(this);
    this->setWindowTitle("Custom MVC");
    this->setCentralWidget(_pTableView);
    this->setContentsMargins(0, 0, 0, 0);
    _pTableView->setModel(_pModel);
    this->initUi();
    this->resize(1024, 768);
}
MainWindow::~MainWindow()
{
    delete ui;
    delete _pModel;
    delete _pTableView;
}
void MainWindow::initUi()
{
    int colCount = _pModel->columnCount(_pModel->index(0, 0));
    _pTableView->resizeColumnsToContents();
    for (int i=0; i<colCount; ++i) {
        _pTableView->setColumnWidth(i, 300);
    }
    COpratorDelegate *pCOD = new COpratorDelegate(_pTableView, COpratorDelegate::MULBTN);
    pCOD->setCModel(_pModel);
    _pTableView->setItemDelegateForColumn(colCount - 1, pCOD);
    auto *pModel = _pTableView->model();
    int row = pModel->rowCount();
    for (int i=0; i<row; ++i) {
        _pTableView->openPersistentEditor(pModel->index(i, colCount - 1));
    }
    _columns.append(colCount - 1);
    COpratorDelegate *pProcessCOD = new COpratorDelegate(_pTableView, COpratorDelegate::PROGRESSBAR);
    pProcessCOD->setCModel(_pModel);
    _pTableView->setItemDelegateForColumn(colCount - 2, pProcessCOD);
    for (int i=0; i<row; ++i) {
        _pTableView->openPersistentEditor(pModel->index(i, colCount - 2));
    }
    _columns.append(colCount - 2);
    COpratorDelegate *pCbxCOD = new COpratorDelegate(_pTableView, COpratorDelegate::COMBOBOX);
    pCbxCOD->setCModel(_pModel);
    _pTableView->setItemDelegateForColumn(colCount - 3, pCbxCOD);
    for (int i=0; i<row; ++i) {
        _pTableView->openPersistentEditor(pModel->index(i, colCount - 3));
    }
    _columns.append(colCount - 3);
    connect(_pTableView, &CTableView::filterUpdate, this,  &MainWindow::openPersistentForColumns );
}
void MainWindow::openPersistentForColumns()
{
    auto *pModel = _pTableView->model();
    int row = _pModel->rowCount();
    for (int i=0; i<row; ++i) {
        for (int &col : _columns) {
            _pTableView->openPersistentEditor(pModel->index(i, col));
        }
    }
}


详细代码参见: https://gitee.com/BeiChen_XQ/custom-delegate.git

相关文章
|
5月前
|
搜索推荐 C++ 索引
C++ Qt开发:QItemDelegate自定义代理组件
在Qt中,`QStyledItemDelegate` 类是用于创建自定义表格视图(如`QTableView`和`QTableWidget`)的委托类,允许你自定义表格中每个单元格的外观和交互。`QStyledItemDelegate` 是`QItemDelegate` 的子类,提供了更现代、更易用的接口。此处我们将实现对`QTableView`表格组件的自定义代理功能,例如默认情况下表格中的缺省代理就是一个编辑框,我们只能够在编辑框内输入数据,而有时我们想选择数据而不是输入,此时就需要重写编辑框实现选择的效果,代理组件常用于个性化定制表格中的字段类型。
41 0
C++ Qt开发:QItemDelegate自定义代理组件
|
4月前
Qt表格中的自定义编辑组件---------------自定义代理QStyledItemDelegate
Qt表格中的自定义编辑组件---------------自定义代理QStyledItemDelegate
31 5
|
SQL 关系型数据库 数据库连接
2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
 Linux下的qt安装,命令时:sudoapt-get install qt-sdk 安装mysql数据库,安装方法参考博客:http://blog.csdn.net/tototuzuoquan/article/details/39565783 如果行想进数据库开发,需要安装libqt5sql5-mysql.命令是: sudo apt-g
4327 0
|
2月前
|
算法 编译器 Linux
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
25 0
|
2月前
|
网络协议 C++
C++ Qt开发:QTcpSocket网络通信组件
`QTcpSocket`和`QTcpServer`是Qt中用于实现基于TCP(Transmission Control Protocol)通信的两个关键类。TCP是一种面向连接的协议,它提供可靠的、双向的、面向字节流的通信。这两个类允许Qt应用程序在网络上建立客户端和服务器之间的连接。Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QTcpSocket`组件实现基于TCP的网络通信功能。
44 8
C++ Qt开发:QTcpSocket网络通信组件
|
13天前
|
开发框架 编译器 C++
Qt:一个强大的跨平台C++应用程序开发框架
Qt:一个强大的跨平台C++应用程序开发框架
30 1
|
13天前
|
开发框架 Linux C++
Qt:强大的跨平台C++应用程序开发框架
Qt:强大的跨平台C++应用程序开发框架
44 3
|
17天前
|
开发框架 数据可视化 编译器
Qt的魅力:探索跨平台图形界面开发之旅
Qt的魅力:探索跨平台图形界面开发之旅
30 1
|
1月前
|
图形学 Python 容器
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
53 0

推荐镜像

更多