#QWidget设置Qt::FramelessWindowHint后,窗体原有任务栏功能和拖拽缩放功能消失
#软件用的QT6开发,目前使用了监听nativeEvent方法,能做到窗体移动和拖拽控制大小,但是任务栏功能消失了。请问资深的qt专家,上述的问题如何实现,目前网上的介绍大多从监控鼠标事件入手,自定义这些功能,效果不好。有如下几点期望:
1 鼠标调整窗口大小高效灵活
2 窗口移动时不卡顿
3 点击任务栏图标窗口能显示或隐藏
#QWidget设置Qt::FramelessWindowHint后,窗体原有任务栏功能和拖拽缩放功能消失
#软件用的QT6开发,目前使用了监听nativeEvent方法,能做到窗体移动和拖拽控制大小,但是任务栏功能消失了。请问资深的qt专家,上述的问题如何实现,目前网上的介绍大多从监控鼠标事件入手,自定义这些功能,效果不好。有如下几点期望:
1 鼠标调整窗口大小高效灵活
2 窗口移动时不卡顿
3 点击任务栏图标窗口能显示或隐藏
引自免费微信小程序:皆我百晓生
在Qt中,当您设置了Qt::FramelessWindowHint
属性时,窗口会失去系统默认的标题栏、边框以及任务栏操作。为实现自定义无边框窗口的同时保持高效的拖拽缩放和任务栏功能,您可以按照以下步骤进行:
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
mousePressPosition = event->globalPos() - this->frameGeometry().topLeft();
event->accept();
}
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
move(event->globalPos() - mousePressPosition);
event->accept();
}
}
bool isResizeArea(const QPoint &pos)
{
QRect rect = this->rect();
int margin = 8; // 自定义可调整大小的边距
return pos.x() >= rect.left() && pos.x() <= rect.right() - margin &&
pos.y() >= rect.top() + margin && pos.y() <= rect.bottom() - margin;
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (isResizeArea(event->pos())) {
resizing = true;
resizeStartPoint = event->globalPos();
resizeEdge = getResizeEdge(event->pos());
event->accept();
}
// ...(上述窗口移动事件代码)
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (resizing) {
QSize newSize = this->size();
switch (resizeEdge) {
case Top:
newSize.setHeight(resizeStartPoint.y() - event->globalY());
break;
case Bottom:
newSize.setHeight(event->globalY() - resizeStartPoint.y());
break;
case Left:
newSize.setWidth(resizeStartPoint.x() - event->globalX());
break;
case Right:
newSize.setWidth(event->globalX() - resizeStartPoint.x());
break;
case TopLeft:
case BottomRight:
newSize.setWidth(resizeStartPoint.x() - event->globalX());
newSize.setHeight(event->globalY() - resizeStartPoint.y());
break;
case TopRight:
case BottomLeft:
newSize.setWidth(event->globalX() - resizeStartPoint.x());
newSize.setHeight(resizeStartPoint.y() - event->globalY());
break;
default:
break;
}
// 添加最小尺寸限制
newSize = newSize.expandedTo(minimumSize());
setFixedSize(newSize);
event->accept();
}
// ...(上述窗口移动事件代码)
}
Qt::Edges MainWindow::getResizeEdge(const QPoint &pos)
{
QRect rect = this->rect();
int margin = 8;
if (pos.y() <= margin) {
if (pos.x() <= margin)
return Qt::TopLeft;
else if (pos.x() >= rect.right() - margin)
return Qt::TopRight;
else
return Qt::Top;
} else if (pos.y() >= rect.bottom() - margin) {
if (pos.x() <= margin)
return Qt::BottomLeft;
else if (pos.x() >= rect.right() - margin)
return Qt::BottomRight;
else
return Qt::Bottom;
} else if (pos.x() <= margin)
return Qt::Left;
else if (pos.x() >= rect.right() - margin)
return Qt::Right;
else
return Qt::NoEdge;
}
void MainWindow::mouseReleaseEvent(QMouseEvent *)
{
resizing = false;
}
Qt::FramelessWindowHint
,但只要窗口是顶级窗口并且正常创建,它应该仍然会在任务栏上显示。要响应点击任务栏图标显示/隐藏窗口,需要处理show()
和hide()
信号或者activateWindow()
方法。例如,在你的主窗口类中:// 假设你有一个 TrayIcon 类实例 trayIcon
QSystemTrayIcon *trayIcon = new QSystemTrayIcon(this);
// 设置托盘图标和关联的上下文菜单
// ...
connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick)
this->setVisible(!this->isVisible()); // 切换窗口显示与隐藏
});
// 在构造函数或初始化阶段设置好 trayIcon 后,记得调用 show()
trayIcon->show();
以上代码片段将帮助您实现一个无边框窗口的高效拖拽和缩放功能,同时确保窗口能够在任务栏正确显示和隐藏。请注意,根据您的具体需求可能需要对代码进行微调以适应不同的场景。