QT之桌面精灵实现(二) --- 右键菜单、开机启动、窗口Z-Order

时间:2022-06-25 20:39:19

1、右键菜单。

这个其实用QT实现容易过头了,不过其中还是被卡了一下,就是给右键菜单选项前面打钩那个功能,首先是不知道该怎么形容,怎么搜都搜不到,后来去慢慢研究帮助文档,总算是弄出来了。

首先才创建菜单项和添加项,然后绑定槽

	act_about = new QAction(tr("关于"), this);
	act_autoRun = new QAction(tr("开机启动"), this);
	act_autoRun->setCheckable(true);//设置可选
	act_autoRun->setChecked(bAutoRun);//设置是否选中
	act_exit = new QAction(tr("退出"), this);
	menu=new QMenu(this);
	menu->addAction(act_about); //添加菜单项1
	menu->addAction(act_autoRun);
	menu->addAction(act_exit); //添加菜单项2
	
	connect(menu, SIGNAL(aboutToHide()), this, SLOT(AboutToHide()));
	connect(menu, SIGNAL(aboutToShow()), this, SLOT(AboutToShow()));
	connect(act_exit, SIGNAL(triggered()), this, SLOT(close()));
	connect(act_exit, SIGNAL(triggered()), this, SLOT(Close()));
	connect(act_about, SIGNAL(triggered()), this, SLOT(About()));
	connect(act_autoRun, SIGNAL(toggled (bool)), this, SLOT(Check(bool)));

目前只有三个项:关于、开机启动、退出。

QT之桌面精灵实现(二) --- 右键菜单、开机启动、窗口Z-Order

	act_autoRun->setCheckable(true);//设置可选
	act_autoRun->setChecked(bAutoRun);//设置是否选中
上面两句就是自己查文档弄出来的。

其实现在还有个问题,就是本来是打算点击“关于”后,弹出的窗口是模态的,但是似乎找不到设置模态的方法。事实上右键菜单弹出来的时候就应该是模态的,因为不知道怎么设置所以在菜单出现和消息上做了点手脚。

关于的显示很简单,直接使用了QMessageBox::about

QT之桌面精灵实现(二) --- 右键菜单、开机启动、窗口Z-Order

这里补充一个问题,就是乱码。唯一出现中文的就是这里了,网上各种方法乱七八糟,最后找到奏效的只有这个方法:

QTextCodec *codec = QTextCodec::codecForName("System");  
	QTextCodec::setCodecForLocale(codec);  
	QTextCodec::setCodecForCStrings(codec);  
	QTextCodec::setCodecForTr(codec); 

关键在System那里,其他什么方法的都不记得了,总之就是无效。


2、开机启动

这个本来应该是一个很简单的问题,但是因为之前找的方法好像是路径有错了,无论如何都注册不到注册表里,因为我检查了很多次似乎都没有错,直到我下定决心去复制了另一个路径才正确注册进去了

reg = new QSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",QSettings::NativeFormat);
	
	bool bAutoRun = false;
	QString path = QApplication::applicationFilePath();
	if (reg->value("DeskTopSprite").toString() == path)//判断是否已经注册
		bAutoRun = true;
在响应Action里面:

void DeskTopSprite::Check( bool bCheck )
{
	//开机自动运行
	if (bCheck)
	{
		reg->setValue("DeskTopSprite",QApplication::applicationFilePath());
	}
	else
	{
		reg->setValue("DeskTopSprite","");
	}
}

3、窗口Z-Order

这个其实非常简单,但是由于没有对其有个根本的认知才导致花了很多时间。这个问题似乎也很少人问,也可能是搜索的关键字不对,至少我在百度里用Z-Order是搜不到的。我是在谷歌搜QT WindowStaysOnTopHint order,然后看到某人提到Z-Order,瞬间恍然大悟,原来窗口直接的顺序也是Z-Order啊。说白了是我对Z-Order有重大误解,因为最早开始做2D游戏的时候,是基于D3D的,所以任务Z-Order这种东西是只有3D才有的概念,纯2D拿来的Z-Order呢?但事实上如果不用这个词,就没法形容这个问题了。

问题的起源是Top-Level窗口,也就是置顶窗口,非置顶窗口,哪个被激活哪个就在最上面,而置顶窗口就永远在最上面,所以如果不手动去干涉它们的顺序,它们创建出来的时候什么顺序就是什么顺序,如果这时候你拖动一个Top-Level的窗口到另一个上面,就可能会发现怎么跑到下面去了的情况,所以这时候就需要把被拖拽的窗口提上来。

QT里一个raise()函数就搞定了,我差API的时候只顾着查set开头的函数,根本没注意这个东西的存在!

void DeskTopSprite::mousePressEvent(QMouseEvent *event)
{
	raise();
	if(event->button() == Qt::LeftButton)
	{
		oldPos = event->globalPos();
		press = true;
		LuaFunctionVoid fun = gLua->GetGlobal("OnHit");
		fun(event->globalX () , event->globalY (), event->x(), event->y());
	}
}

在鼠标点击的时候调用一下,就能保证被拖拽的窗口在最上面