pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

如何在 QLayout 中查找給定類型的小部件?

How to find widgets of a given type in a QLayout?(如何在 QLayout 中查找給定類型的小部件?)
本文介紹了如何在 QLayout 中查找給定類型的小部件?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我可以通過這種方式找到 QRadioButton:

I am able to find the QRadioButton this way:

for(int i = 0; i < ui->verticalLayout->count(); i++)
{
    QRadioButton* r = qobject_cast<QRadioButton*>(ui->verticalLayout->itemAt(i)->widget());
    if(r->isChecked())
        //found it!
}

但我不喜歡這種迭代元素的方式,并希望使用 foreach 構造.我的第一次嘗試失敗了:

But I don't like this way of iterating over elements and would like to use the foreach construct. My first attempt fails:

foreach(QRadioButton* child, ui->verticalLayout->findChildren<QRadioButton*>())
{
    if(child->isChecked())
        //found it!
}

問題在于 ui->verticalLayout->findChildren() 返回零元素.它也不返回帶有 findChildren() 的元素.有人可以解釋一下這種行為嗎?

Problem is that the ui->verticalLayout->findChildren<QRadioButton*>() returns zero elements. It also returns no elements with findChildren<QObject*>(). Can someone please explain this behaviour?

注意:這個標題 問題與我的幾乎相同,但它與python Qt有關,并且不包含任何對我有用的信息.

Note: the title of this question is almost identical to mine, but it is related to python Qt, and does not contain any helpful information for me.

實驗上我認為 ui->verticalLayout->children().count() 返回零,其中 ui->verticalLayout->count() 返回我在 verticalLayout 中的元素數量.這意味著 itemAt(i)findChild() 不會訪問同一個列表.查看關于 children() 的 Qt 文檔對我沒有幫助.

Experimentally I figured that ui->verticalLayout->children().count() returns zero where as ui->verticalLayout->count() returns the number of elements I have in the verticalLayout. This implies that itemAt(i) and findChild<QRadioButton*>() do not access the same list. Looking at the Qt documentation on children() did not help me.

有人能給我指點關于 Qt 子父概念的好材料嗎?我假設這與訪問嵌套對象無關,而這正是我想要完成的.

Can someone point me to a good material on Qt child parent concepts? I am assuming that this has nothing to do with accesing nested objects which is what I am trying to accomplish.

正如 Kuba Ober 所建議的,這個問題的答案包含關于另一個主題的寶貴信息,而他的回答澄清了我關于布局子項的問題.因此這不是一個重復的問題.

As suggested by Kuba Ober, the answers to this question contains valuable information on another topic, whereas his answer makes clarification on my question about children of layout. Thus this is not a duplicate question.

推薦答案

QObject 子項而言,小部件不是布局的子項 - 它們是父小部件的子項.QWidget 只能是另一個 QWidget 的子項 - 因此您不能期望小部件是布局的子項.雖然 new QWidget(new QWidget()) 有效,但 new QWidget(new QHBoxLayout()) 不會編譯.

The widgets are not children of the layout in the sense of being QObject children - they are children of the parent widget. A QWidget can only be a child of another QWidget - thus you can't ever expect widgets to be layout's children. While new QWidget(new QWidget()) works, new QWidget(new QHBoxLayout()) won't compile.

您可以按如下方式迭代給定類型的小部件的子部件:

You could iterate a widget's children of a given type as follows:

// C++11
for (auto button : findChildren<QRadioButton*>()) if (button->isChecked()) {
  ...
}

// C++98
Q_FOREACH (QWidget * button, findChildren<QRadioButton*>())
  if (button->isChecked()) {
    ...
  }

如果你使用 C++11,你應該使用 range-基于 for 循環,而不是現在過時的 foreachQ_FOREACH.

If you're using C++11, you should use the range-based for loop, not the now obsolete foreach or Q_FOREACH.

要迭代由布局管理的子小部件,您需要一個用于布局的迭代器適配器.例如:

To iterate the child widgets managed by a layout, you need an iterator adapter for the layout. For example:

#include <QLayout>
#include <QDebug>
#include <QPointer>
#include <utility>

template<class WT> class IterableLayoutAdapter;

