- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我能够找到 QRadioButton
这样:
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
构造。我的第一次尝试失败了:
foreach(QRadioButton* child, ui->verticalLayout->findChildren<QRadioButton*>())
{
if(child->isChecked())
//found it!
}
问题是 ui->verticalLayout->findChildren<QRadioButton*>()
返回零元素。它还不返回带有 findChildren<QObject*>()
的元素.有人可以解释这种行为吗?
注意: this 的标题问题与我的几乎相同,但它与 python Qt 有关,并且不包含对我有任何帮助的信息。
通过实验,我认为 ui->verticalLayout->children().count()
返回零,其中 ui->verticalLayout->count()
返回我在 verticalLayout
中拥有的元素数量.这意味着 itemAt(i)
和 findChild<QRadioButton*>()
不要访问相同的列表。查看关于 children()
的 Qt 文档对我没有帮助。
有人能给我指出有关 Qt 子父概念的好资料吗?我假设这与访问嵌套对象无关,而这正是我想要完成的。
根据 Kuba Ober 的建议,this question 的答案包含关于另一个主题的有值(value)的信息,而他的回答澄清了我关于布局 child 的问题。因此这不是一个重复的问题。
最佳答案
从 QObject
子级的意义上说,小部件不是布局的子级 - 它们是父级小部件的子级。 QWidget
只能是另一个 QWidget
的子级 - 因此您永远不能期望小部件是布局的子级。虽然 new QWidget(new QWidget())
有效,但 new QWidget(new QHBoxLayout())
无法编译。
您可以按如下方式迭代给定类型的小部件的子级:
// C++11
for (auto button : findChildren<QRadioButton*>()) if (button->isChecked()) {
...
}
// C++98
Q_FOREACH (QWidget * button, findChildren<QRadioButton*>())
if (button->isChecked()) {
...
}
如果您使用的是 C++11,则应使用 range-based for loop ,而不是现在已过时的 foreach
或 Q_FOREACH
。
要迭代由布局管理的子部件,您需要布局的迭代器适配器。例如:
#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());
}
关于c++ - 如何在 QLayout 中查找给定类型的小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31546511/
我有一个包含其他布局(子布局)的布局。我需要从布局中删除包含内容的子布局。我该怎么做? QVBoxLayout* mainLayout = new QVBoxLayout; QHBoxLayout*
我想创建一些标签,我阅读了这个答案:How to add a tab in PySide 我使用答案中的代码并进行了一些更改。因为我的代码必须读取一些文件并从这些文件中获取我的选项卡的名称,所以我在我
我想创建一个窗口,其中Qt3DWindow在后面,一些QPushButton在它上面。但是,仅显示 Qt3DWindow 动画,而看不到 QPushButton。我还希望有 Qt3DWindow 功能
我有QLayout接受 QLabel 的类(class)并将其对齐为 Qt::AlignRight在单元格中,最初我认为它正在工作(因为布局单元格的大小正好等于像素图的大小),我有一个与 QLabel
我正在寻找一个 super 简单的示例,但似乎找不到。我有一个主窗口。当按下按钮时,我想创建一个新窗口,该窗口在 MainWindow 的布局中打开,成为主窗口的一部分。 我有代码在按下按钮调用这个插
这让我发疯。我有一个自定义菜单类,当设置为可见时,它会显示位于特定文件夹中的项目列表。当按下硬件按钮时,我的应用程序获取最新的项目列表,用它们填充菜单,然后返回。 显示这些项目的菜单使用填充了自定义小
我正在使用 QHBoxLayout 显示 5 个水平对齐的小部件。 如果我隐藏和显示一个小部件,它会调整大小。我该如何防止这种情况发生? 最佳答案 你不能。如果您隐藏了一个小部件,它就会从屏幕上消失,
我有一个 Qt4 应用程序,它有很多对话框。我很想知道 QDialog 是否删除了它的布局。举个例子: class MyDialog : public QDialog { public:
我的结构如下: QWidget -QHBoxLayout -QLabel -QVBoxLayout -QLabel
我知道我可以向QPushButton 添加Icon 和Text,但我对它们的布局不满意。有没有办法将带有我想要的任何控件的 QLayout 添加到 QPushButton?例如,我可以有一个 Icon
我正在尝试实现这个 CardLayout 示例 https://doc.qt.io/qt-5/layout.html但是当我尝试编译给定的文件 card.h 时,它无法提示 QLayout 的构造函数
我能够找到 QRadioButton这样: for(int i = 0; i verticalLayout->count(); i++) { QRadioButton* r = qobject
例如,我们在 QMainWindow 中有 QHBoxLayout。 让我们在上面的布局中设置小部件。 但是 (!) 很少有小部件具有离散的视觉表示。换句话说,它们几乎没有依赖于可用空间的状态。 例如
我从 Qt 文档中知道 QLayout 对象拥有其小部件的所有权。但就 QLayout 对象而言,在堆栈上创建它然后使用 setLayout 函数将其传递给小部件是否安全?还是必须在堆上创建? #in
我正在尝试实现一个由一堆子元素组成的 UI 元素。它们可以像 parent 一样增长或缩小。非常简单 QLayout东西。然而,当父元素变得太小时,它会隐藏几个子元素(这意味着现在有更多的空间可以容纳
我正在实现一个选项卡样式的 UI。其中选项卡由 QListWidget 显示,内容由 QStackedWidget 显示。在 QStackWidget 的每一页上都有允许在 QHBoxlayout 中
我有两个示例,其中我基本上是在创建包装器对象,而不是理想情况下的简单转换。 如果 foo 是之前实例化的 QWidget*,我是否可以避免为其创建包装器 QLayout: const auto lay
我正在尝试在布局中放置一些旋转框、行编辑。但规模超出了必要性。下面是图 我在这里添加了一个 QScrollArea 小部件和一个 QVBoxLayout 到 QHBoxLayout 中。然后我将行编辑
执行时(没有编译错误)我进入控制台 QWidget::setLayout: Attempting to set QLayout "" on CGSearchResult "", which alrea
我正在为 Blender 做一个插件,并且正在使用 PySide2。我能够删除窗口标题并仅显示窗口的内容。我在 QFrame 中插入了一个动画 gif 并更改了它的边框。问题是容器仍然出现尖锐的边框。
我是一名优秀的程序员,十分优秀!