Qt tabview 批量升级UI

最近对某位老哥的《Qt 自定义委托--实现批量升级UI》进行了学习以及一些补充

  1. Qt模型视图采用类MVC框架,那什么是MVC框架?

    • M--模型:负责组织数据

    • V--试图:负责显示数据

    • C--控制:负责用户输入

 

 模型视图中的委托:①委托是视图中处理用户输入的部件。②视图可以设置委托对象用于用户输入。③委托对象负责创建和显示用户输入上下文

整体实现结果:

 UI界面的配置:

    其中整体控件布局 垂直layout中,且水平策略:Expanding  垂直策略:Expanding, 其他控件最小长度,最小高度设置下,这样在拉伸窗口时整体控件大小可均匀的拉伸。

 源码:

/*************************mainwindow.h**********************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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



private slots:
    void on_allCheckBox_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
/********************************mainwindow.cpp***************************/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qricetableview.h"
#include "QTimer"

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

     setWindowTitle(tr("水火汪"));

       struct QRiceTableView::tableItemInfo info;
       info.name = tr("RiceChen");
       info.age = tr("18");
       info.work = tr("程序员");
       ui->tableView->QRiceTableAddItem(0, &info);

       info.name = tr("米饭");
       info.age = tr("20");
       info.work = tr("公务员");
       ui->tableView->QRiceTableAddItem(1, &info);

       QTimer * timer = new QTimer(this);
       connect(timer,&QTimer::timeout,[=](){
               static int Progress1 = 0;
               static int Progress2 = 0;

               ui->tableView->QRiceTableSetProgress(0, Progress1);
               ui->tableView->QRiceTableSetProgress(1, Progress2);
               Progress1 += 1;
               Progress2 += 2;
               if(Progress1 > 100)
               {
                   Progress1 = 0;
               }
               if(Progress2 > 100)
               {
                   Progress2 = 0;
               }
       });
       timer->start(1000);
 }


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



void MainWindow::on_allCheckBox_clicked()
{
    for(int row = 0; row < ui->tableView->QRiceTableGetRow(); row++)
        {
            if(ui->allCheckBox->checkState() == Qt::Checked)
            {
                ui->tableView->QRiceTableSetSelect(row, true);
            }
            else
            {
                ui->tableView->QRiceTableSetSelect(row, false);
            }
        }
}
/******************************qricebuttondelegate.h**********************/
#ifndef QRICEBUTTONDELEGATE_H
#define QRICEBUTTONDELEGATE_H

#include <QItemDelegate>

class QRiceButtonDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit QRiceButtonDelegate(QObject *parent = nullptr);
    ~QRiceButtonDelegate();

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
signals:

private:
    void showMsg(QString str);

private:
    typedef QMap<QModelIndex, QStyleOptionButton* > collButtons;
    collButtons buttonDelegate;
};

#endif // QRICEBUTTONDELEGATE_H
/*************************************qricebuttondelegate.cpp**************/
#include "qricebuttondelegate.h"
#include <qevent.h>
#include <QPainter>
#include <QApplication>
#include <QMessageBox>


QRiceButtonDelegate::QRiceButtonDelegate(QObject *parent)
    : QItemDelegate(parent)
{

}

QRiceButtonDelegate::~QRiceButtonDelegate()
{

}



void QRiceButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionButton *buttonStyle = buttonDelegate.value(index);
    if(!buttonStyle)
    {
        buttonStyle = new QStyleOptionButton();          // 创建按钮项样式
        buttonStyle->text = "Update";                    // 设置按钮中显示的内容
        buttonStyle->state |= QStyle::State_Enabled;     // 设置按钮中的状态
        (const_cast<QRiceButtonDelegate *>(this))->buttonDelegate.insert(index, buttonStyle);
    }
    buttonStyle->rect = option.rect.adjusted(4, 4, -4, -4); //设置按钮的大小
    painter->save();

    if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());
    }

    painter->restore();
    QApplication::style()->drawControl(QStyle::CE_PushButton, buttonStyle, painter);   //绘制
}

bool QRiceButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    Q_UNUSED(model);
    Q_UNUSED(option);
    QMouseEvent *mouseEvent = (QMouseEvent *)event;

    if(event->type() == QEvent::MouseButtonPress)              // 按钮按下,设置按钮的状态
    {
        if(buttonDelegate.contains(index))
        {
            QStyleOptionButton *buttonStyle = buttonDelegate.value(index);
            if(buttonStyle->rect.contains(mouseEvent->x(), mouseEvent->y()))
            {
                buttonStyle->state |= QStyle::State_Sunken;
            }
        }
    }
    if(event->type() == QEvent::MouseButtonRelease)         // 按钮松开,设置按钮的状态
    {
        if(buttonDelegate.contains(index))
        {
            QStyleOptionButton *buttonStyle = buttonDelegate.value(index);
            if(buttonStyle->rect.contains(mouseEvent->x(), mouseEvent->y()))
            {
                buttonStyle->state &= (~QStyle::State_Sunken);
                showMsg(tr("btn1 column %1").arg(index.row()));   // 松开弹出消息框,显示对应行号
            }
        }
    }

    return true;
}

