那是自家在项目实战中的个人统计,写的仓促,有些东西也不自然标准,有些是上下一心测度的,还指望各位多多指教,多多评论。

 那是自己在类型实战中的个人总括,写的匆匆,有些东西也不自然标准,有些是自己揣测的,还期待各位多多指教,多多评论。

飞速支付QCombox以及工作样式自定义,qcombox样式自定义

 那是自家在项目实战中的个人统计,写的仓促,有些东西也不肯定标准,有些是团结预计的,还希望各位多多指教,多多评论。

 关于QCombox要是不须要自定义,其实写UI是很简短的。

始建实例:QComboBox*  m_pMicrophoneCombox = new QComboBox;

自家是用的QSS去的写样式,那里用了一个命名函数:m_pMicrophoneCombox->setObjectName(“DeviceCombox”);

假倘若用的setstylesheet直接在代码里去写就好了。

上边说多少个特性函数:

m_pMicrophoneCombox->set马克斯VisibleItems(2);//最大可知区域为显示两条。

m_pMicrophoneCombox->setEditable(false); //设置QComboBox可编辑。

m_pMicrophoneCombox->setFocusPolicy(Qt::NoFocus);//设置QCombox不成难点。

m_pMicrophoneCombox->setLineEdit(edit);//edit是一个lineedit,就是说QCombox的LineEdit可以自定义,而QT的源码中,顶端也是一个LineEdit。

m_pMicrophoneCombox->setCurrentIndex(0); // 设置当前选中的目录。

m_pMicrophoneCombox->setCurrentText(TR_TALK_DEVICE_COMBOX);//设置QCombox当前的显得text,我是用宏封装的,满足中期修改。

m_pMicrophoneCombox->setItemData(i,
list[i]);//QCombox也得以友善传入一个链表,并且自己定义索引,当然,你想传一条数据,并且自己定义索引。

QListWidget* pListWidget = new QListWidget();//new一个widget的实例。

m_pMicrophoneCombox->setModel(pListWidget->model());//塞进widget的model。
m_pMicrophoneCombox->setView(pListWidget);//将widget装进Combox。

m_pMicrophoneCombox->count();//用来总括combox下拉窗体的轻重缓急。

m_pMicrophoneCombox->addItems(list);//插入一个列表。

m_pMicrophoneCombox->addItem(“111”);//插入单条数据。

上述函数基本满意工作必要,如若交互的体裁相比较复杂,需求自定义样式,这样的话,我们就要协调去写每一个item的体制。

分析下QCombox的源码,其实他的兑现就是一个LineEdit和一个ListWidget,知道啊这些就可以自己去重新写一个ListWidget。

Item *pItem = new Item();
//item是上下一心自定义写的布局,每一个item的自定义样式就可以写在那个里面。
QListWidgetItem *pListWidgetItem = new
QListWidgetItem(list[i],pListWidget);//我是将链表的多寡塞进QCombox里。
pItem->setItemData(list[i]);//给每一个item塞进多少
pListWidget->setItemWidget(pListWidgetItem,
pItem);//关于那么些函数我的驾驭是:在底下一层下边再覆盖一层。

下一场在QSS的体裁里写hover、pressed鼠标事件,就有鼠标的互相。

那种艺术就算实惠,然而多少不与UI分离,都搅在一团。

极品的方案就是:

  既然QT的combox协理listwidget,那么全部都用自己定制的listwidget。

 在itemwidget里写布局,自己搞一个delegate,在代理去管理UI,数据在model里去操作,那里的model可能要自己包装一层,满意combox的竞相需求。

pListWidget->m_pModel->Append(list[i]);//将每一个数额塞进model,剩下的数码操作就由model去管理。

出色注意的是:这几个时候,qt原生的那个接口都不见效了,例如:setcurrenttext还有setcurrentindex,查看源码发现都是按照索引来操控,而其实,大家用自己的model

去管理的数目,并不会转变一个目录来满足combox管理的数额,所以这个对外的接口可能也要和谐去封装出来,可以说基本上是屏弃了combox,自己去组装LineEdit和ListWidget。

实际上代码量是许多的,公司业务可以去封装成控件,方便开发。

    最终,假若大神们有更好的艺术,欢迎评论。

 

 

