前些日子对于输入拼音提示缩写词的那个程序一直在改进,具体就是通过键盘对于列表移动选中事件的响应。
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
}