1

私が取り組んでいるアプリケーションでは、標準の QObject::connect でスロットに接続された QLineEdit があります。

QObject::connect(m_searchBar, SIGNAL(textChanged(const QString &)),this,SLOT(slot_searchBar()));

ご覧のとおり、textChanged シグナルを私の作成したスロットに接続しています。このスロットは次のようになります。

   void LibraryWidget::slot_searchBar() 
{
    QString stringToFind = m_searchBar->text();

    m_searchResults->clear();
    if(stringToFind.isEmpty())
    {
        //set stacked widget back to the library when no text in search bar 
        m_libraryAndSearch->setCurrentWidget(libTree);
    } 
    else 
    {
        //show the search results
        QFont headerFont;
        QTreeWidgetItem * searchingMsg = new QTreeWidgetItem;
        headerFont = searchingMsg->font(0);
        headerFont.setBold(false);
        headerFont.setItalic(true);
        searchingMsg->setText(0, "Searching...");
        searchingMsg->setFont(0, headerFont);
        Qt::ItemFlags currentState = searchingMsg->flags();
        Qt::ItemFlags noSelect = (!(Qt::ItemIsSelectable) & currentState);
        searchingMsg->setFlags(noSelect);
        m_searchResults->addTopLevelItem(searchingMsg);
        m_libraryAndSearch->setCurrentWidget(m_searchResults);
        //m_searchThread->setTerminateAndWait();    
        //m_searchThread->beginThread(stringToFind);
        int testTwo = 0;
        for(int testInt = 0; testInt < 1000000000; testInt++)
        {
            testTwo++;
        }
        int testingThree = 0;
    }
}

これは重要性が限定されていることを願っていますが、問題の根本がここにある場合に備えて、表示するのがおそらく最善です.

問題の QLineEdit である検索バーに文字列を入力し (非常にすばやく)、接続されているデバッガー (Visual Studio 2010) で何が起こっているかを見ると、最も奇妙なことがわかります。

検索バーに既に "Jake" がある場合 (以前の検索でゆっくりと入力した場合)、すぐに "gh" と入力stringToFindすると、スロットの最初の実行では値が "Jakegh" になり、2 回目の実行では "Jakeg" になります。 .

Qt がシグナルの送信をキューではなくスタックに追加し、逆の順序でイベント ループに戻したようです。

質問は、ここで何が起こっているのか手がかりを持っている人はいますか? 誰かが同様の結果を経験しましたか?

Qt バージョン 4.7

現状のコードは問題を再現するだけで、何もしません。int testTwo -> int testingThree は、コードを遅くするためだけに存在します。

ありがとう...

EDIT 文字列が関数の引数としてスロットに渡された場合、同じ動作が観察されました。この線

QString stringToFind = m_searchBar->text();

この現象をデバッグして回避する試みでした。

編集 2

これを自宅で再現してみました。Mac OS X 10.7 のターミナルから Qt をビルドしているため、デバッガーは使用できません。上記と同じ形式の非常に単純なクラスと main.cpp を使用していますが、Qt に文字を逆の順序で提供させることはできません。信号を逃すことはできますが。行編集でテキストが変更されるたびに、 を使用してテキスト編集に出力されるように、行編集をテキスト編集に接続しましたQTextEdit::append(( const QString & text ))

たとえば、「N」、「e」、「w」と入力すると、「N」、「Ne」、「New」がテキスト編集に出力されます。ただし、代わりに「N」、「New」と表示されることがあります。すべてを遅くする for ループがあり、キーを非常に速く打たなければなりません。

この現象を最初に発生させたシステムは、必然的に私が構築したものよりもはるかに複雑であり、デバッグで実行され、実行が遅かった. なぜそれが動作を引き起こすのかはまだわかりませんが、間違いなくそうでした!

4

2 に答える 2

0

明らかな問題は、おそらく実際の検索が行うことをエミュレートする遅延ループです。それはまさにそれにアプローチする間違った方法です。検索は、別のスレッドに移動できる別の QObject で非同期に実行する必要があります。検索バーのシグナルをサーチャー オブジェクトに接続するだけで、サーチャーが新しい結果を取得したときにシグナルが返されます。

テスト遅延ループはQTimer::singleShot(1000, this, SLOT(fakeResults()))、スロット内のコードが GUI 内の関連するスロットを呼び出して偽の結果を出すようなものに置き換える必要があります。

物事を監視するために、「ウォッチャー」オブジェクトも QLineEdit にアタッチすることをお勧めします。方法は次のとおりです。

// in some file, say foo.cpp
class Watcher : public QObject
{
  Q_OBJECT
  QPointer<QLineEdit*> const edit;
public:
  Watcher(QLineEdit * ed, QObject * parent = 0) : QObject(parent), edit(ed) {
    connect(ed, SIGNAL(textChanged(QString)), SLOT(monitor(QString)));
  }
public slots:
  void monitor(const QString & str) {
    qDebug("Line edit signals text: %s", str.toLocal8Bit().constData());
    if (! edit.isNull() && edit->text() != str) {
      qDebug("... but line edit has text %s", edit->text().toLocal8Bit().constData());
    }
  }
}

#include "foo.moc" // replace 'foo' with actual name of the file (sans .cpp)
于 2012-06-11T20:10:20.190 に答える
0

テキストを取得しないでください。シグナルで QString & を使用してください。

QObject::connect(m_searchBar, SIGNAL(textChanged(const QString &)),this,SLOT(slot_searchBar(const QString &))); 

そしてその後

void LibraryWidget::slot_searchBar(const QString &stringToFind) {
...

あなたがあなたの行動を見ている理由については、ある時点でそれが Qt::QueuedConnection であることをほぼ保証できます。シングルスレッドコードでも QueuedConnection を使用できます。次のイベントループまで待ってコードを実行します。詳細を確認してください: http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum

于 2012-06-11T20:13:14.463 に答える