template<typename WT>
class LayoutIterator {
   QPointer<QLayout> m_layout;
   int m_index;
   friend class IterableLayoutAdapter<WT>;
   LayoutIterator(QLayout * layout, int dir) :
      m_layout(layout), m_index(dir>0 ? -1 : m_layout->count()) {
      if (dir > 0) ++*this;
   }
   friend QDebug operator<<(QDebug dbg, const LayoutIterator & it) {
      return dbg << it.m_layout << it.m_index;
   }
   friend void swap(LayoutIterator& a, LayoutIterator& b) {
      using std::swap;
      swap(a.m_layout, b.m_layout);
      swap(a.m_index, b.m_index);
   }
public:
   LayoutIterator() : m_index(0) {}
   LayoutIterator(const LayoutIterator & o) :
      m_layout(o.m_layout), m_index(o.m_index) {}
   LayoutIterator(LayoutIterator && o) { swap(*this, o); }
   LayoutIterator & operator=(LayoutIterator o) {
      swap(*this, o);
      return *this;
   }
   WT * operator*() const { return static_cast<WT*>(m_layout->itemAt(m_index)->widget()); }
   const LayoutIterator & operator++() {
      while (++m_index < m_layout->count() && !qobject_cast<WT*>(m_layout->itemAt(m_index)->widget()));
      return *this;
   }
   LayoutIterator operator++(int) {
      LayoutIterator temp(*this);
      ++*this;
      return temp;
   }
   const LayoutIterator & operator--() {
      while (!qobject_cast<WT*>(m_layout->itemAt(--m_index)->widget()) && m_index > 0);
      return *this;
   }
   LayoutIterator operator--(int) {
      LayoutIterator temp(*this);
      --*this;
      return temp;
   }
   bool operator==(const LayoutIterator & o) const { return m_index == o.m_index; }
   bool operator!=(const LayoutIterator & o) const { return m_index != o.m_index; }
};

template <class WT = QWidget>
class IterableLayoutAdapter {
   QPointer<QLayout> m_layout;
public:
   typedef LayoutIterator<WT> const_iterator;
   IterableLayoutAdapter(QLayout * layout) : m_layout(layout) {}
   const_iterator begin() const { return const_iterator(m_layout, 1); }
   const_iterator end() const { return const_iterator(m_layout, -1); }
   const_iterator cbegin() const { return const_iterator(m_layout, 1); }
   const_iterator cend() const { return const_iterator(m_layout, -1); }
};

template <class WT = QWidget>
class ConstIterableLayoutAdapter : public IterableLayoutAdapter<const WT> {
public:
   ConstIterableLayoutAdapter(QLayout * layout) : IterableLayoutAdapter<const WT>(layout) {}
};

用法如下:

#include <QApplication>
#include <QLabel>
#include <QHBoxLayout>

int main(int argc, char ** argv) {
   QApplication app(argc, argv);
   tests();
   QWidget a, b1, b3;
   QLabel b2;
   QHBoxLayout l(&a);
   l.addWidget(&b1);
   l.addWidget(&b2);
   l.addWidget(&b3);

   // Iterate all widget types as constants
   qDebug() << "all, range-for";
   for (auto widget : ConstIterableLayoutAdapter<>(&l)) qDebug() << widget;
   qDebug() << "all, Q_FOREACH";
   Q_FOREACH (const QWidget * widget, ConstIterableLayoutAdapter<>(&l)) qDebug() << widget;

   // Iterate labels only
   qDebug() << "labels, range-for";
   for (auto label : IterableLayoutAdapter<QLabel>(&l)) qDebug() << label;
   qDebug() << "labels, Q_FOREACH";
   Q_FOREACH (QLabel * label, IterableLayoutAdapter<QLabel>(&l)) qDebug() << label;
}

一些基本測試如下:

void tests() {
   QWidget a, b1, b3;
   QLabel b2;
   QHBoxLayout l(&a);

   IterableLayoutAdapter<> l0(&l);
   auto i0 = l0.begin();
   qDebug() << i0; Q_ASSERT(i0 == l0.begin() && i0 == l0.end());

   l.addWidget(&b1);
   l.addWidget(&b2);
   l.addWidget(&b3);

   IterableLayoutAdapter<> l1(&l);
   auto i1 = l1.begin();
         qDebug() << i1; Q_ASSERT(i1 == l1.begin() && i1 != l1.end());
   ++i1; qDebug() << i1; Q_ASSERT(i1 != l1.begin() && i1 != l1.end());
   ++i1; qDebug() << i1; Q_ASSERT(i1 != l1.begin() && i1 != l1.end());
   ++i1; qDebug() << i1; Q_ASSERT(i1 != l1.begin() && i1 == l1.end());
   --i1; qDebug() << i1; Q_ASSERT(i1 != l1.begin() && i1 != l1.end());
   --i1; qDebug() << i1; Q_ASSERT(i1 != l1.begin() && i1 != l1.end());
   --i1; qDebug() << i1; Q_ASSERT(i1 == l1.begin() && i1 != l1.end());

   IterableLayoutAdapter<QLabel> l2(&l);
   auto i2 = l2.begin();
         qDebug() << i2; Q_ASSERT(i2 == l2.begin() && i2 != l2.end());
   ++i2; qDebug() << i2; Q_ASSERT(i2 != l2.begin() && i2 == l2.end());
   --i2; qDebug() << i2; Q_ASSERT(i2 == l2.begin() && i2 != l2.end());
}