void QRiceButtonDelegate::showMsg(QString str)
{
    QMessageBox msg;
    msg.setText(str);
    msg.exec();
}
#ifndef QRICECHECKBOXDELEGATE_H
#define QRICECHECKBOXDELEGATE_H

#include <QItemDelegate>

class QRiceCheckBoxDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit QRiceCheckBoxDelegate(QObject *parent = nullptr);
    ~QRiceCheckBoxDelegate();

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
signals:

};

#endif // QRICECHECKBOXDELEGATE_H
#include "qricecheckboxdelegate.h"

#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QStyleOption>
#include <QDebug>

QRiceCheckBoxDelegate::QRiceCheckBoxDelegate(QObject *parent)
    : QItemDelegate(parent)
{

}

QRiceCheckBoxDelegate::~QRiceCheckBoxDelegate()
{

}

void QRiceCheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(QVariant::Bool == index.data(Qt::DisplayRole).type()) //如果数据类型为bool型,才绘制单选宽
    {
        QStyleOptionButton checkBox;
        checkBox.state = index.data().toBool() ? QStyle::State_On : QStyle::State_Off; //绘制后的默认状态
        checkBox.state |= QStyle::State_Enabled;
        checkBox.rect = option.rect;
        checkBox.rect.setX(option.rect.x() + option.rect.width()/2 - 6); //设置在表格中的显示位置

        QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBox, painter);   // 绘制
    }
    else
    {
        QItemDelegate::paint(painter, option, index);
    }
}

bool QRiceCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    bool ret = true;
    if(QVariant::Bool == index.data().type())
    {
        QMouseEvent* mouse = dynamic_cast<QMouseEvent*>(event);

        if( (NULL != mouse) && (QEvent::MouseButtonPress == mouse->type()) && (option.rect.contains(mouse->pos())) )
        {
            model->setData(index, !index.data().toBool(), Qt::DisplayRole); // 更新模型数据
        }
    }
    else
    {
        ret = QItemDelegate::editorEvent(event, model, option, index);
    }

    return ret;
}
#ifndef QRICEPROGRESSBARDELEGATE_H
#define QRICEPROGRESSBARDELEGATE_H

#include <QItemDelegate>

class QRiceProgressBarDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit QRiceProgressBarDelegate(QObject *parent = nullptr);
    ~QRiceProgressBarDelegate();

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
signals:

};

#endif // QRICEPROGRESSBARDELEGATE_H
#include "qriceprogressbardelegate.h"
#include <QApplication>


QRiceProgressBarDelegate::QRiceProgressBarDelegate(QObject *parent)
    : QItemDelegate(parent)
{

}

QRiceProgressBarDelegate::~QRiceProgressBarDelegate()
{

}



void QRiceProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    int progress = index.data(Qt::DisplayRole).toInt();
    QStyleOptionProgressBar progressBar;

    progressBar.minimum = 0;                                //设置进度条最小值
    progressBar.maximum = 100;                              //设置进度条最大值
    progressBar.progress = progress;                        //设置绘制后的数值
    progressBar.rect = option.rect.adjusted(4, 4, -4, -4);  //设置进度条的大小
    progressBar.textVisible = true;                         //设置进度条显示数值
    progressBar.textAlignment = Qt::AlignCenter;            //设置进度条数值显示位置
    progressBar.text = QString("%1%").arg(progress);        //设置进度条数值显示

    QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBar, painter); // 绘制
}

bool QRiceProgressBarDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    bool ret = true;

    if(QEvent::MouseButtonDblClick != event->type())
    {
        ret = QItemDelegate::editorEvent(event, model, option, index);
    }

    return ret;
}
#ifndef QRICETABLEVIEW_H
#define QRICETABLEVIEW_H

#include <QTableView>

#include <QStandardItemModel>
#include "qricecheckboxdelegate.h"
#include "qriceprogressbardelegate.h"
#include "qricebuttondelegate.h"

class QRiceTableView : public QTableView
{
    Q_OBJECT
public:
    struct tableItemInfo
    {
        QString name;
        QString age;
        QString work;
    };
public:
    explicit QRiceTableView(QWidget *parent = nullptr);
    ~QRiceTableView();

signals:

public:
    int QRiceTableGetRow(void);
    int QRiceTableGetColumn(void);
    void QRiceTableAddItem(int row, struct tableItemInfo *info);
    void QRiceTableSetProgress(int row, int Progress);
    void QRiceTableSetSelect(int row, bool select);
    bool QRiceTableGetSelect(int row);
    QString QRiceTableGetString(int row, int column);

private:
    QStandardItemModel *tableItemModel;

    QRiceCheckBoxDelegate *tableCheckBoxDelegate;
    QRiceProgressBarDelegate *tableProgressBarDelegate;
    QRiceButtonDelegate *tableButtonDelegate;
};