这是自身在类型实战中的个人统计,写的急促,有些东西也不必然标准,有些是自己推…

记录下使用QListView遇到的各样难点

 关于QCombox要是不须要自定义,其实写UI是很简短的。

 关于QCombox借使不要求自定义,其实写UI是很粗略的。

QListView可以用来以列表的样式显得数据,在Qt中行使model/View结构来治本数据与视图的关系,model负责数据的存取,数据的相互通过delegate来促成。

创办实例:QComboBox*  m_pMicrophoneCombox = new QComboBox;

创立实例:QComboBox*  m_【澳门金沙国际】迅猛支付QCombox以及业务样式自定义。pMicrophoneCombox = new QComboBox;

累加数据模型

QT提供了部分现成的models用于拍卖数据项:
QStringListModel 用于存储简单的QString列表。
QStandardItemModel
管理复杂的树型结构数据项,每项都足以涵盖自由数据。
QDirModel 提供当地文件系统中的文件与目录音讯。
QSqlQueryModel, QSqlTableModel,QSqlRelationTableModel用来做客数据库。

动用Qt自带的模型类QStandardItemModel即可。模型中的每个数据项都有一个与之相应的role来储存某一类数据。须要存取自定义数据可以拔取UserRole,UserRole+1…

对此自定义数据类型,如果要动用QVariant,就亟须使用Q_DECLARE_METATYPE注册。

struct ItemData{
    QString name;
    QString tel;
};

Q_DECLARE_METATYPE(ItemData)

我是用的QSS去的写样式,这里用了一个命名函数:m_pMicrophoneCombox->setObjectName(“DeviceCombox”);

自身是用的QSS去的写样式,这里用了一个命名函数:m_pMicrophoneCombox->setObjectName(“DeviceCombox”);

纯净数据存取

//存
Item->setData(itemStatus,Qt::UserRole);  // 单一存取

//取
ItemStatus status = (ItemStatus)(index.data(Qt::UserRole).toInt());

倘使是用的setstylesheet直接在代码里去写就好了。

万一是用的setstylesheet直接在代码里去写就好了。

结构体数据存取

//存
Item->setData(QVariant::fromValue(itemData),Qt::UserRole+1);//整体存取

//取
QVariant variant = index.data(Qt::UserRole+1);
ItemData data = variant.value<ItemData>();

下边说多少个属性函数:

上面说多少个属性函数:

自定义delegate

模型的互动和制图通过自定义delegate来贯彻,暂时没用到交互,先说下item的绘图。继承了QStyledItemDelegate后,重写paint函数处理item的体制,以及sizeHint函数重临item的大大小小:

m_pMicrophoneCombox->set马克斯VisibleItems(2);//最大可知区域为显示两条。

m_pMicrophoneCombox->set马克斯VisibleItems(2);//最大可知区域为呈现两条。

绘制item