這篇關于如何在 QLayout 中查找給定類型的小部件?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數據?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環: for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環?)
Reusing thread in loop c++(在循環 C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環形?)
主站蜘蛛池模板: 逗网红-抖音网红-快手网红-各大平台网红物品导航 | 钢格板_钢格栅_格栅板_钢格栅板 - 安平县鑫拓钢格栅板厂家 | 钢格栅板_钢格板网_格栅板-做专业的热镀锌钢格栅板厂家-安平县迎瑞丝网制造有限公司 | 空调风机,低噪声离心式通风机,不锈钢防爆风机,前倾皮带传动风机,后倾空调风机-山东捷风风机有限公司 | 冷却塔减速机器_冷却塔皮带箱维修厂家_凉水塔风机电机更换-广东康明冷却塔厂家 | 车载加油机品牌_ 柴油加油机厂家| 泰州物流公司_泰州货运公司_泰州物流专线-东鑫物流公司 | 武汉高低温试验箱_恒温恒湿试验箱厂家-武汉蓝锐环境科技有限公司 | 网络推广公司_网络营销方案策划_企业网络推广外包平台-上海澜推网络 | 水压力传感器_数字压力传感器|佛山一众传感仪器有限公司|首页 | 南京雕塑制作厂家-不锈钢雕塑制作-玻璃钢雕塑制作-先登雕塑厂 | 样品瓶(色谱样品瓶)百科-浙江哈迈科技有限公司 | 淬火设备-钎焊机-熔炼炉-中频炉-锻造炉-感应加热电源-退火机-热处理设备-优造节能 | 密集架-手摇-智能-移动-价格_内蒙古档案密集架生产厂家 | 无菌水质袋-NASCO食品无菌袋-Whirl-Pak无菌采样袋-深圳市慧普德贸易有限公司 | 讲师宝经纪-专业培训机构师资供应商_培训机构找讲师、培训师、讲师经纪就上讲师宝经纪 | 不锈钢列管式冷凝器,换热器厂家-无锡飞尔诺环境工程有限公司 | 彼得逊采泥器-定深式采泥器-电动土壤采样器-土壤样品风干机-常州索奥仪器制造有限公司 | 亿诺千企网-企业核心产品贸易 | 生态板-实木生态板-生态板厂家-源木原作生态板品牌-深圳市方舟木业有限公司 | 飞行者联盟-飞机模拟机_无人机_低空经济_航空技术交流平台 | 都江堰招聘网-都江堰人才网 都江堰人事人才网 都江堰人才招聘网 邢台人才网_邢台招聘网_邢台123招聘【智达人才网】 | 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 耐酸泵,耐腐蚀真空泵,耐酸真空泵-淄博华舜耐腐蚀真空泵有限公司 精密模具-双色注塑模具加工-深圳铭洋宇通 | 山东钢格板|栅格板生产厂家供应商-日照森亿钢格板有限公司 | 断桥铝破碎机_铝合金破碎机_废铁金属破碎机-河南鑫世昌机械制造有限公司 | 螺杆真空泵_耐腐蚀螺杆真空泵_水环真空泵_真空机组_烟台真空泵-烟台斯凯威真空 | 回转窑-水泥|石灰|冶金-巩义市瑞光金属制品有限责任公司 | 威实软件_软件定制开发_OA_OA办公系统_OA系统_办公自动化软件 | 全国冰箱|空调|洗衣机|热水器|燃气灶维修服务平台-百修家电 | 超声骨密度仪-动脉硬化检测仪器-人体成分分析仪厂家/品牌/价格_南京科力悦 | 爱德华真空泵油/罗茨泵维修,爱发科-比其尔产品供应东莞/杭州/上海等全国各地 | 北京律师事务所_房屋拆迁律师_24小时免费法律咨询_云合专业律师网 | SEO网站优化,关键词排名优化,苏州网站推广-江苏森歌网络 | 电机铸铝配件_汽车压铸铝合金件_发动机压铸件_青岛颖圣赫机械有限公司 | 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 高光谱相机-近红外高光谱相机厂家-高光谱成像仪-SINESPEC 赛斯拜克 | 螺杆式冷水机-低温冷水机厂家-冷冻机-风冷式-水冷式冷水机-上海祝松机械有限公司 | 耐驰泵阀管件制造-耐驰泵阀科技(天津)有限公司 | 污水提升器,污水提升泵,地下室排水,增压泵,雨水泵,智能供排水控制器-上海智流泵业有限公司 | U拓留学雅思一站式服务中心_留学申请_雅思托福培训 |