久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

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

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

問題描述

我可以通過這種方式找到 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 構(gòu)造.我的第一次嘗試失敗了:

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?

注意:這個(gè)標(biāo)題 問題與我的幾乎相同,但它與python Qt有關(guān),并且不包含任何對(duì)我有用的信息.

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.

實(shí)驗(yàn)上我認(rèn)為 ui->verticalLayout->children().count() 返回零,其中 ui->verticalLayout->count() 返回我在 verticalLayout 中的元素?cái)?shù)量.這意味著 itemAt(i)findChild() 不會(huì)訪問同一個(gè)列表.查看關(guān)于 children() 的 Qt 文檔對(duì)我沒有幫助.

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.

有人能給我指點(diǎn)關(guān)于 Qt 子父概念的好材料嗎?我假設(shè)這與訪問嵌套對(duì)象無關(guān),而這正是我想要完成的.

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 所建議的,這個(gè)問題的答案包含關(guān)于另一個(gè)主題的寶貴信息,而他的回答澄清了我關(guān)于布局子項(xiàng)的問題.因此這不是一個(gè)重復(fù)的問題.

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 子項(xiàng)而言,小部件不是布局的子項(xiàng) - 它們是父小部件的子項(xiàng).QWidget 只能是另一個(gè) QWidget 的子項(xiàng) - 因此您不能期望小部件是布局的子項(xiàng).雖然 new QWidget(new QWidget()) 有效,但 new QWidget(new QHBoxLayout()) 不會(huì)編譯.

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,你應(yīng)該使用 range-基于 for 循環(huán),而不是現(xiàn)在過時(shí)的 foreachQ_FOREACH.

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

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

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;
}

一些基本測(cè)試如下:

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());
}

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

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

相關(guān)文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數(shù)據(jù)?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環(huán): for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環(huán)?)
Reusing thread in loop c++(在循環(huán) C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環(huán)形?)
主站蜘蛛池模板: 国产一级片在线观看视频 | 狠狠操狠狠干 | 伊人一二三 | 国产成人精品视频在线观看 | 国产一区二区三区在线 | 91精品在线播放 | 美女视频一区二区 | 一级全黄少妇性色生活免费看 | 亚洲瑟瑟 | 久久精品青青大伊人av | 国产精品日女人 | 美女视频黄色片 | 91人人在线 | 国产成人啪免费观看软件 | 美女天堂在线 | 国产一在线观看 | 国产成人jvid在线播放 | 久久国产精品偷 | 成人在线精品 | 国产成人久久av免费高清密臂 | 一区二区av | 国产精品日日摸夜夜添夜夜av | 中文字幕日本一区二区 | 国产精品美女久久久久久久久久久 | 精品91久久| 国产成人jvid在线播放 | 亚洲欧美在线视频 | 一区二区三区在线免费 | 国产伦精品一区二区三区精品视频 | 久久久久久久久久久成人 | 成年人在线视频 | 欧美国产一区二区 | 亚洲一区二区三区免费在线观看 | 卡通动漫第一页 | 久久久久久国产 | 最新中文字幕第一页视频 | 国产激情一区二区三区 | 亚洲一区二区三区在线播放 | 成人精品国产一区二区4080 | 久久精品日产第一区二区三区 | 亚洲电影中文字幕 |