2012-06-23 53 views
1

我想創建一個派生自QLineEdit的類,但我無法爲Escape按鈕指定一個信號。QLineEdit和Escape Signal

代碼正在工作,直到我添加了cancel_signal(),然後出現了LNK2019/LNK1120錯誤。

如何爲逃生按鈕指定一個信號?


LineEditAlphaNum.h:

#ifndef _LINEEDIT_ALPHA_NUM_ 
#define _LINEEDIT_ALPHA_NUM_ 

#include <QtGui> 

class LineEditAlphaNum : public QLineEdit 
{ 
public: 
    LineEditAlphaNum(QWidget* parent); 

    void setPrevNextWidget(QWidget* prev, QWidget* next); 

protected: 
    void keyPressEvent(QKeyEvent *); 

private: 
    void keyLogic(QString& str, int key); 

    int keyIndex; 
    int lastKey; 

    QWidget* m_pPrev; 
    QWidget* m_pNext; 

signals: 
    void cancel_signal(); 
}; 

#endif // _LINEEDIT_ALPHA_NUM_ 

LineEditAlphaNum.cpp:

#include "LineEditAlphaNum.h" 

LineEditAlphaNum::LineEditAlphaNum(QWidget *parent) : 
    QLineEdit(parent), 
    keyIndex(0), 
    lastKey(0) 
{ 
} 

void LineEditAlphaNum::keyPressEvent(QKeyEvent *e) 
{ 
    QString str = text(); 

    switch(e->key()) 
    { 
    case Qt::Key_Escape: 
     emit cancel_signal(); 
    case Qt::Key_Up: 
     m_pPrev->setFocus(Qt::OtherFocusReason); 
     break; 
    case Qt::Key_Down: 
     m_pNext->setFocus(Qt::OtherFocusReason); 
     break; 
    case Qt::Key_Right: 
     keyIndex = 0; 
     lastKey = e->key(); 
     break; 
    case Qt::Key_0: 
    case Qt::Key_1: 
    case Qt::Key_2: 
    case Qt::Key_3: 
    case Qt::Key_4: 
    case Qt::Key_5: 
    case Qt::Key_6: 
    case Qt::Key_7: 
    case Qt::Key_8: 
    case Qt::Key_9: 
     keyLogic(str, e->key()); 
     break; 
    case Qt::Key_Backspace: 
     str.remove(str.size()-1, 1); 
     break; 

    default: 
     break; 
    } 

    setText(str); 
} 

void LineEditAlphaNum::keyLogic(QString& str, int key) 
{ 
    char* Keys[] = {"0 ", 
        "1", 
        "2ABC", 
        "3DEF", 
        "4GHI", 
        "5JKL", 
        "6MNO", 
        "7PQRS", 
        "8TUV", 
        "9WXYZ"}; 

    char* keymap = Keys[ key - Qt::Key_0 ]; 
    int length = strlen(keymap); 

    if (lastKey == key) 
    { 
     keyIndex = (++keyIndex) % length; 
     str.remove(str.size()-1, 1); 
    } 
    else 
    { 
     keyIndex = 0; 
     lastKey = key; 
    } 

    str.append(QChar(keymap[keyIndex])); 
} 
void LineEditAlphaNum::setPrevNextWidget(QWidget* prev, QWidget* next) 
{ 
    m_pPrev = prev; 
    m_pNext = next; 
} 
+0

請注意,如果您希望用戶能夠使用退格鍵和刪除鍵移動光標並刪除任何字符(不僅是最後一個字符),您應該將左,右,退格鍵和刪除鍵轉發給超級用戶類事件處理程序。 – leemes

+0

另外請注意,如果你的「小部件的鏈表」不是循環的,但你在兩端都有空指針,你應該在訪問成員函數之前檢查空指針(在你的情況下上/下鍵)。 – leemes

回答

3

因爲信號是一個C++函數,你得到這個鏈接錯誤,尚未定義。這通常由moc完成,它不會生成你的類的一些代碼。

每當你想使用信號和槽在QObject派生類或需要別的東西,它使用QMetaObject,你需要你的類定義的左大括號後添加

Q_OBJECT 

注意,當您添加該宏,你還需要手動運行QMAKE,因爲QtCreator試圖聰明,如果.pro文件並沒有改變跳過此構建步驟。但是Q_OBJECT宏的前置或不存在必須被視爲qmake的更改,因爲moc(元對象編譯器)需要在類定義中的所有具有Q_OBJECT宏的文件上運行。

+0

謝謝,我真的離開了它,你救了我一個巨大的負擔 – amcali

+0

@amcali沒問題:)我的建議是:讓自己一個檢查清單,你應該檢查/做任何事情,只要你的程序不編譯。這個列表可能包含:在QObject派生類中插入'Q_OBJECT'宏,手動重新運行'qmake',完全重建你的應用程序,...(有些人不能解釋一些編譯器/鏈接器錯誤,它們是由一些丟失Makefile中的依賴關係或其他...) – leemes