翻譯|使用教程|編輯:龔雪|2024-10-22 11:35:28.610|閱讀 172 次
概述:本文主要介紹如何在Qt應(yīng)用程序中實(shí)現(xiàn)一個(gè)半透明的背景,歡迎下載最新版組件體驗(yàn)~
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
Qt 是目前最先進(jìn)、最完整的跨平臺(tái)C++開發(fā)工具。它不僅完全實(shí)現(xiàn)了一次編寫,所有平臺(tái)無差別運(yùn)行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運(yùn)用于超過70個(gè)行業(yè)、數(shù)千家企業(yè),支持?jǐn)?shù)百萬設(shè)備及應(yīng)用。
本文將為大家展示如何制作一個(gè)帶有半透明背景的圓形窗口。
 
 
將背景設(shè)置為半透明的小部件將對(duì)所有未繪制的像素透明,并且背景將通過不透明度低于100%繪制的像素發(fā)光,沒有繪制的像素也不會(huì)接收任何鼠標(biāo)輸入,這可用于自定義頂級(jí)小部件的形狀。在大多數(shù)窗口系統(tǒng)中,設(shè)置某些窗口標(biāo)志將導(dǎo)致窗口裝飾(標(biāo)題欄、窗口框架、按鈕)被禁用,從而允許創(chuàng)建特殊形狀的窗口。在這個(gè)示例中,我們使用這個(gè)特性來創(chuàng)建一個(gè)包含模擬時(shí)鐘的圓形窗口。
由于這個(gè)示例的窗口沒有提供File菜單或關(guān)閉按鈕,因此我們提供了一個(gè)帶有Exit條目的上下文菜單,以便可以關(guān)閉該示例,單擊窗口上方的鼠標(biāo)右鍵來打開此菜單。
Qt技術(shù)交流群:166830288 歡迎一起進(jìn)群討論
ShapedClock類基于AnalogClock示例中定義的AnalogClock類,整個(gè)類定義如下:
class ShapedClock : public QWidget
{
Q_OBJECT
public:
ShapedClock(QWidget *parent = nullptr);
QSize sizeHint() const override;
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
QPoint dragPosition;
};
()現(xiàn)在半透明背景(時(shí)鐘面)上繪制模擬時(shí)鐘,此外我們實(shí)現(xiàn)了sizeHint(),這樣就不必顯示地調(diào)整小部件的大小。
由于包含時(shí)鐘小部件的窗口將沒有標(biāo)題欄,因此我們提供了()和()的實(shí)現(xiàn),來允許在屏幕上拖動(dòng)時(shí)鐘,dragPosition變量使我們能夠跟蹤用戶最后單擊小部件的位置。
ShapedClock構(gòu)造函數(shù)設(shè)置一個(gè)計(jì)時(shí)器,并將其連接到小部件的update()槽。此外,我們向小部件添加了一個(gè)操作,當(dāng)右鍵單擊小部件時(shí),該操作將通過上下文菜單自動(dòng)變?yōu)榭捎谩?
ShapedClock::ShapedClock(QWidget *parent)
: QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint)
{
setAttribute(Qt::WA_TranslucentBackground);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&ShapedClock::update));
timer->start(1000);
QAction *quitAction = new QAction(tr("E&xit"), this);
quitAction->setShortcut(tr("Ctrl+Q"));
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
addAction(quitAction);
setContextMenuPolicy(Qt::ActionsContextMenu);
setToolTip(tr("Drag the clock with the left mouse button.\n"
"Use the right mouse button to open a context menu."));
setWindowTitle(tr("Shaped Analog Clock"));
}
我們通過設(shè)置 小部件屬性來請(qǐng)求透明窗口,通過在窗口管理器上設(shè)置 標(biāo)志來通知窗口管理器該窗口不使用窗口框架來裝飾。因此,我們需要為用戶提供一種在屏幕上移動(dòng)時(shí)鐘的方法。
鼠標(biāo)按鈕事件被傳遞給mousePressEvent()處理程序:
void ShapedClock::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
event->accept();
}
}
如果在小部件上按下鼠標(biāo)左鍵,我們將以全局(屏幕)坐標(biāo)記錄小部件框架的左上角位置(即使隱藏時(shí))與鼠標(biāo)單擊發(fā)生點(diǎn)之間的位移。如果用戶按住左鍵移動(dòng)鼠標(biāo),將使用此位移。由于我們對(duì)事件進(jìn)行了操作,因此通過調(diào)用它的()函數(shù)來接受它。
 
 
如果鼠標(biāo)移動(dòng)到小部件上,則調(diào)用mouseMoveEvent()處理程序。
void ShapedClock::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
move(event->globalPosition().toPoint() - dragPosition);
event->accept();
}
}
如果在移動(dòng)鼠標(biāo)時(shí)按住左鍵,則小部件的左上角將移動(dòng)到通過從全局坐標(biāo)中的當(dāng)前光標(biāo)位置減去dragPosition給出的位置。如果我們拖動(dòng)小部件,也接受事件。
paintEvent()函數(shù)主要與模擬時(shí)鐘示例中描述的相同,另外我們使用QPainter::drawEllipse()來繪制一個(gè)圓形的鐘面,將畫筆的不透明度降低到90%,并使用調(diào)色板的默認(rèn)背景色。
void ShapedClock::paintEvent(QPaintEvent *)
{
static const QPoint hourHand[4] = {
QPoint(5, 14),
QPoint(-5, 14),
QPoint(-4, -71),
QPoint(4, -71)
};
static const QPoint minuteHand[4] = {
QPoint(4, 14),
QPoint(-4, 14),
QPoint(-3, -89),
QPoint(3, -89)
};
static const QPoint secondsHand[4] = {
QPoint(1, 14),
QPoint(-1, 14),
QPoint(-1, -89),
QPoint(1, -89)
};
const QColor hourColor(palette().color(QPalette::Text));
const QColor minuteColor(palette().color(QPalette::Text));
const QColor secondsColor(palette().color(QPalette::Accent));
int side = qMin(width(), height());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);
painter.setPen(Qt::NoPen);
painter.setBrush(palette().window());
painter.setOpacity(0.9);
painter.drawEllipse(QPoint(0, 0), 98, 98);
painter.setOpacity(1.0);
QTime time = QTime::currentTime();
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 4);
painter.restore();
for (int i = 0; i < 12; ++i) {
painter.drawRect(73, -3, 16, 6);
painter.rotate(30.0);
}
painter.setBrush(minuteColor);
painter.save();
painter.rotate(6.0 * time.minute());
painter.drawConvexPolygon(minuteHand, 4);
painter.restore();
painter.setBrush(secondsColor);
painter.save();
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondsHand, 4);
painter.drawEllipse(-3, -3, 6, 6);
painter.drawEllipse(-5, -68, 10, 10);
painter.restore();
painter.setPen(minuteColor);
for (int j = 0; j < 60; ++j) {
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
}
最后為小部件實(shí)現(xiàn)sizeHint(),以便在它第一次顯示時(shí)給出一個(gè)合理的默認(rèn)大小:
QSize ShapedClock::sizeHint() const
{
return QSize(200, 200);
}
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:慧都網(wǎng)