void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{


    if(index.isValid())
    {
        painter->save();

        ItemStatus status = (ItemStatus)(index.data(Qt::UserRole).toInt());

        QVariant variant = index.data(Qt::UserRole+1);
        ItemData data = variant.value<ItemData>();

        QStyleOptionViewItem viewOption(option);//用来在视图中画一个item

        QRectF rect;
        rect.setX(option.rect.x());
        rect.setY(option.rect.y());
        rect.setWidth( option.rect.width()-1);
        rect.setHeight(option.rect.height()-1);

        //QPainterPath画圆角矩形
        const qreal radius = 7;
        QPainterPath path;
        path.moveTo(rect.topRight() - QPointF(radius, 0));
        path.lineTo(rect.topLeft() + QPointF(radius, 0));
        path.quadTo(rect.topLeft(), rect.topLeft() + QPointF(0, radius));
        path.lineTo(rect.bottomLeft() + QPointF(0, -radius));
        path.quadTo(rect.bottomLeft(), rect.bottomLeft() + QPointF(radius, 0));
        path.lineTo(rect.bottomRight() - QPointF(radius, 0));
        path.quadTo(rect.bottomRight(), rect.bottomRight() + QPointF(0, -radius));
        path.lineTo(rect.topRight() + QPointF(0, radius));
        path.quadTo(rect.topRight(), rect.topRight() + QPointF(-radius, -0));

        if(option.state.testFlag(QStyle::State_Selected))
        {
            painter->setPen(QPen(Qt::blue));
            painter->setBrush(QColor(229, 241, 255));
            painter->drawPath(path);
        }
        else if(option.state.testFlag(QStyle::State_MouseOver))
        {
            painter->setPen(QPen(Qt::green));
            painter->setBrush(Qt::NoBrush);
            painter->drawPath(path);
        }
        else{
            painter->setPen(QPen(Qt::gray));
            painter->setBrush(Qt::NoBrush);
            painter->drawPath(path);
        }

        //绘制数据位置
        QRect NameRect = QRect(rect.left() +10, rect.top()+10, rect.width()-30, 20);
        QRect circle = QRect(NameRect.right(), rect.top()+10, 10, 10);
        QRect telRect = QRect(rect.left() +10, rect.bottom()-25, rect.width()-10, 20);


        switch (status) {
        case S_RED:
            painter->setBrush(Qt::red);
            painter->setPen(QPen(Qt::red));
            break;
        case S_BLUE:
            painter->setBrush(Qt::blue);
            painter->setPen(QPen(Qt::blue));
            break;
        case S_YELLOW:
            painter->setBrush(Qt::yellow);
            painter->setPen(QPen(Qt::yellow));
            break;
        }

        painter->drawEllipse(circle);     //画圆圈

        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("Times", 12, QFont::Bold));
        painter->drawText(NameRect,Qt::AlignLeft,data.name); //绘制名字

        painter->setPen(QPen(Qt::gray));
        painter->setFont(QFont("Times", 10));
        painter->drawText(telRect,Qt::AlignLeft,data.tel); //绘制电话

        painter->restore();
    }
}

QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return QSize(160, 60);
}

m_pMicrophoneCombox->setEditable(false); //设置QComboBox可编辑。

m_pMicrophoneCombox->setEditable(false); //设置QComboBox可编辑。

安装item不一致意况下的体裁

在paint函数中,还足以博得当前item的处境,并安装区其他体裁:

 if(option.state.testFlag(QStyle::State_Selected)) //选中状态
        {
            painter->setPen(QPen(Qt::blue));
            painter->setBrush(QColor(229, 241, 255));
            painter->drawPath(path);
        }
        else if(option.state.testFlag(QStyle::State_MouseOver))//鼠标划过状态
        {
            painter->setPen(QPen(Qt::green));
            painter->setBrush(Qt::NoBrush);
            painter->drawPath(path);
        }
        else{
            painter->setPen(QPen(Qt::gray));
            painter->setBrush(Qt::NoBrush);
            painter->drawPath(path);
        }

安装好模型后,再对QListView举行下属性设置:

    ui->listView->setItemDelegate(m_delegate);       //为视图设置委托
    ui->listView->setSpacing(15);                   //为视图设置控件间距
    ui->listView->setModel(m_model);                  //为委托设置模型
    ui->listView->setViewMode(QListView::IconMode); //设置Item图标显示
    ui->listView->setDragEnabled(false); 

模型的多少和出示都处理好后,运行效果如下:

listview展示

m_pMicrophoneCombox->setFocusPolicy(Qt::NoFocus);//设置QCombox不是难点。

m_pMicrophoneCombox->setFocusPolicy(Qt::NoFocus);//设置QCombox没有典型。

过滤item

Qt中提供了一个有益处理模型排序和过滤的类QSortFilterProxyModel,通过她得以相当便宜的处理大家的model。将QListView显示的model设置成代理模型:

    ui->listView->setItemDelegate(m_delegate);       //为视图设置委托
    ui->listView->setSpacing(15);                   //为视图设置控件间距
    m_proxyModel = new QSortFilterProxyModel(ui->listView);
    m_proxyModel->setSourceModel(m_model);
    m_proxyModel->setFilterRole(Qt::UserRole);
    m_proxyModel->setDynamicSortFilter(true);
    ui->listView->setModel(m_proxyModel);                  //为委托设置模型
    ui->listView->setViewMode(QListView::IconMode); //设置Item图标显示
    ui->listView->setDragEnabled(false);            //控件不允许拖动

其中,m_proxyModel->setFilterRole(Qt::UserRole);设置依据模型的某一项数据来拍卖模型的过滤。proxyModel能够安装过滤的点子,根据QString或者正则表达式来过滤:

