头文件
#ifndef SHORTCUTSETTINGDLG_H #define SHORTCUTSETTINGDLG_H #include <QWidget> #include <set> class QSingleShortcut; class QShortcutSettingDlg : public QDialog { Q_OBJECT public: QShortcutSettingDlg(QWidget *parent); ~QShortcutSettingDlg(); //描述,以及对应的快捷键指针. void init(QStringList& list,vector<QShortcut*> &p); public slots: void slotFinish(); void slotCancel(); void slotEnable(int); void slotKeyWasSet(const QString&hotKey); public: bool isenable(){return m_bEnableAll;}; void setEnable(bool b){m_pBoxCheck->setChecked(!b);}; private: // vector<QString> m_strDescription; vector<QShortcut*> *m_pShortcut; vector<QSingleShortcut*> m_vecpItem;//快键键设置控件 QPushButton *m_pBtnOK;//确认按钮 QPushButton *m_pBtnCancel;//取消按钮 QCheckBox *m_pBoxCheck;//单选框 bool m_bEnableAll;//单选框对应的标识 bool m_bModfied; }; /*------------------------------------------------------ ------------------------------------------------------*/ class QSingleShortcut : public QWidget { Q_OBJECT public: QSingleShortcut(QWidget *parent,QString,QShortcut*); ~QSingleShortcut(); const QString& text(){return m_strkey;}; void reset(){m_pLineEdit->setText(m_strkey);}; signals: void signalNewShortcut(const QString&);//用于防止重复. protected: bool eventFilter(QObject *obj, QEvent *ev); private: QString m_strkey;//保存界面上已经设置好的快捷键. QString m_newkey;//临时的快捷键,当条件具备时,更新保存的 QShortcut *m_pShortcut; QLabel *m_pLabel; QLineEdit *m_pLineEdit; }; #endif // SHORTCUTSETTINGDLG_H
源文件
#include "StdAfx.h" #include "ShortcutSettingDlg.h" const int DEFALUTWIDTH=250;//默认宽度 const int DEFALUTHEIGHT=20;//默认高度 const int DEFALUTWSPACE=25; //默认间隔 const int DEFALUTHSPACE=5; //默认间隔 QShortcutSettingDlg::QShortcutSettingDlg(QWidget *parent) : QDialog(parent), m_bEnableAll(true), m_bModfied(false), m_pShortcut(0) { setWindowFlags(Qt::WindowSystemMenuHint|Qt::Window); setWindowTitle(QString::fromLocal8Bit("控制栏快捷键设置...")); m_pBoxCheck = new QCheckBox(QString::fromLocal8Bit("禁用热键"),this); m_pBoxCheck->setTristate(false); m_pBoxCheck->setCheckState(Qt::Unchecked); m_pBtnOK = new QPushButton(QString::fromLocal8Bit("确定"),this); m_pBtnCancel = new QPushButton(QString::fromLocal8Bit("取消"),this); int origin = 5; m_pBoxCheck->setGeometry(20,origin,70,20); m_pBtnOK->setGeometry(100,origin,80,20); m_pBtnCancel->setGeometry(195,origin,80,20); resize(300,origin+25); connect(m_pBtnOK,SIGNAL(clicked()),this,SLOT(slotFinish())); connect(m_pBtnCancel,SIGNAL(clicked()),this,SLOT(slotCancel())); connect(m_pBoxCheck,SIGNAL(stateChanged(int)),this,SLOT(slotEnable(int))); QPalette pal; pal.setBrush(QPalette::Window,QBrush(QColor(60,60,60))); setPalette(pal); setStyleSheet("QCheckBox,QLabel{color:white;};"); } QShortcutSettingDlg::~QShortcutSettingDlg() { } void QShortcutSettingDlg::slotEnable(int state) {// connect(m_pBoxCheck,SIGNAL(stateChanged(int)),this,SLOT(slotDisable(int))); // if ((state ==Qt::Unchecked && m_bEnableAll) // ||(state ==Qt::Checked && !m_bEnableAll)) // return; if (state == Qt::Unchecked) { m_bEnableAll = true; for (int i=0;i<m_vecpItem.size();i++) { m_vecpItem[i]->setEnabled(m_bEnableAll); } } else if (state == Qt::Checked) {//禁用所有热键同时设置标志. //貌似加一个中间层比较方便.暂时这样了 m_bEnableAll = false; for (int i=0;i<m_vecpItem.size();i++) { m_vecpItem[i]->setEnabled(m_bEnableAll); } } } void QShortcutSettingDlg::init(QStringList& list,vector<QShortcut*> &vec) { //数据 ENSURE(list.size() == vec.size()); m_pShortcut = &vec; for (int i=0; i<vec.size(); i++) { m_vecpItem.push_back(new QSingleShortcut(this,list.at(i),vec.at(i))); connect(m_vecpItem[i],SIGNAL(signalNewShortcut(QString)), this,SLOT(slotKeyWasSet(QString))); } //布局 int origin = DEFALUTHSPACE; for (int i=0;i<m_vecpItem.size();i++) {//快捷键 m_vecpItem[i]->setGeometry(DEFALUTWSPACE,origin,DEFALUTWIDTH,DEFALUTHEIGHT); origin += DEFALUTHEIGHT + DEFALUTHSPACE; } //按钮 m_pBoxCheck->setGeometry(20,origin,70,20); m_pBtnOK->setGeometry(100,origin,80,20); m_pBtnCancel->setGeometry(195,origin,80,20); setFixedSize(300,origin+25); } void QShortcutSettingDlg::slotFinish() { if (m_bEnableAll) { QString str; for (int i=0;i<m_vecpItem.size();i++) { str = m_vecpItem[i]->text(); m_pShortcut->at(i)->setKey(QKeySequence(str)); } } else { QString str; for (int i=0;i<m_vecpItem.size();i++) { // str = m_vecpItem[i]->newText(); m_pShortcut->at(i)->setKey(QKeySequence(str)); } } done(true); } void QShortcutSettingDlg::slotCancel() { if (m_bModfied) { int ret = QMessageBox::warning(this,QString::fromLocal8Bit("警告!"), QString::fromLocal8Bit("是否保存现有的更改?"), QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel, QMessageBox::Save); if (ret == QMessageBox::Save) slotFinish(); if (ret == QMessageBox::Cancel) return; } done(false); } void QShortcutSettingDlg::slotKeyWasSet(const QString&hotKey) { QString str; QSingleShortcut* p = (QSingleShortcut*)sender(); for (int i=0;i<m_vecpItem.size();i++) { str = m_vecpItem[i]->text();//m_strkey; if( str.compare(hotKey) == 0 ) { if (p == m_vecpItem[i])//帮大忙了... continue;//如果是同一个控件不考虑 p->reset(); QToolTip::showText(mapToGlobal(p->pos())+QPoint(75,0), QString::fromLocal8Bit("快捷键重叠!"),this); break; } } } /*---------------------------------------------------------------------- * * ----------------------------------------------------------------------*/ QSingleShortcut::QSingleShortcut(QWidget *parent,QString qstr,QShortcut* pshortcut) :QWidget(parent), m_pShortcut(pshortcut) { m_pLabel = new QLabel(qstr,this); m_pLineEdit = new QLineEdit(this); m_strkey = m_pShortcut->key().toString(); m_newkey = m_strkey; m_pLineEdit->setText(m_strkey); this->setFixedSize(250,20); m_pLabel->setGeometry(0,0,100,20); m_pLineEdit->setGeometry(100,0,150,20); m_pLineEdit->installEventFilter(this); } QSingleShortcut::~QSingleShortcut() { } bool QSingleShortcut::eventFilter(QObject *obj, QEvent *ev) { QLineEdit *pEdit = static_cast<QLineEdit*>(obj); if (ev->type() == QEvent::KeyPress) { QKeyEvent *e = static_cast<QKeyEvent*>(ev); m_newkey.clear(); qDebug()<<hex<<e->key()<<";"<<e->modifiers()<<";"<<e->text(); int mods = e->modifiers(); // if (mods&Qt::MetaModifier) // {//还是不用Win键了 // m_newkey += "Win+"; // } if (mods&Qt::ControlModifier) { m_newkey += "Ctrl+"; } if (mods&Qt::AltModifier) { m_newkey += "Alt+"; } if (mods&Qt::ShiftModifier) { m_newkey += "Shift+"; } //第二阶段:主要按键转换//苦力活 if (e->key()==Qt::Key_Shift ||e->key()==Qt::Key_Alt ||e->key()==Qt::Key_Control) // ||e->key()==Qt::Key_Meta)//还是不用Win键了 {//占位 } else if (e->key()==Qt::Key_Escape) {//Esc m_newkey += "Esc"; } else if(e->key()==Qt::Key_Home) {//Home m_newkey += "Home"; } else if(e->key()==Qt::Key_End) {//End m_newkey += "End"; } else if(e->key()==Qt::Key_Insert) {//Ins m_newkey += "Ins"; } else if(e->key()==Qt::Key_Delete) {//Del m_newkey += "Del"; } else if(e->key()==Qt::Key_PageUp) {//PageUp m_newkey += "PageUp"; } else if(e->key()==Qt::Key_PageDown) {//PageDown m_newkey += "PageDown"; } else if(e->key()==Qt::Key_Left) {//Left m_newkey += "Left"; } else if(e->key()==Qt::Key_Right) {//Right m_newkey += "Right"; } else if(e->key()==Qt::Key_Up) {//Up m_newkey += "Up"; } else if(e->key()==Qt::Key_Down) {//down m_newkey += "Down"; } else if (e->key()>0x40 && e->key()<0x5b) {//字符 if(!m_newkey.isEmpty()) {//不能单纯的字符 char c = 'A'; c += e->key()-0x41; m_newkey +=c; } else { QToolTip::showText(mapToGlobal(pEdit->pos()), QString::fromLocal8Bit("不能定义单一字符"),this); m_newkey = m_strkey; } } else if (e->key()>0x2f && e->key()<0x3a) {//数字 if(!m_newkey.isEmpty()) {//不能单纯的数字 char c = '0'; c += e->key()-0x30; m_newkey +=c; } else { QToolTip::showText(mapToGlobal(pEdit->pos()), QString::fromLocal8Bit("不能定义单一数字!"),this); m_newkey = m_strkey; } } else if (e->key()>0x0100002f && e->key()<0x01000053) {//F1~F35 //X11才有F25-F35 m_newkey += 'F'; m_newkey += QString::number(e->key()-0x0100002f); } else if (e->key()==Qt::Key_Backspace) {//自定义的清除快捷键操作 m_newkey.clear(); m_strkey.clear(); } else {//其他按键,两种处理方式 //m_newkey.clear();//清空 m_newkey = m_strkey;//还原 QToolTip::showText(mapToGlobal(pEdit->pos()), QString::fromLocal8Bit("不支持的热键!"),this); } //按键阶段结束,得到一个设置的键值 pEdit->setText(m_newkey); return true; } else if (ev->type() == QEvent::KeyRelease) { QKeyEvent *e = static_cast<QKeyEvent*>(ev); qDebug()<<e->key()<<";"<<e->modifiers()<<";"<<e->text(); if (e->key()==Qt::Key_Shift ||e->key()==Qt::Key_Alt ||e->key()==Qt::Key_Control) // ||e->key()==Qt::Key_Meta)//还是不用Win键了 {//辅助键释放,不需要处理 pEdit->setText(m_strkey); return true; } if (m_strkey == m_newkey)//一样的快捷键,不需要修改 { } // else if (m_newkey.right(1)==QString("+")) // {//还原处理 // pEdit->setText(m_strkey); // } else if (m_newkey.isEmpty()) { m_strkey.clear(); } else { emit signalNewShortcut(m_newkey); //最终更新 m_strkey = pEdit->text(); } return true; } //为了让Edit显示.后期可以自己drawText return QObject::eventFilter(obj,ev); }