如何创建一组UI元素,您可以迭代
How to create a group of UI elements that you are able to iterate through
我有一个应用程序作为班级的项目,其中包含游戏吊床和其他人。
我有一个行编辑输入字段供用户猜测字母。此输入仅限于1个字母。
我想有一个for循环,该循环检查用户输入是否与游戏中的任何字母匹配目标单词,并且是否将其放在屏幕上。
我有一堆标签,我打算将单个字母放入其中,每个字母都与正确的单词字符串中的字母放置相对应。
如何将QT UI元素放入数据结构中,以便我可以以循环访问它们?
这是我在网上查找后尝试的一些代码,以使您了解我要做什么。
int Hangman::check_input(QString input){
QList<QObject *> visible_word = {ui->label_0, ui->label_1,ui->label_2, ui->label_3,ui->label_4};
int i;
for (i = 0; i < current_word.length(); i++){
if (input == current_word[i]){
ui->visible_word[i]->text() == current_word[i];
}
}
}
您所做的工作有效,并且假设英语,因为可能的字母数可能固定为26(除非您出于某种原因允许非字母字符)错误。如果标签的数量是可变的或巨大的,这只是有问题的,而且这里似乎没有这种情况。
您还可以做的就是使用findChildren
方法,并且有几种变体。最简单的是,如果您的所有标签都属于同一小部件,并且在同一父母下没有其他QLabel
实例:
QList <QLabel *> parent->findChildren <QLabel *> ();
否则,您可能需要使用接受正则表达式以匹配子名称的变体:
QList <QLabel *> parent->findChildren <QLabel *> (QRegExp ("^label_"));
请注意,在两种情况下的顺序可能不是您想要使用所选字母填充标签的内容。文档没有说,但是我相信返回的顺序反映了孩子的创建顺序。由于您在QT设计师中创建了这些命令,因此该顺序可能不可靠;例如,如果您错过了中间的12号并将其添加在其他人之后,则Label_12将在列表中进行最后。根据您的其余方法,这可能无关紧要。如果您需要您的列表按标签0,标签1等顺序,那么您当前的机制可能是您想要的。
看起来很蛮力,但有时是完全可以接受的。
从您拥有的代码开始,让我们对其进行修复,以便它具有正确的方法签名,以使其编译:
/// Returns the number of newly matched letters.
int Hangman0::check_input(QChar input) {
int matched{};
std::array<QLabel*, 5> visible_word = {ui->label_0, ui->label_1,ui->label_2, ui->label_3,ui->label_4};
for (int i{}; i < current_word.length(); i++) {
auto const ch = current_word.at(i);
if (input == ch && visible_word[i]->text() != ch) {
visible_word[i]->setText(ch);
++ matched;
}
}
return matched;
}
但是,手动列举这些UI元素的意义很小,也可以手动将它们插入UI文件中的布局中。取而代之的是,将UI文件带有空布局,然后根据需要以编程方式插入元素。首先,让我们从最小.ui
文件中近似UIC输出:
// https://github.com/KubaO/stackoverflown/tree/master/questions/hangman-42261596
#include <QtWidgets>
#include <forward_list>
namespace Ui { // Approximate uic output
struct Hangman {
QFormLayout * topLayout;
QHBoxLayout * lettersLayout;
QLineEdit * letterEntry;
QPushButton * setup;
void setupUi(QWidget * widget) {
topLayout = new QFormLayout{widget};
topLayout->addRow(lettersLayout = new QHBoxLayout);
topLayout->addRow("Guess", letterEntry = new QLineEdit);
letterEntry->setMaxLength(1);
topLayout->addRow(setup = new QPushButton{"Setup"});
}
};
}
然后,让我们设计一个基本的Hangman
游戏小部件。我们可以在std::forward_list
中按值保持字母标签 - 这使生活相对容易,我们不必处理任何形式的明确内存管理。
class Hangman : public QWidget {
Q_OBJECT
Ui::Hangman ui;
QString m_currentWord;
std::forward_list<QLabel> m_letters;
public:
explicit Hangman(QWidget * parent = nullptr) :
QWidget{parent}
{
ui.setupUi(this);
connect(ui.letterEntry, &QLineEdit::returnPressed, [this]{
auto const text = ui.letterEntry->text();
if (!text.isEmpty())
checkInput(text[0]);
});
connect(ui.setup, &QPushButton::clicked, [this]{
setWord(QInputDialog::getText(this, "Setup", "Secret word:",
QLineEdit::Normal, m_currentWord)); // a hack
});
setWord("Hello");
}
void setWord(const QString & word) {
m_currentWord = word.toUpper();
m_letters.clear();
auto letter = m_letters.before_begin();
for (int i{}; i < word.size(); ++i) {
letter = m_letters.emplace_after(letter);
letter->setFrameShape(QFrame::Box);
ui.lettersLayout->addWidget(&*letter);
}
}
int checkInput(QChar input) {
int matched{};
input = input.toUpper();
auto letter = m_letters.begin();
for (int i{}; i < m_currentWord.size(); ++i) {
if (m_currentWord.at(i) == input) {
letter->setText(input);
matched ++;
}
letter ++;
}
return matched;
}
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
Hangman hangman;
hangman.show();
return app.exec();
}
#include "main.moc"
- 擦除while循环中迭代的元素
- 对于set上的循环-获取next元素迭代器
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 高级选择排序 - 在一次迭代中搜索两个元素
- 访问要输出的矢量迭代器元素
- 为什么这个程序没有打印返回的迭代器的正确第二个元素?
- 位集元素迭代的抽象
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 调用 erase() 函数是否也会在擦除元素之前更改迭代器值?
- 为什么 min_element() 返回最小元素的索引,而不是迭代器?
- 如何将元素插入和迭代到这种映射.C++
- 如何通过查找迭代器结果分配给一组对的元素
- 在迭代期间添加到 std::unordered_set(或 unordered_map)中的元素是否会在迭代期间访问?
- 使用 Rcpp 加速替换迭代算法中的列表和向量元素是否合法?
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 如何在集合中迭代替代元素(或进行特定大小的飞跃)?
- 无法将 std::set 中的元素迭代器插入到 std::list
- 使用std :: remove_reference获取STL容器的元素迭代器
- C++ 从地图的第二个元素迭代
- 在未排序向量中查找第 k 个最小元素(迭代)