m_proxyModel->setFilterFixedString(QString::number(S_RED));//根据字符串过滤
m_proxyModel->setFilterRegExp(QRegExp("^[0|2]$")); //根据正则表达式过滤

过滤模型

m_pMicrophoneCombox->setLineEdit(edit);//edit是一个lineedit,就是说QCombox的LineEdit可以自定义,而QT的源码中,顶端也是一个LineEdit。

m_pMicrophoneCombox->setLineEdit(edit);//edit是一个lineedit,就是说QCombox的LineEdit能够自定义,而QT的源码中,顶端也是一个LineEdit。

赢得选中item

对于列表中item的操作,可以是在delegate中处理相互事件,也足以通过QListView获取到具有入选item的QModelIndex,然后对模型本身进行改动。那里自己拔取的接班人:

QModelIndexList modelIndexList = ui->listView->selectionModel()->selectedIndexes();

m_pMicrophoneCombox->setCurrentIndex(0); // 设置当前当选的目录。

m_pMicrophoneCombox->setCurrentIndex(0); // 设置当前入选的目录。

安装多选

将QListView的selectionBehavior设置成MultiSelection即可。

对于多选的时候,模型的改动有一个坑。在设置了代理模型后,由于开启了动态排序情势,如果改动代理模型的多少,在率先个item修改数据后可能就不在当前过滤模型中,会被过滤掉,后边的item的QModelIndex就会扭转,导致持续的修改战败。

dynamicSortFilter : bool
This property holds whether the proxy model is dynamically sorted and
filtered whenever the contents of the source model change.
Note that you should not update the source model through the proxy
model when dynamicSortFilter is true. For instance, if you set the
proxy model on a QComboBox, then using functions that update the
model, e.g., addItem(), will not work as expected. An alternative is
to set dynamicSortFilter to false and call sort() after adding items
to the QComboBox.
The default value is true.

有多少个艺术处理这几个坑,一是不修改代理模型,修改源模型的多寡。二是在改动模型数据的时候关闭代理模型的动态排序作用。

m_pMicrophoneCombox->setCurrentText(TR_TALK_DEVICE_COMBOX);//设置QCombox当前的显得text,我是用宏封装的,满意中期修改。

m_pMicrophoneCombox->setCurrentText(TR_TALK_DEVICE_COMBOX);//设置QCombox当前的显得text,我是用宏封装的,满意前期修改。

修改数据

QModelIndexList sourceIndexList;
    foreach (QModelIndex modelIndex, modelIndexList){
        sourceIndexList<<m_proxyModel->mapToSource(modelIndex); //获取源model的modelIndex
    }

//    g_proxyModel->setDynamicSortFilter(false);
    foreach (QModelIndex sourceIndex, sourceIndexList){
        ItemStatus status = (ItemStatus)(sourceIndex.data(Qt::UserRole).toInt());
        qDebug() << "Index : " << sourceIndex.row();

        switch (status) {
            case S_RED:
                redNum--;
                break;
            case S_BLUE:
                blueNum--;
                break;
            case S_YELLOW:
                yellowNum--;
                break;
        }

        status = S_RED;
        redNum++;

        m_model->setData(sourceIndex,status,Qt::UserRole);
    }
//    g_proxyModel->setDynamicSortFilter(true);

弄完大致是酱紫的:

说到底效果

Demo在这里:->Github链接地址。

m_pMicrophoneCombox->setItemData(i,
list[i]);//QCombox也可以自己传入一个链表,并且自己定义索引,当然,你想传一条数据,并且自己定义索引。

m_pMicrophoneCombox->setItemData(i,
list[i]);//QCombox也足以协调传入一个链表,并且自己定义索引,当然,你想传一条数据,并且自己定义索引。

QListWidget* pListWidget = new QListWidget();//new一个widget的实例。

QListWidget* pListWidget = new QListWidget();//new一个widget的实例。

m_pMicrophoneCombox->setModel(pListWidget->model());//塞进widget的model。
m_pMicrophoneCombox->setView(pListWidget);//将widget装进Combox。

m_pMicrophoneCombox->setModel(pListWidget->model());//塞进widget的model。
m_pMicrophoneCombox->setView(pListWidget);//将widget装进Combox。

