QT裡Enter快捷鍵的設定
前些日子對於輸入拼音提示縮寫詞的那個程式一直在改進,具體就是通過鍵盤對於列表移動選中事件的響應。
UP、DOWN都很容易的實現了,但是Enter鍵卻一直都不能響應。
以前一直以為Enter的快捷鍵是Key_Enter,但是試了下不行。今天又仔細看了下manual,發現了Key_Enter後面有個Description:Typically located on the keypad.於是試了下小鍵盤區裡的Enter,果然好使。也就是說,Qt::Key_Enter這個提供的快捷鍵的響應其實是對小鍵盤區域的響應。那麼,對於另一個Enter也就是我們常用的Enter肯定會有另一個快捷鍵的定義。
若干查詢嘗試後,終於發現了Qt::Key_Return是對常用Enter鍵的快捷鍵響應,NND,起的名字這麼隱晦,猜都猜不出來。
想起前天在網上發了個貼求助的這個問題,既然已經解決,於是打算去把貼結了。不想剛開啟,發現有個剛剛哥們回答了,和我找到的是一樣的,太巧。
程式碼:
QShortcut *m_ALT_enter_Accel= new QShortcut(Qt::Key_Return, this);
connect(m_ALT_enter_Accel, SIGNAL(activated()), this, SLOT(enterTreeItem()));
CPP檔案:
更新下整個程式,新增快捷鍵上下Enter:
#include "convertpinyin.h"
convertPinyin::convertPinyin(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
readFile("./places.txt");
listwidget = new QListWidget(this);
listwidget->hide();
try
{
connect(ui.lineEdit,SIGNAL(textEdited(QString)),this,SLOT(generateList(QString)));
}
catch(...){
}
curRowNum = -1;
QShortcut *m_ALT_down_Accel= new QShortcut(Qt::Key_Down, this);
connect(m_ALT_down_Accel, SIGNAL(activated()), this, SLOT(downTreeItem()));
QShortcut *m_ALT_up_Accel= new QShortcut(Qt::Key_Up, this);
connect(m_ALT_up_Accel, SIGNAL(activated()), this, SLOT(upTreeItem()));
QShortcut *m_ALT_enter_Accel= new QShortcut(Qt::Key_Return, this);
connect(m_ALT_enter_Accel, SIGNAL(activated()), this, SLOT(enterTreeItem()));
}
convertPinyin::~convertPinyin()
{
}
string convertPinyin::getPinyin(string str){
char chr[3];
wchar_t wchr = 0;
char* buff = new char[str.length()/2];
memset(buff, 0x00, sizeof(char)*str.length()/2+1);
for (int i = 0, j = 0; i < (str.length()/2); ++i)
{
memset(chr, 0x00, sizeof(chr));
chr[0] = str[j++];
chr[1] = str[j++];
chr[2] = '\0';
// 單個字元的編碼 如:'我' = 0xced2
wchr = 0;
wchr = (chr[0] & 0xff) << 8;
wchr |= (chr[1] & 0xff);
buff[i] = convert(wchr);
}
return buff;
}
char convertPinyin::convert(wchar_t n)
{
if (In(0xB0A1,0xB0C4,n)) return 'a';
if (In(0XB0C5,0XB2C0,n)) return 'b';
if (In(0xB2C1,0xB4ED,n)) return 'c';
if (In(0xB4EE,0xB6E9,n)) return 'd';
if (In(0xB6EA,0xB7A1,n)) return 'e';
if (In(0xB7A2,0xB8C0,n)) return 'f';
if (In(0xB8C1,0xB9FD,n)) return 'g';
if (In(0xB9FE,0xBBF6,n)) return 'h';
if (In(0xBBF7,0xBFA5,n)) return 'j';
if (In(0xBFA6,0xC0AB,n)) return 'k';
if (In(0xC0AC,0xC2E7,n)) return 'l';
if (In(0xC2E8,0xC4C2,n)) return 'm';
if (In(0xC4C3,0xC5B5,n)) return 'n';
if (In(0xC5B6,0xC5BD,n)) return 'o';
if (In(0xC5BE,0xC6D9,n)) return 'p';
if (In(0xC6DA,0xC8BA,n)) return 'q';
if (In(0xC8BB,0xC8F5,n)) return 'r';
if (In(0xC8F6,0xCBF0,n)) return 's';
if (In(0xCBFA,0xCDD9,n)) return 't';
if (In(0xCDDA,0xCEF3,n)) return 'w';
if (In(0xCEF4,0xD1B8,n)) return 'x';
if (In(0xD1B9,0xD4D0,n)) return 'y';
if (In(0xD4D1,0xD7F9,n)) return 'z';
return '\0';
}
bool convertPinyin::In(wchar_t start, wchar_t end, wchar_t code)
{
if (code >= start && code <= end)
{
return true;
}
return false;
}
void convertPinyin::on_pushButton_clicked()
{
QString str = ui.lineEdit->text();
string sstr = wstring2string(str.toStdWString());
ui.label->setText(QString::fromStdString(getPinyin(sstr)));
}
string convertPinyin::wstring2string(wstring ws)
{
string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
string result = _Dest;
delete []_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
//根據輸入動態輸出符合條件的漢字詞語
void convertPinyin::generateList(QString pinyin){
curRowNum = -1;
vector<string> vec = getList(pinyin.toStdString());
//如果之前樹列表有內容
if (listwidget)
{
listwidget->clear();
delete listwidget;
listwidget = 0;
listwidget = new QListWidget(this);
for (int i = 0;i < vec.size();i++)
{
QListWidgetItem *item = new QListWidgetItem;
item->setText(tr(vec.at(i).c_str()));
listwidget->addItem(item);
}
}
connect(listwidget,SIGNAL(itemClicked(QListWidgetItem *)),this,SLOT(clickedListWidgetItem(QListWidgetItem *)));
//設定滑鼠滑過下拉詞框時的顏色
listwidget->setStyleSheet( "QListView::item:hover{background-color:rgb(0,0,200,50)}");
listwidget->setGeometry(ui.lineEdit->x(),ui.lineEdit->y() + ui.lineEdit->height(),ui.lineEdit->width(),25*vec.size());
listwidget->show();
}
//讀取指定路徑的檔案
void convertPinyin::readFile(QString filePath){
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
string shortPinyin = getPinyin(wstring2string(line.toStdWString()));
map<string,vector<string> >::iterator it = shortNameToFull.find(shortPinyin);
if (it != shortNameToFull.end())
{
//說明以前有該縮寫的地名,在之前的記錄上繼續新增
vector<string> vec = it->second;
vec.push_back(wstring2string(line.toStdWString()));
//刪除原來的
shortNameToFull.erase(it);
shortNameToFull.insert(make_pair(shortPinyin,vec));
}
else{
//說明是第一次新增該縮寫的地名
vector<string> vec;
vec.push_back(wstring2string(line.toStdWString()));
shortNameToFull.insert(make_pair(shortPinyin,vec));
}
}
}
vector<string> convertPinyin::getList(string strPinyin){
vector<string> vec;
map<string,vector<string> >::iterator it;
for (it = shortNameToFull.begin();it != shortNameToFull.end();it++)
{
if (isRightStr(strPinyin,it->first))
{
vector<string> tempVec = it->second;
for (int i = 0;i < tempVec.size();i++)
{
vec.push_back(tempVec.at(i));
}
}
}
return vec;
}
bool convertPinyin::isRightStr(string strPinyin,string comparedStr){
bool isRight = false;
if (strPinyin == comparedStr)
{
return true;
}
//否則,先進行長度比較
if (strPinyin.size() > comparedStr.size())
{
return false;
}
//到此說明輸入縮寫與要比較縮寫長度的關係為小於等於u
for (int i = 0;i < strPinyin.size();i++)
{
if (strPinyin.at(i) != comparedStr.at(i))
{
isRight = false;
break;
}
else{
isRight = true;
}
}
return isRight;
}
void convertPinyin::clickedListWidgetItem(QListWidgetItem *item){
QString str = item->text();
string s = wstring2string(str.toStdWString());
ui.lineEdit->setText(tr(s.c_str()));
listwidget->hide();
}
void convertPinyin::downTreeItem(){
curRowNum++;
if (curRowNum >= listwidget->count())
{
curRowNum--;
return;
}
listwidget->setCurrentRow(curRowNum);
}
void convertPinyin::upTreeItem(){
curRowNum--;
if (curRowNum < 0)
{
curRowNum++;
return;
}
listwidget->setCurrentRow(curRowNum);
}
void convertPinyin::enterTreeItem(){
QListWidgetItem *item1 = listwidget->item(curRowNum);
clickedListWidgetItem(item1);
.h檔案:
#ifndef CONVERTPINYIN_H
#define CONVERTPINYIN_H
#include <QtGui/QMainWindow>
#include "ui_convertpinyin.h"
#include <QtCore>
#include <QtGui>
#include <map>
#include <vector>
using namespace std;
class convertPinyin : public QMainWindow
{
Q_OBJECT
public:
convertPinyin(QWidget *parent = 0, Qt::WFlags flags = 0);
~convertPinyin();
private:
Ui::convertPinyinClass ui;
char convert(wchar_t n);
bool In(wchar_t start, wchar_t end, wchar_t code);
string getPinyin(string str);//根據漢字得到拼音縮寫
string wstring2string(wstring ws);
map<string,vector<string> > shortNameToFull;//建立拼音縮寫和地名的對應關係
QListWidget *listwidget;
void readFile(QString filePath);//讀取指定路徑的檔案
vector<string> getList(string strPinyin);//根據拼音縮寫查詢符合條件的地名
bool isRightStr(string strPinyin,string comparedStr);//符合提示條件的,比如輸入bj,符合條件的漢語詞縮寫可以是bj,也可以是以bj縮寫詞開頭的詞語
int curRowNum;
private slots:
void on_pushButton_clicked();
void generateList(QString str);//根據輸入拼音的變化動態生成漢字提示
void clickedListWidgetItem(QListWidgetItem *);//點選下拉框中某個詞
void downTreeItem();
void upTreeItem();
void enterTreeItem();
};
#endif // CONVERTPINYIN_H
}