关于Arm开发板中的利用wpa_supplicant与Qt的MVC模式做一个关于wifi的配饰界面

关于wpa_supplicant这块的代码,基本可以参考https://blog.csdn.net/Dr_Abel/article/details/51335599,对其中做了部分的修改。

主要是记录一下Qt的模型/视图编程,可以先看一下演示效果:

主要的wifi参数有强度 ,ssid,与连接状态,数据的显示时使用QTableview显示,采用模型/视频编程,下面上这部分代码

mainwindow界面代码:

#include "../NetworkManager/passworddialog.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    my_model = new WifiModel(this);
    mydelete = new ButtonDelegate(this);
    connect(mydelete,&ButtonDelegate::buttonclicked,this,&MainWindow::showpasswordDialg);
    connect(instance,&NetworkManager::sigRefreshed,my_model,&WifiModel::refrushModel);

    ui->wifitableView->setModel(my_model);
    ui->wifitableView->setItemDelegateForColumn(2,mydelete);
    ui->wifitableView->show();

}

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

void MainWindow::showpasswordDialg(QString bssid)
{
    QDialog *d = new PasswordDialog(this,bssid);
    d->setWindowModality(Qt::WindowModal);

    d->show();
}

这部分代码很好理解,通过给wifitableview部件设置数据模型my_model,与将Tableview表中的第三列委托成按键控件ButtonDelegate,使其能够通过按钮控件患处QDialog窗口,通过内部lineEdit唤出输入法插件,这里用的是goole的一个输入法插件。

 

my_model部分代码:

#include "wifimodel.h"

WifiModel::WifiModel(QObject *parent)
    : QAbstractTableModel(parent)
{
    m_header<<tr("强度")<<tr("名称")<<tr("状态");
}

QVariant WifiModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    // FIXME: Implement me!
    if(role==Qt::DisplayRole&&orientation==Qt::Horizontal)
    {

        return m_header[section];
    }

    return QAbstractTableModel::headerData(section,orientation,role);
}

int WifiModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    //return 3;
    return instance->wifiList().size();

}

int WifiModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return 3;
}

QVariant WifiModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    if(role == Qt::DisplayRole)
    {
        QString value;
        switch (index.column()) {
        case 0:
        value = instance->wifiList().operator[](index.row()).operator[](ESSID_SIGNAL);
        break;

        case 1:
        value = instance->wifiList().operator[](index.row()).operator[](ESSID_NAME);
        break;

        default:
        break;

        }
        return value;

    }

    return QVariant();
}

void WifiModel::refrushModel()
{
    beginResetModel();
    endResetModel();
}

关于model这块,其中headerData是表头函数,用于配置表格的表头,这里用三列,m_header<<tr("强度")<<tr("名称")<<tr("状态");rowCount与columnCount返回行列与竖列,其中竖列就是插入的表头个数,行列数是通过wpa_supplicant代码模块搜索到的wifi个数。

data函数尤为重要,用于精确的返回表中显示的数据。其中refrushModel用于刷新数据,主要是刷新界面使用。

 

关于delegate部分的代码

#include "buttondelegate.h"
#include <QDebug>
#include <QMouseEvent>
#include <QDialog>
#include <QDesktopWidget>
#include "passworddialog.h"

const int FILE_OPERATE_COLUMN = 2;//按键所在列

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

}

ButtonDelegate::~ButtonDelegate()
{
    QMap<QModelIndex, QStyleOptionButton*>::iterator it;
    for (it = m_btns.begin();it != m_btns.end(); it++)
    {
        if(it.value() != nullptr)
        {
            delete it.value();
            it.value() = nullptr;
        }
    }
}

void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //在特定的索引处绘制按键,这个变量临时存储绘制的按键信息
    QStyleOptionButton* button = m_btns.value(index);
    //如果为按键列绘制按键
    if (index.column() == FILE_OPERATE_COLUMN) {
        //进行判断,如果是Map容器中没有,则为它动态分配内存
        if(button == nullptr)
        {
            button = new QStyleOptionButton();//绘制存button的参数的对象
            button->features = QStyleOptionButton::None;//设置为pushButton类型,可以按下
            button->rect = option.rect.adjusted(1, 1, -1, -1);//绘制尺寸

            button->state |= QStyle::State_Enabled;
            (const_cast<ButtonDelegate *>(this))->m_btns.insert(index, button);//将绘制的按键放入Qmap
        }

        if(instance->wifiList().operator[](index.row()).operator[](ESSID_STATUS) != "COMPLETED")
        {
            button->text = tr("连接");
        }
        else {
            button->text = tr("已连接");
        }
    }

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

    QApplication::style()->drawControl(QStyle::CE_PushButton, button, painter);
}

bool ButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonPress)
    {

        QMouseEvent* e =(QMouseEvent*)event;
        //确定鼠标点击的位置在画的按键中
        if (option.rect.adjusted(1, 1, -1, -1).contains(e->x(), e->y()) && m_btns.contains(index))
        {
            qDebug()<<"--------";
            m_btns.value(index)->state |= QStyle::State_Sunken;

        }
    }
    if (event->type() == QEvent::MouseButtonRelease)
    {
        //qDebug()<<"++++++++";
        QMouseEvent* e =(QMouseEvent*)event;
        if (option.rect.adjusted(1, 1, -1, -1).contains(e->x(), e->y()) && m_btns.contains(index))
        {
            m_btns.value(index)->state &= (~QStyle::State_Sunken);
            emit buttonclicked(instance->wifiList().operator[](index.row()).operator[](ESSID_BSSID));
        }
    }
    return true;
}

关于Button控件的委托,要想控件一开始就显示在Tableview上,需要重写paint代码,同时对于事件编辑器editorEvent需要重写按键事件。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值