m_pMicrophoneCombox->count();//用来计量combox下拉窗体的大小。

m_pMicrophoneCombox->count();//用来计量combox下拉窗体的分寸。

m_pMicrophoneCombox->addItems(list);//插入一个列表。

m_pMicrophoneCombox->addItems(list);//插入一个列表。

m_pMicrophoneCombox->addItem(“111”);//插入单条数据。

澳门金沙国际,m_pMicrophoneCombox->addItem(“111”);//插入单条数据。

以上函数基本满意工作必要,如若交互的体制相比复杂,要求自定义样式,这样的话,大家就要协调去写每一个item的体裁。

以上函数基本知足工作要求,假设交互的样式相比复杂,须要自定义样式,那样的话,我们就要团结去写每一个item的体裁。

浅析下QCombox的源码,其实她的落到实处就是一个LineEdit和一个ListWidget,知道啊那么些就可以协调去重新写一个ListWidget。

解析下QCombox的源码,其实她的达成就是一个LineEdit和一个ListWidget,知道啊这一个就足以团结去重新写一个ListWidget。

Item *pItem = new Item();
//item是和谐自定义写的布局,每一个item的自定义样式就足以写在这些里面。
QListWidgetItem *pListWidgetItem = new
QListWidgetItem(list[i],pListWidget);//我是将链表的数目塞进QCombox里。
pItem->setItemData(list[i]);//给每一个item塞进多少
pListWidget->setItemWidget(pListWidgetItem,
pItem);//关于那么些函数我的精通是:在底下一层上面再覆盖一层。

Item *pItem = new Item();
//item是自己自定义写的布局,每一个item的自定义样式就足以写在那些里面。
QListWidgetItem *pListWidgetItem = new
QListWidgetItem(list[i],pListWidget);//我是将链表的多少塞进QCombox里。
pItem->setItemData(list[i]);//给每一个item塞进多少
pListWidget->setItemWidget(pListWidgetItem,
pItem);//关于这几个函数我的敞亮是:在上边一层上边再覆盖一层。

下一场在QSS的样式里写hover、pressed鼠标事件,就有鼠标的相互。

接下来在QSS的体制里写hover、pressed鼠标事件,就有鼠标的竞相。

那种艺术固然实惠,可是数量不与UI分离,都搅在一团。

那种办法即使实惠,不过数量不与UI分离,都搅在一团。

顶尖的方案就是:

极品的方案就是:

  既然QT的combox扶助listwidget,那么全体都用自己定制的listwidget。

  既然QT的combox支持listwidget,那么全部都用自己定制的listwidget。

 在itemwidget里写布局,自己搞一个delegate,在代理去管理UI,数据在model里去操作,那里的model可能要和谐包裹一层,满意combox的相互需求。

 在itemwidget里写布局,自己搞一个delegate,在代理去管理UI,数据在model里去操作,那里的model可能要自己包装一层,满足combox的相互须要。

pListWidget->m_pModel->Append(list[i]);//将每一个数额塞进model,剩下的多少操作就由model去管理。

pListWidget->m_pModel->Append(list[i]);//将每一个数目塞进model,剩下的数目操作就由model去管理。

新鲜注意的是:那么些时候,qt原生的那一个接口都不奏效了,例如:setcurrenttext还有setcurrentindex,查看源码发现都是依据索引来操控,而实际,大家用自己的model

格外注意的是:那个时候,qt原生的那个接口都不见效了,例如:setcurrenttext还有setcurrentindex,查看源码发现都是根据索引来操控,而实际上,大家用自己的model

去管理的多寡,并不会变卦一个目录来满意combox管理的数据,所以那个对外的接口可能也要和谐去封装出来,可以说基本上是放任了combox,自己去组装LineEdit和ListWidget。

去管理的多寡,并不会转移一个目录来满意combox管理的数量,所以那一个对外的接口可能也要自己去封装出来,能够说基本上是舍弃了combox,自己去组装LineEdit和ListWidget。

其实代码量是累累的,集团工作可以去封装成控件,方便开发。

实际代码量是诸多的,集团工作可以去封装成控件,方便开发。

    最终,即使大神们有更好的形式,欢迎评论。

    最终,如若大神们有更好的办法,欢迎评论。

 

 

 

 

相关文章