2017-02-15 13 views
1

私はゲームのハングマンなどを含むクラスのプロジェクトとして作成しているアプリケーションがあります。
私は、ユーザーが手紙を推測するための行編集入力フィールドを持っています。この入力は1文字に制限されています。
ユーザーの入力がゲームのターゲット単語の文字と一致するかどうかを確認するforループが必要です。そうであれば、その文字が画面に配置されます。
私は、正しい文字列の文字の配置に対応するように1文字を入れたいと思うラベルをたくさん持っています。
Qt UI要素をデータ構造に入れて、forループでアクセスできるようにするにはどうすればよいですか?
ここに私が何をしようとしているのかを知るために、オンラインで見た後のいくつかのコードがあります。繰り返すことができる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]; 
     } 
    } 
} 

答えて

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ファイルに空のレイアウトを残し、必要に応じて要素をプログラムで挿入します。基本的なHangmanゲームウィジェットを設計してみましょう、そして、

// 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"}); 
    } 
}; 
} 

:まずは、最小限の.uiファイルからUICの出力を近似しましょう。文字ラベルを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" 
+0

ありがとうございます!これはそれを処理する良い方法のようです –

2
あなたが作品をやった

、可能な文字の数はおそらく26で固定されているので、(あなたには、いくつかの理由で非アルファベット文字を許可している場合を除き)、英語を想定し、それには何の問題も本当にありません。ラベルの数が可変であるか巨大である場合にのみ問題があり、どちらの状況もそうではないようです。

findChildrenメソッドを使用することもできますが、いくつかのバリエーションがあります。あなたのラベルのすべてが同じウィジェットに親されており、他のQLabelのインスタンスは、同じ親の下に存在しない場合、最も簡単なものである:

QList <QLabel *> parent->findChildren <QLabel *>(); 

そうでない場合、あなたはおそらく、正規表現を受け入れバリエーションを使用する必要があるだろう子の名前と一致する:

QList <QLabel *> parent->findChildren <QLabel *> (QRegExp ("^label_")); 

両方の場合の順序は、選択した文字でラベルを設定するためのものではないことに注意してください。ドキュメンテーションは言いませんが、返される注文には子供が作成された順序が反映されていると思います。Qtデザイナで作成したので、その順序は信頼できません。たとえば、途中で数字12を見つけずに他の数字の後に追加した場合、label_12はリストの最後になります。それはあなたのアプローチの残りの部分に応じて重要かもしれません。あなたのリストがラベル0、ラベル1の順になるようにする必要があるならば、あなたの現在のメカニズムはおそらくあなたが望むものです。

これは凶暴なように見えますが、時にはそれが完全に受け入れられます。あなたが持っているコードを皮切り

関連する問題