2014-02-21 25 views
1

我正在開發一個銷售點應用程序,我有一個函數從QLineEdit(產品的條形碼)獲取文本並運行一個查詢查找產品顯示。問題是每次文本更改時都會運行查詢,即每次鍵入新字符時都會運行查詢。有沒有辦法等待用戶停止鍵入,然後運行查詢?我將使用手持式掃描儀,因此每個輸入字符之間的距離應爲100毫秒。等待在QLineEdit中輸入的最後一個字符:: onTextChanged

我想我需要這樣的:

void PoS::on_lineEdit_textEdited() 
{ 
    //check for keys still being pressed 
    //if 100ms have passed without any key press, run query 
} 

我曾嘗試使用計時器,也線程(我是很新的Qt的5),但到目前爲止都失敗了。

回答

3

您將需要一個計時器。閱讀更多關於QTimer這裏:http://qt-project.org/doc/qt-5.1/qtcore/qtimer.html

添加一個QTimer *mTimer作爲私有成員變量。創建一個名爲例如do_query的插槽,您將在其中進行查詢。將這個地方在構造函數:

mTimer = new QTimer(this); // make a QTimer 
mTimer->setSingleShot(true); // it will fire once after it was started 
connect(mTimer, &QTimer::timeout, this, &PoS::do_query); // connect it to your slot 

現在,在你的函數:

void PoS::on_lineEdit_textEdited() 
{ 
    mTimer->start(100); // This will fire do_query after 100msec. 
    // If user would enter something before it fires, the timer restarts 
} 

,做你的查詢:

void PoS::do_query() 
{ 
    // your code goes here 
} 
+0

工程就像一個魅力!這正是我需要的。謝謝 – user3338859

+0

簡單而優雅!我將在Qt維基上的相關頁面上添加(具有適當的歸屬),以增加其可見性:https://wiki.qt.io/Delay_action_to_wait_for_user_interaction – waldyrious

0

有兩種方法:

  1. 查詢最後一次更改後100毫秒。爲此,你(重新)在按鍵上啓動一個100ms的定時器。當它到期時,您運行查詢。

  2. 查詢 100毫秒,而用戶正在進行更改。按下按鍵可以開始100ms的時間,但只有當它還沒有運行時。當它到期時,您運行查詢。

如果要實現在一個單獨的QObject查詢處理器,然後你可以平凡它移到一個單獨的線程 - 但要確保你已經創建了一個線程的數據庫連接了。 UI對象和查詢處理器之間唯一的通信方式應該是通過信號/插槽 - 這樣就可以處理線程之間的同步數據交換。

您可以刪除moveToThread調用:它仍然有效。然後,在GUI線程中運行查詢執行程序,因此數據庫驅動程序通常在查詢處理期間阻塞時,用戶體驗可能會更糟。

#include <QApplication> 
#include <QTextEdit> 
#include <QBasicTimer> 
#include <QSqlDatabase> 
#include <QThread> 

class ProductData { 
}; 
Q_DECLARE_METATYPE(ProductData) 

class PoS : public QWidget { 
    Q_OBJECT 
    enum QueryBehavior { FinalQuery, MultipleQuery }; 
    QBasicTimer m_queryTimer; 
    QueryBehavior m_queryBehavior; 
    Q_SLOT void on_lineEdit_textEdited() { 
     if (m_queryBehavior == FinalQuery || !m_queryTimer.isActive()) 
     m_queryTimer.start(100, this); 
    } 
    void timerEvent(QTimerEvent * ev) { 
     if (ev->timerId() != m_queryTimer.timerId()) return; 
     m_queryTimer.stop(); 
     emit queryRequest(); 
    } 
public: 
    Q_SIGNAL void queryRequest(); 
    Q_SLOT void queryResponse(const ProductData &) { /* ... */ } 
    // ... 
}; 

class QueryExecutor : public QObject { 
    Q_OBJECT 
    QSqlDatabase m_dbConnection; 
public: 
    Q_SLOT void queryRequest() { 
     if (!m_dbConnection.isOpen()) { 
     // Open the database connection here, NOT in the constructor. 
     // The constructor executes in the wrong thread. 
     // ... 
     } 
     ProductData pdata; 
     // ... 
     emit queryResponse(pdata); 
    } 
    Q_SIGNAL void queryResponse(const ProductData &); 
}; 

//! A thread that's always safe to destruct. 
class Thread : public QThread { 
private: 
    using QThread::run; // This is a final class. 
public: 
    Thread(QObject * parent = 0) : QThread(parent) {} 
    ~Thread() { quit(); wait(); } 
}; 

int main(int argc, char ** argv) { 
    QApplication app(argc, argv); 
    qRegisterMetaType<ProductData>(); 
    PoS pos; 
    QueryExecutor executor; 
    Thread thread; // must come after the executor! 
    thread.start(); 
    executor.moveToThread(&thread); 
    executor.connect(&pos, SIGNAL(queryRequest()), SLOT(queryRequest())); 
    pos.connect(&executor, SIGNAL(queryResponse(ProductData)), SLOT(queryResponse(ProductData))); 
    pos.show(); 
    return app.exec(); 
} 

#include "main.moc" 
相關問題