- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Windows 平台上工作。如果我使用原生无框窗口标志,例如:
::SetWindowLongPtr((HWND)winId(), GWL_STYLE, WS_POPUP | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
我收到的无框窗口可以与默认 Windows 窗口编辑器一起正常工作 - 当我按下“WIN”键 + 箭头时它可以正确更改状态。
当我尝试使用具有以下无框窗口标志的 Qt 库时:
setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::CustomizeWindowHint);
我收到的窗口对“WIN”键 + 箭头没有反应。所以它不适用于默认的 Windows 窗口编辑器。
Qt 窗口标志的哪些组合具有与上述 native 标志类似的行为?
最佳答案
看来,这确实与 Qt 关系不大。在 Windows 窗口上只有一个完整的框架似乎禁用了“捕捉”快捷方式,即使窗口仍然可以调整大小或使用键盘箭头移动(从 Alt+Space 系统菜单)。
解决方法实际上非常简单。基本上是实现 QWidget::nativeEvent()
虚方法并忽略 WM_NCCALCSIZE
消息。
我在从一个屏幕捕捉到另一个屏幕时遇到了一些绘画问题,但使用 mask 解决了这个问题(代码注释中的注释)。很高兴找到一个更干净的解决方案(实际上它可能符合 Qt 错误)。
作为奖励,这还允许圆角。绘画/样式基于我为 another answer 制作的圆形消息框,绘画代码在那边有更完整的记录。
系统菜单和所有与键的交互(移动/调整大小/捕捉/等)工作。可以通过在 nativeEvent()
中实现 WM_NCHITTEST
消息来添加鼠标处理(请参阅下面的引用资料)。
只在 Win7 上测试过,想知道它在 Win10 上的表现如何。
FramelessWidget
#include <QPainter>
#include <QPalette>
#include <QStyle>
#include <QStyleOption>
#include <QWidget>
#include <qt_windows.h>
class FramelessWidget : public QWidget
{
Q_OBJECT
public:
explicit FramelessWidget(QWidget *p = nullptr, Qt::WindowFlags f = Qt::Window) :
// the flags set here should "match" the GWL_STYLE flags set below
QWidget(p, f | Qt::WindowMinMaxButtonsHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint)
{
setAttribute(Qt::WA_TranslucentBackground); // for rounded corners
// set flags which will override what Qt does, especially with the Qt::FramelessWindowHint which essentially disables WS_SIZEBOX/WS_THICKFRAME
SetWindowLongPtr(HWND(winId()), GWL_STYLE, WS_POPUPWINDOW | WS_CAPTION | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CLIPCHILDREN);
}
// these settings are only used when no styleSheet is set
qreal radius = 0.0; // desired radius in absolute pixels
qreal borderWidth = -1.0; // -1: use style hint frame width; 0: no border; > 0: use this width.
protected:
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override
{
MSG *msg = static_cast<MSG*>(message);
if (msg && msg->message == WM_NCCALCSIZE) {
// Just return 0 and mark event as handled. This will draw the widget contents
// into the full size of the frame, instead of leaving room for it.
*result = 0;
return true;
}
return QWidget::nativeEvent(eventType, message, result);
}
// Override paint event because of transparent background.
// Can be styled using CSS or QPalette with backgroundRole()/foregroundRole().
void paintEvent(QPaintEvent *) override
{
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing);
QStyleOption opt;
opt.initFrom(this);
// be sure to use the full frame size, not the default rect() which is inside frame.
opt.rect.setSize(frameSize());
if (testAttribute(Qt::WA_StyleSheetTarget)) {
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
setMask(QRegion(opt.rect)); // see notes below
return;
}
QRectF rect(opt.rect);
qreal penWidth = borderWidth;
if (penWidth < 0.0)
penWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, this);
if (penWidth > 0.0) {
p.setPen(QPen(palette().brush(foregroundRole()), penWidth));
const qreal dlta = (penWidth * 0.5);
rect.adjust(dlta, dlta, -dlta, -dlta);
}
else {
p.setPen(Qt::NoPen);
}
p.setBrush(palette().brush(backgroundRole()));
if (radius > 0.0)
p.drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize);
else
p.drawRect(rect);
// Setting a mask works around an issue with artifacts when switching screens with Win+arrow
// keys. I don't think it's the actual mask which does it, rather it triggers the region
// around the widget to be polished but I'm not sure. As support for my theory, the mask
// doesn't even have to follow the border radius.
setMask(QRegion(opt.rect));
}
}; // FramelessWidget
测试实现
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//QLoggingCategory::setFilterRules(QStringLiteral("qt.qpa.windows = true\n"));
FramelessWidget msgBox;
msgBox.setWindowTitle("Frameless window test");
msgBox.setLayout(new QVBoxLayout);
msgBox.layout()->addWidget(new QLabel(QStringLiteral("<h3>Frameless rounded widget.</h3>"), &msgBox));
QLabel *lbl = new QLabel(QStringLiteral(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean fermentum erat rhoncus, "
"scelerisque eros ac, hendrerit metus. Nunc ac lorem id tortor porttitor mollis. Nunc "
"tristique orci vel risus convallis, non hendrerit sapien condimentum. Phasellus lorem tortor, "
"mollis luctus efficitur id, consequat eget nulla. Nam ac magna quis elit tristique hendrerit id "
"at erat. Integer id tortor elementum, dictum urna sed, tincidunt metus. Proin ultrices tempus "
"lacinia. Integer sit amet fringilla nunc."
), &msgBox);
lbl->setWordWrap(true);
msgBox.layout()->addWidget(lbl);
QPushButton *pb = new QPushButton(QStringLiteral("Close"), &msgBox);
QObject::connect(pb, &QPushButton::clicked, qApp, &QApplication::quit);
msgBox.layout()->addItem(new QSpacerItem(1,1, QSizePolicy::Expanding, QSizePolicy::Expanding));
msgBox.layout()->addWidget(pb);
msgBox.setStyleSheet(QStringLiteral(
"FramelessWidget { "
"border-radius: 12px; "
"border: 3px solid palette(shadow); "
"background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #ffeb7f, stop: 1 #d09d1e); "
"}"
));
msgBox.show();
return a.exec();
}
引用资料:
WM_NCHITTEST
实现)WM_NCHITTEST
版本)qwindowsintegration
、qwindowswindow
、qwindowscontext
)关于c++ - 如何在Windows composer中集成Qt无框窗口? (系统快捷方式不起作用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59017362/
我有这个代码: System.err.print("number of terms = "); System.out.println(allTerms.size()); System.err
我有以下问题:在操作系统是 Linux 的情况下和在操作系统是 MacOs 的情况下,我必须执行不同的操作。 所以我创建了以下 Ant 脚本目标: /u
我正在调用 system("bash ../tools/bashScript\"This is an argument!\"&"),然后我正在调用 close(socketFD) 直接在 system
使用最初生成的随机元素来约束随机数组的连续元素是否有效。 例如:我想生成一组 10 个 addr、size 对来模拟典型的内存分配例程并具有如下类: class abc; rand bit[5:0
我正在创建一个必须使用system(const char*)函数来完成一些“繁重工作”的应用程序,并且我需要能够为用户提供粗略的进度百分比。例如,如果操作系统正在为您移动文件,它会为您提供一个进度条,
我即将编写一些项目经理、开发人员和业务分析师会使用的标准/指南和模板。目标是更好地理解正在开发或已经开发的解决方案。 其中一部分是提供有关记录解决方案的标准/指南。例如。记录解决/满足业务案例/用户需
在开发使用压缩磁盘索引或磁盘文件的应用程序时,其中部分索引或文件被重复访问(为了论证,让我们说一些类似于 Zipfian 分布的东西),我想知道什么时候足够/更好地依赖操作系统级缓存(例如,Debia
我们编写了一个 powershell 脚本,用于处理来自内部系统的图像并将其发送到另一个系统。现在,业务的另一部分希望加入其中,对数据进行自己的处理,并将其推送到另一个系统。打听了一下,公司周围有几个
我正在尝试朗姆酒我的应用程序,但我收到以下错误:System.Web.HttpUnhandledException:引发了“System.Web.HttpUnhandledException”类型的异
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
所以我在其他程序中没有收到此错误,但我在这个程序中收到了它。 这个程序是一个我没有收到错误的示例。 #include int main() { system("pause"); } // en
我在 c# System.URI.FormatExption 中遇到问题 为了清楚起见,我使用的是 Segseuil 的 Matlab 方法,并且它返回一个图片路径 result。我想为其他用户保存此
我正在尝试像这样设置文本框的背景色: txtCompanyName.BackColor = Drawing.Color.WhiteSmoke; 它不喜欢它,因为它要我在前面添加系统,例如: txtCo
请帮助我解决 System.StackOverflowException我想用 .aspx 将记录写入数据库我使用 4 层架构来实现这一切都正常但是当我编译页面然后它显示要插入数据的字段时,当我将数据
我使用了一些通常由系统调用的API。 因此,我将 android:sharedUserId="android.uid.system" 添加到 manifest.xml, 并使用来自 GIT 的 And
我正在尝试创建一个小型应用程序,它需要对/system 文件夹进行读/写访问(它正在尝试删除一个文件,并创建一个新文件来代替它)。我可以使用 adb 毫无问题地重新挂载该文件夹,如果我这样做,我的应用
我想从没有 su 的系统 priv-app 将/system 重新挂载为 RW。如何以编程方式执行此操作?只会用 Runtime.getruntime().exec() 执行一个 shell 命令吗
我正在尝试制作一个带有登录系统的程序我对此很陌生,但我已经连续工作 8 个小时试图解决这个问题。这是我得到的错误代码 + ServerVersion 'con.ServerVersion' threw
当我“构建并运行”Code::Blocks 中的程序时,它运行得非常好!但是当我从“/bin”文件夹手动运行它时,当它试图用 system() 调用“temp.bat”时,它会重置。这是为什么?它没有
我想使用 system/pipe 命令来执行具有特殊字符的命令。下面是示例代码。通过系统/管道执行命令后,它通过改变特殊字符来改变命令。我很惊讶地看到系统命令正在更改作为命令传递的文本。 run(ch
我是一名优秀的程序员,十分优秀!