C++ 通过单击内部小部件而不是标题栏来移动窗口
在Windows中,当我创建QMainWindow时,我可以通过单击标题栏并拖动它在屏幕上移动它 在我的应用程序中,我通过使用C++ 通过单击内部小部件而不是标题栏来移动窗口,c++,qt,window,mousemove,titlebar,C++,Qt,Window,Mousemove,Titlebar,在Windows中,当我创建QMainWindow时,我可以通过单击标题栏并拖动它在屏幕上移动它 在我的应用程序中,我通过使用setWindowFlags(Qt::CustomizeWindowint)隐藏了标题栏,我试图使用小部件构建一个自定义标题栏,并使用setMenuWidget(myWidget)在菜单空间中设置它 现在,我想重现最初的行为:我想在QMainWindow中单击我的MyWidget小部件,当按下鼠标时,拖动鼠标移动窗口 有办法吗?您只需要通过覆盖MyWidget的mouse
setWindowFlags(Qt::CustomizeWindowint)
隐藏了标题栏,我试图使用小部件构建一个自定义标题栏,并使用setMenuWidget(myWidget)
在菜单空间中设置它
现在,我想重现最初的行为:我想在QMainWindow中单击我的MyWidget
小部件,当按下鼠标时,拖动鼠标移动窗口
有办法吗?您只需要通过覆盖
MyWidget
的mousePressEvent()
、mouseMoveEvent()
和mousereleasevent()
处理程序来实现必要的鼠标事件处理
您可以通过
window()
方法从MyWidget
内部获取窗口(顶级小部件)。您只需通过覆盖MyWidget
的mousePressEvent()
、mouseMoveEvent()
和mousereleasevent()
处理程序来实现必要的鼠标事件处理
您可以通过
window()
方法从MyWidget
内部获取窗口(顶级小部件)。这是一个关于如何实现假标题栏的示例,该标题栏具有标准按钮(最小化、最大化、关闭),可以拖动以移动整个窗口(这基于@Kevin回答中的方法)
#包括
类FakeTitleBar:publicqwidget{
Q_对象
公众:
显式FakeTitleBar(QWidget*parent=nullptr):QWidget(parent){
label.setSizePolicy(QSizePolicy::Expansing,
QSizePolicy::扩展);
layout.addWidget(&label);
layout.addWidget(&buttonMinimize);
layout.addWidget(&buttonMaximize);
layout.addWidget(&buttonClose);
//将按钮信号连接到插槽
连接(&Button最小化,&QPushButton::单击,
这,&FakeTitleBar::MinimizeWindow);
连接(&buttonMaximize,&QPushButton::单击,
这,&FakeTitleBar::MaximizeWindow);
连接(&buttonClose,&QPushButton::单击,
这是(FakeTitleBar::CloseWindow);
//设置垂直固定大小策略
//这样标题栏就不会占用任何额外的空间
设置策略(QSizePolicy::首选,QSizePolicy::固定);
//一点造型
setStyleSheet(“QPushButton{margin:0px;padding:5px;}”
“QWidget{背景色:蓝色;颜色:白色;}”);
}
公众时段:
//对应按钮的插槽
void MinimizeWindow(){
window()->showmimized();
}
void MaximizeWindow(){
如果(!window()->isMaximized())
window()->showMaximized();
其他的
window()->showNormal();
}
void CloseWindow(){
window()->close();
}
受保护的:
作废鼠标压力事件(QMouseEvent*事件){
//保存按键位置(相对于当前小部件)
按pos=事件->pos();
isMoving=真;
}
作废mouseMoveEvent(QMouseEvent*事件){
//isMoving标志确保拖放事件起源于
//从标题栏中,因为否则窗口不应移动
如果(正在移动){
//计算按下位置和新鼠标位置之间的差值
//(这是相对于当前小部件的)
QPoint diff=事件->位置()-按位置;
//通过不同的方式移动窗口
window()->move(window()->pos()+diff);
}
}
无效mouseReleaseEvent(QMouseEvent*/*event*/){
//拖放操作结束
isMoving=假;
}
//双击标题栏可以使窗口最大化
void mouseDoubleClickEvent(QMouseEvent*/*event*/){
最大化窗口();
}
//以便样式表应用于此自定义小部件
//看https://doc.qt.io/qt-5/stylesheet-reference.html#qwidget-小部件
无效paintEvent(QPaintEvent*)
{
qstyleopt;
选择初始(本);
油漆工p(本);
style()->drawPrimitive(QStyle::PE_小部件,&opt,&p,this);
}
私人:
QHBoxLayout布局{this};
QLabel标签{“假标题栏”};
QPushButton按钮最小化{“-”};
QPushButton按钮最大化{“M”};
QPushButton按钮关闭{“X”};
点按位置;
布尔·伊斯莫温{false};
};
//样本使用
类Widget:publicqwidget{
公众:
显式小部件(QWidget*parent=nullptr):QWidget(parent){
setWindowFlags(Qt::CustomizeWindowint);
layout.addWidget(标题栏和标题栏);
layout.addWidget(&label);
布局.setContentsMargins(0,0,0,0);
label.setAlignment(Qt::AlignCenter);
//窗口的默认大小
调整大小(320240);
}
~Widget(){}
私人:
QVBoxLayout布局{this};
FakeTitleBar标题栏;
QLabel标签{“这是一个示例窗口”};
};
int main(int argc,char*argv[]){
QApplication应用程序(argc、argv);
小部件w;
w、 show();
返回app.exec();
}
#包括“main.moc”
这是一个关于如何实现假标题栏的示例,该标题栏具有标准按钮(最小化、最大化、关闭),可以拖动以移动整个窗口(这是基于@Kevin答案中的方法)
#包括
类FakeTitleBar:publicqwidget{
Q_对象
公众:
显式FakeTitleBar(QWidget*parent=nullptr):QWidget(parent){
标签设置策略(QS)
#include <QtWidgets>
class FakeTitleBar : public QWidget{
Q_OBJECT
public:
explicit FakeTitleBar(QWidget* parent= nullptr):QWidget(parent){
label.setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
layout.addWidget(&label);
layout.addWidget(&buttonMinimize);
layout.addWidget(&buttonMaximize);
layout.addWidget(&buttonClose);
//connecting buttons' signals to slots
connect(&buttonMinimize, &QPushButton::clicked,
this, &FakeTitleBar::MinimizeWindow);
connect(&buttonMaximize, &QPushButton::clicked,
this, &FakeTitleBar::MaximizeWindow);
connect(&buttonClose, &QPushButton::clicked,
this, &FakeTitleBar::CloseWindow);
//setting vertical fixed size policy
//so that the title bar does not take up any additional space
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
//a bit of styling
setStyleSheet("QPushButton {margin:0px; padding:5px;}"
"QWidget {background-color:blue; color:white;}");
}
public slots:
//slots for corresponding buttons
void MinimizeWindow(){
window()->showMinimized();
}
void MaximizeWindow(){
if(!window()->isMaximized())
window()->showMaximized();
else
window()->showNormal();
}
void CloseWindow(){
window()->close();
}
protected:
void mousePressEvent(QMouseEvent* event){
//save the press position (this is relative to the current widget)
pressPos= event->pos();
isMoving= true;
}
void mouseMoveEvent(QMouseEvent* event){
//isMoving flag makes sure that the drag and drop event originated
//from within the titlebar, because otherwise the window shouldn't be moved
if(isMoving){
//calculate difference between the press position and the new Mouse position
//(this is relative to the current widget)
QPoint diff= event->pos() - pressPos;
//move the window by diff
window()->move(window()->pos()+diff);
}
}
void mouseReleaseEvent(QMouseEvent* /*event*/){
//drag and drop operation end
isMoving= false;
}
//double-clicking on the title bar should maximize the window
void mouseDoubleClickEvent(QMouseEvent* /*event*/){
MaximizeWindow();
}
//in order for the style sheet to apply on this custom widget
//see https://doc.qt.io/qt-5/stylesheet-reference.html#qwidget-widget
void paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
private:
QHBoxLayout layout{this};
QLabel label{"Fake Title Bar"};
QPushButton buttonMinimize{"-"};
QPushButton buttonMaximize{"M"};
QPushButton buttonClose{"X"};
QPoint pressPos;
bool isMoving{false};
};
//sample usage
class Widget : public QWidget{
public:
explicit Widget(QWidget* parent= nullptr):QWidget(parent){
setWindowFlags(Qt::CustomizeWindowHint);
layout.addWidget(&titleBar);
layout.addWidget(&label);
layout.setContentsMargins(0, 0, 0, 0);
label.setAlignment(Qt::AlignCenter);
//default size for the window
resize(320,240);
}
~Widget(){}
private:
QVBoxLayout layout{this};
FakeTitleBar titleBar;
QLabel label{"this is a sample window"};
};
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}
#include "main.moc"