现在的位置: 首页 > 综合 > 正文

Qt 热键设置控件(批量版)

2013年08月30日 ⁄ 综合 ⁄ 共 7982字 ⁄ 字号 评论关闭

头文件

#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);
}


抱歉!评论已关闭.