KGC*_*beX 4 qt qwidget qdialog
我需要创建一个带有圆角半透明角的QDialog 。问题是这样做时,角是半透明的,但以某种方式被窗口的 alpha 属性填充,使其变黑(这是我对问题原因的理解)
清晰可见的是圆形边缘,但有某种黑色的“背景”。QThread确认一下,此对话框是由from启动的模式对话框QMainWindow。它不是父窗口。
QDialog(根)组件的 CSS是:
QDialog {
background-color: rgba(250, 250, 250, 255);
border-radius: 30px;
color: #3C3C3C;
}
Run Code Online (Sandbox Code Playgroud)
组件布局如下所示
我也添加了阴影效果QDialog。这是构造函数代码QDialog:
UpdateDialog::UpdateDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::UpdateDialog)
{
ui->setupUi(this);
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect();
effect->setBlurRadius(5);
this->setGraphicsEffect(effect);
}
Run Code Online (Sandbox Code Playgroud)
值得注意的是,父级QMainWindow在其构造函数中设置了以下属性
ui->setupUi(this);
statusBar()->hide();
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground, true);
// Set rounded corners style
setStyleSheet("QMainWindow {\n background-color:rgba(240,240,240,255);\n border-radius: 30px;\n}\n\nQDialog {\n border-radius: 30px;\n}");
// Add shadow to main window
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect(ui->mainWindow);
effect->setBlurRadius(5);
effect->setOffset(4, 4);
this->setGraphicsEffect(effect);
Run Code Online (Sandbox Code Playgroud)
我如何使其QDialog具有圆角半透明的角?
更新:这是一个更好的版本。除其他事项外,像素化的角落也困扰着我。它看起来像丝绸一样光滑,可以使用 CSS 或 C++ 进行设计。它确实需要对要进行QWidget舍入的子类化(与第一个版本不同),但这是值得的。为了简单起见,我再次使用 aQMessageBox作为基本小部件(无布局/等),但它可以与任何小部件一起使用QWidget(可能需要Qt::Dialog添加窗口标志)。
消息框实现:
\n#include <QtWidgets>\n\nclass RoundedMessageBox : public QMessageBox\n{\n Q_OBJECT\n public:\n explicit RoundedMessageBox(QWidget *parent = nullptr) :\n QMessageBox(parent)\n {\n // The FramelessWindowHint flag and WA_TranslucentBackground attribute are vital.\n setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);\n setAttribute(Qt::WA_TranslucentBackground);\n }\n\n qreal radius = 0.0; // desired radius in absolute pixels\n qreal borderWidth = -1.0; // -1 : use style hint frame width; 0 : no border; > 0 : use this width.\n\n protected:\n void paintEvent(QPaintEvent *ev) override\n {\n // If the transparency flag/hint aren\'t set then just use the default paint event.\n if (!(windowFlags() & Qt::FramelessWindowHint) && !testAttribute(Qt::WA_TranslucentBackground)) {\n QMessageBox::paintEvent(ev);\n return;\n }\n\n // Initialize the painter.\n QPainter p(this);\n p.setRenderHint(QPainter::Antialiasing);\n\n // Have style sheet?\n if (testAttribute(Qt::WA_StyleSheetTarget)) {\n // Let QStylesheetStyle have its way with us.\n QStyleOption opt;\n opt.initFrom(this);\n style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);\n p.end();\n return;\n }\n\n // Paint thyself.\n QRectF rect(QPointF(0, 0), size());\n // Check for a border size.\n qreal penWidth = borderWidth;\n if (penWidth < 0.0) {\n // Look up the default border (frame) width for the current style.\n QStyleOption opt;\n opt.initFrom(this);\n penWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, this);\n }\n // Got pen?\n if (penWidth > 0.0) {\n p.setPen(QPen(palette().brush(foregroundRole()), penWidth));\n // Ensure border fits inside the available space.\n const qreal dlta = penWidth * 0.5;\n rect.adjust(dlta, dlta, -dlta, -dlta);\n }\n else {\n // QPainter comes with a default 1px pen when initialized on a QWidget.\n p.setPen(Qt::NoPen);\n }\n // Set the brush from palette role.\n p.setBrush(palette().brush(backgroundRole()));\n // Got radius? Otherwise draw a quicker rect.\n if (radius > 0.0)\n p.drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize);\n else\n p.drawRect(rect);\n\n // C\'est fin\xc3\xad\n p.end();\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n显示 CSS 和 C++ 样式选项的示例用法:
\nint main(int argc, char *argv[])\n{\n //QApplication::setStyle("Fusion");\n QApplication app(argc, argv);\n\n // Dialog setup\n RoundedMessageBox *msgBox = new RoundedMessageBox();\n msgBox->setAttribute(Qt::WA_DeleteOnClose);\n msgBox->setMinimumSize(300, 300);\n msgBox->setWindowTitle("Frameless window test");\n\n msgBox->setText("<h3>Frameless rounded message box.</h3>");\n msgBox->setInformativeText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean fermentum erat rhoncus, "\n "scelerisque eros ac, hendrerit metus. Nunc ac lorem id tortor porttitor mollis. Nunc "\n "tristique orci vel risus convallis, non hendrerit sapien condimentum. Phasellus lorem tortor, "\n "mollis luctus efficitur id, consequat eget nulla. Nam ac magna quis elit tristique hendrerit id "\n "at erat. Integer id tortor elementum, dictum urna sed, tincidunt metus. Proin ultrices tempus "\n "lacinia. Integer sit amet fringilla nunc.");\n\n if (1) {\n // Use QSS style\n app.setStyleSheet(QStringLiteral(\n "QDialog { "\n "border-radius: 12px; "\n "border: 3.5px solid; "\n "border-color: qlineargradient(x1: 1, y1: 1, x2: 0, y2: 0, stop: 0 #ffeb7f, stop: 1 #d09d1e); "\n "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #ffeb7f, stop: 1 #d09d1e); "\n "color: #003200; "\n "}"\n ));\n }\n else {\n // Use "native" styling\n msgBox->radius = 12.0;\n msgBox->borderWidth = 3.5;\n\n QLinearGradient bgGrad(0, 0, 1, 1);\n bgGrad.setCoordinateMode(QGradient::ObjectMode);\n bgGrad.setColorAt(0.0, QColor("gold").lighter());\n bgGrad.setColorAt(1.0, QColor("goldenrod").darker(105));\n QLinearGradient fgGrad(bgGrad);\n fgGrad.setStart(bgGrad.finalStop());\n fgGrad.setFinalStop(bgGrad.start());\n\n QPalette pal;\n pal.setBrush(QPalette::Window, QBrush(bgGrad));\n pal.setBrush(QPalette::Mid, QBrush(fgGrad));\n pal.setBrush(QPalette::WindowText, QColor("darkgreen").darker());\n msgBox->setPalette(pal);\n\n msgBox->setForegroundRole(QPalette::Mid); // default is WindowText\n msgBox->setBackgroundRole(QPalette::Window); // this is actually the default already\n }\n\n // Drop shadow doesn\'t work.\n // QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect();\n // effect->setBlurRadius(2);\n // msgBox->setGraphicsEffect(effect);\n\n msgBox->show();\n return app.exec();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n原始:使用通用 QMessageBox 并在其上设置掩码。
\n事实证明,我可以在新应用程序中使用一个简单的无框架对话框作为“关于”消息框……所以就这样吧。这是我能想到的最简单的方法,无需完全重新实现小部件绘制过程(如 Qt 时钟示例)。但这种实现方式显然有局限性,而且我还没有在 Mac 上尝试过。
\n另外,阴影也非常方便......虽然你实际上看不到它,但它在平滑角落方面做得很好。好主意,即使这不是初衷。:)
\n#include <QtWidgets>\n\nint main(int argc, char *argv[])\n{\n QApplication app(argc, argv);\n\n // Dialog setup. Actually use a QMessageBox for a shorter example.\n QMessageBox *msgBox = new QMessageBox();\n msgBox->setAttribute(Qt::WA_DeleteOnClose);\n msgBox->setMinimumSize(300, 300);\n msgBox->setWindowTitle("Frameless window test"); // might still be visible eg. in a taskbar\n msgBox->setText("<h3>Frameless rounded message box.</h3>");\n msgBox->setInformativeText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean fermentum erat rhoncus, "\n "scelerisque eros ac, hendrerit metus. Nunc ac lorem id tortor porttitor mollis. Nunc "\n "tristique orci vel risus convallis, non hendrerit sapien condimentum. Phasellus lorem tortor, "\n "mollis luctus efficitur id, consequat eget nulla. Nam ac magna quis elit tristique hendrerit id "\n "at erat. Integer id tortor elementum, dictum urna sed, tincidunt metus. Proin ultrices tempus "\n "lacinia. Integer sit amet fringilla nunc.");\n\n // Here come the styling bits... First need the frameless window flag hint\n msgBox->setWindowFlags(msgBox->windowFlags() | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);\n // The desired border radius;\n const int radius = 12;\n // Style the box with CSS. Set the border radius here. \n // The border style helps blend the corners, but could be omitted.\n // The background is optional... could add other styling here too.\n msgBox->setStyleSheet(QString(\n "QDialog { "\n "border-radius: %1px; "\n "border: 2px solid palette(shadow); "\n "background-color: palette(base); "\n "}"\n ).arg(radius));\n\n // The effect will not be actually visible outside the rounded window,\n // but it does help get rid of the pixelated rounded corners.\n QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect();\n // The color should match the border color set in CSS.\n effect->setColor(QApplication::palette().color(QPalette::Shadow));\n effect->setBlurRadius(5);\n msgBox->setGraphicsEffect(effect);\n\n // Need to show the box before we can get its proper dimensions.\n msgBox->show();\n\n // Here we draw the mask to cover the "cut off" corners, otherwise they show through.\n // The mask is sized based on the current window geometry. If the window were resizable (somehow)\n // then the mask would need to be set in resizeEvent().\n const QRect rect(QPoint(0,0), msgBox->geometry().size());\n QBitmap b(rect.size());\n b.fill(QColor(Qt::color0));\n QPainter painter(&b);\n painter.setRenderHint(QPainter::Antialiasing);\n painter.setBrush(Qt::color1);\n // this radius should match the CSS radius\n painter.drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize);\n painter.end();\n msgBox->setMask(b);\n\n return app.exec();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
6385 次 |
| 最近记录: |