#endif // QRICETABLEVIEW_H
#include "qricetableview.h"
#include <QObject>
#include <QTableView>
#include <QApplication>
#include <QHeaderView>

QRiceTableView::QRiceTableView(QWidget  *parent)
                 : QTableView(parent)
{
       horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

       tableItemModel = new QStandardItemModel();
       setModel(tableItemModel);

       tableCheckBoxDelegate = new QRiceCheckBoxDelegate(this);
       setItemDelegate(tableCheckBoxDelegate);

       tableProgressBarDelegate = new QRiceProgressBarDelegate(this);
       setItemDelegateForColumn(4, tableProgressBarDelegate);

       tableButtonDelegate = new QRiceButtonDelegate(this);
       setItemDelegateForColumn(5, tableButtonDelegate);

       QStringList tableHeaders;
       tableHeaders << tr("Select")  <<tr("Name") << tr("Age") << tr("Work") << tr("Progress") << tr("Update");
       tableItemModel->setHorizontalHeaderLabels(tableHeaders);
}

QRiceTableView::~QRiceTableView()
{

}


int QRiceTableView::QRiceTableGetRow(void)
{
    return tableItemModel->rowCount();
}

int QRiceTableView::QRiceTableGetColumn(void)
{
    return tableItemModel->columnCount();
}

void QRiceTableView::QRiceTableAddItem(int row, struct tableItemInfo *info)
{
    QStandardItem* otaDeviceListStandardItem = tableItemModel->invisibleRootItem();

    QStandardItem *checkBox = new QStandardItem();
    QStandardItem *name = new QStandardItem();
    QStandardItem *age = new QStandardItem();
    QStandardItem *work = new QStandardItem();

    checkBox->setData(false, Qt::DisplayRole);
    name->setData(info->name, Qt::DisplayRole);
    age->setData(info->age, Qt::DisplayRole);
    work->setData(info->work, Qt::DisplayRole);

    otaDeviceListStandardItem->setChild(row, 0, checkBox);
    otaDeviceListStandardItem->setChild(row, 1, name);
    otaDeviceListStandardItem->setChild(row, 2, age);
    otaDeviceListStandardItem->setChild(row, 3, work);
}

void QRiceTableView::QRiceTableSetProgress(int row, int Progress)
{
    if(row < tableItemModel->rowCount())
    {
        QModelIndex index = tableItemModel->index(row, 4);
        tableItemModel->setData(index, Progress, Qt::DisplayRole);
    }
}

void QRiceTableView::QRiceTableSetSelect(int row, bool select)
{
    if(row < tableItemModel->rowCount())
    {
        QModelIndex index = tableItemModel->index(row, 0);
        tableItemModel->setData(index, select, Qt::DisplayRole);
    }
}

bool QRiceTableView::QRiceTableGetSelect(int row)
{
    if(row < tableItemModel->rowCount())
    {
        QModelIndex index = tableItemModel->index(row, 0);
        return index.data(Qt::DisplayRole).toBool();
    }
    return false;
}

QString QRiceTableView::QRiceTableGetString(int row, int column)
{
    if(row < tableItemModel->rowCount()
       && column > 0 && column < (tableItemModel->columnCount() - 2))
    {
        QModelIndex index = tableItemModel->index(row, column);
        return index.data(Qt::DisplayRole).toString();
    }
    return "";
}

整体代码结构:

 其中QRiceTableView的类需要提升,在ui界面上tabview控件点击提升窗口部件

 

 QtCreator:中文乱码解决:在pro文件增加下面一行。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要从子线程中获取数据并更新QT的TabView,您可以使用以下步骤: 1. 创建一个自定义的QObject子类,用于在主线程中处理数据更新。我们称之为DataHandler。 ```cpp class DataHandler : public QObject { Q_OBJECT public slots: void handleData(const QString& data) { // 在此处更新TabView中的数据 // 您可以使用信号和槽机制将数据传递给TabView并进行更新 } }; ``` 2. 在主线程中创建一个DataHandler对象,并将其与TabView连接起来。 ```cpp DataHandler dataHandler; QTabView tabView; QObject::connect(&dataHandler, SIGNAL(dataUpdated(QString)), &tabView, SLOT(updateData(QString))); ``` 在此示例中,我们假设TabView具有名为updateData的槽函数,用于接收并更新数据。 3. 在子线程中执行耗时操作,并在完成后将数据发送到DataHandler。 ```cpp void MyThread::run() { // 执行耗时操作 QString data = performLongOperation(); // 发送数据到主线程的DataHandler QMetaObject::invokeMethod(&dataHandler, "handleData", Qt::QueuedConnection, Q_ARG(QString, data)); } ``` 在此示例中,我们假设在子线程中执行了一个名为performLongOperation的耗时操作,并将结果存储在data变量中。然后,我们使用QMetaObject::invokeMethod将数据传递给DataHandler对象的handleData槽函数。 请注意,使用Qt的信号和槽机制,您可以在主线程中安全地更新UI元素,而无需直接在子线程中操作UI。 希望这可以帮助到您!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值