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

如何在 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 ()?環形?)
主站蜘蛛池模板: 欧美精品一区二区三区四区 | 国产精品99久久久久久久vr | 亚洲免费三区 | 久久精品一 | 欧美8一10sex性hd | 精品日韩在线 | 一级片av| 亚洲精品99999 | 狠狠视频| 国产在线精品免费 | 欧美性极品xxxx做受 | 成人在线视频免费播放 | 日本电影免费完整观看 | 精品av| 午夜小电影 | 亚洲毛片 | 欧美性猛交一区二区三区精品 | 欧美aaa一级片 | 亚洲精品欧美一区二区三区 | 欧美日韩久久精品 | 国产日韩精品一区二区 | 午夜免费观看体验区 | 国产精品成人一区二区三区 | av中文在线 | 国产成人精品一区二 | 国产一级一级毛片 | 日韩精品1区2区3区 爱爱综合网 | 欧美日韩视频在线第一区 | 日本免费小视频 | 欧美三级在线 | 一区二区三区av | 精品国产欧美 | 巨大荫蒂视频欧美另类大 | 久久久久av| 在线看国产| 中文字幕在线精品 | 欧美一区二区在线观看 | 日韩欧美三级电影 | 成人免费大片黄在线播放 | 国产一级片网站 | 欧美xxxx日本 |