标签(空格分隔): Qt frameless 无边框
Qt的一大优势就是QSS样式表,不过在用的时候界面还是有些不太舒服的地方,比如丑陋的标题栏。这里记录下改造Qt界面的步骤。
Qt5.7.0 Dialog空白工程
既然标题栏很丑,那么就直接去掉算了。
setWindowFlags( Qt::FramelessWindowHint );
无边框之后会造成新问题–界面拖动不了,而且本来可以缩放的界面也不能拖动缩放了。解决方法很多,对我等小白来说最简单的是用第三方类NcFramelessHelper
,3句代码就可以完美解决问题。下载链接最后附上。
#include "NcFramelessHelper.h"
//.....
Dialog w;//
w.setWindowFlags( Qt::FramelessWindowHint );
NcFramelessHelper* fh = new NcFramelessHelper;
fh->activateOn(&w);
效果是这样的
取消了默认的标题栏不代表不需要标题栏,为了实现较为时髦的标题栏,可以从QWidgets派生一个,再添加到界面上去。
这里继续用第三方类State_Button
State_Button* minBtn = new State_Button(this);
minBtn->set_pixmap(QPixmap(":/min.png"));
State_Button* maxBtn = new State_Button(this);
maxBtn->set_pixmap(QPixmap(":/max.png"));
State_Button* clostBtn = new State_Button(this);
clostBtn->set_pixmap(QPixmap(":/close.png"));
QHBoxLayout* btnGroupLayout = new QHBoxLayout;
QHBoxLayout* titleLayout = new QHBoxLayout;
btnGroupLayout->addWidget(minBtn, 0, Qt::AlignTop);
btnGroupLayout->addWidget(maxBtn, 0, Qt::AlignTop);
btnGroupLayout->addWidget(clostBtn, 0, Qt::AlignTop);
titleLayout->addLayout(btnGroupLayout);
setLayout(titleLayout);
效果是这样的
和普通标题栏有点像了,但位置还不对,另外还缺少左侧的icon、对话框标题,下面一个个加进去。
修改如下代码
QLabel*icon = new QLabel();
icon->setPixmap(QPixmap(":/icon.png"));
icon->setFixedSize(16, 16);
icon->setScaledContents(true);
QLabel*title = new QLabel("这是标题栏文字");
State_Button* minBtn = new State_Button(this);
minBtn->set_pixmap(QPixmap(":/min.png"));
State_Button* maxBtn = new State_Button(this);
maxBtn->set_pixmap(QPixmap(":/max.png"));
State_Button* clostBtn = new State_Button(this);
clostBtn->set_pixmap(QPixmap(":/close.png"));
QHBoxLayout* titleLayout = new QHBoxLayout;
titleLayout->addWidget(icon, 0, Qt::AlignTop);
titleLayout->addSpacing(5);
titleLayout->addWidget(title, 0, Qt::AlignTop);
titleLayout->addStretch();
titleLayout->addWidget(minBtn, 0, Qt::AlignTop);
titleLayout->addWidget(maxBtn, 0, Qt::AlignTop);
titleLayout->addWidget(clostBtn, 0, Qt::AlignTop);
setLayout(titleLayout);
运行效果是这样
到这里标题栏样式就差不多了,但没有按钮点击事件啊,继续添加代码,同时按照C++封装的思想,将标题栏封装成类。代码如下
//无边框界面标题栏类
class Title_Bar: public QWidget
{
Q_OBJECT
public:
Title_Bar(QWidget *parent = NULL);
~Title_Bar();
QString get_text(){return title->text();}
void set_text(const QString& text){title->setText(text);}
bool is_window_maximized() const {return is_maxed;}
protected:
void init();
private slots:
void show_small();
void show_max_restore();
void close_window();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
private:
QHBoxLayout* titleLayout;
QLabel* icon;
QLabel* title;
State_Button* menu_button;
State_Button* min_button;
State_Button* max_button;
State_Button* close_button;
QRect normal_rect;
QPoint click_pos; //
bool left_pressed; //left mouse pressed
bool is_maxed; //window Maximized
};
Title_Bar::Title_Bar( QWidget* parent )
:QWidget(parent)
,left_pressed(false)
,is_maxed(false)
{
titleLayout = new QHBoxLayout(this);
icon = new QLabel(this);
title = new QLabel(this);
menu_button = new State_Button(this);
min_button = new State_Button(this);
max_button = new State_Button(this);
close_button = new State_Button(this);
//设置name以方便使用 CSS
icon->setObjectName("title_bar_icon");
title->setObjectName("title_bar_text");
menu_button->setObjectName("title_bar_menu");
min_button->setObjectName("title_bar_min");
max_button->setObjectName("title_bar_max");
close_button->setObjectName("title_bar_close");
init();
}
Title_Bar::~Title_Bar()
{
}
void Title_Bar::init()
{
//标题栏
title->setText("这是标题栏");
// 标题栏高度
int titlebar_height = style()->pixelMetric(QStyle::PM_TitleBarHeight);
setFixedHeight(titlebar_height);
const int frame_width = 5;
//layout
titleLayout->addWidget(icon, 0, Qt::AlignVCenter);
titleLayout->addSpacing(frame_width);
titleLayout->addWidget(title, 0, Qt::AlignVCenter);
titleLayout->addStretch();
titleLayout->addWidget(menu_button, 0, Qt::AlignTop);
titleLayout->addWidget(min_button, 0, Qt::AlignTop);
titleLayout->addWidget(max_button, 0, Qt::AlignTop);
titleLayout->addWidget(close_button, 0, Qt::AlignTop);
titleLayout->setSpacing(1);
titleLayout->setMargin(1);
//icon
icon->setPixmap(QPixmap(":/icon.png"));
icon->setFixedSize(16, 16);
icon->setScaledContents(true);
//windows taskbar icon
window()->setWindowIcon(QPixmap(":/icon.png"));
//
menu_button->set_pixmap(QPixmap(":/menu.png"));
min_button->set_pixmap(QPixmap(":/min.png"));
max_button->set_pixmap(QPixmap(":/max.png"));
close_button->set_pixmap(QPixmap(":/close.png"));
//
setLayout(titleLayout);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
//
connect(min_button, SIGNAL(clicked()), this, SLOT(show_small()));
connect(max_button, SIGNAL(clicked()), this, SLOT(show_max_restore()));
connect(close_button, SIGNAL(clicked()), this, SLOT(close_window()));
}
void Title_Bar::show_max_restore()
{
if (is_maxed)
{
is_maxed = false;
window()->setGeometry(normal_rect);
max_button->set_pixmap(QPixmap(":/max.png"));
} else {
is_maxed = true;
normal_rect = window()->geometry();
window()->setGeometry(QApplication::desktop()->availableGeometry());
max_button->set_pixmap(QPixmap(":/restore.png"));
}
}
void Title_Bar::mousePressEvent( QMouseEvent *e )
{
QRect r = rect();
r.adjust(5, 5, -5, -5);
if (r.contains(e->pos())) //5:边框大小,边框用来拉伸改变窗口大小
{
if (e->button() == Qt::LeftButton)
{
left_pressed = true;
click_pos = mapToParent(e->pos());
e->accept();
return;
}
}
e->ignore();
}
void Title_Bar::mouseMoveEvent( QMouseEvent *e )
{
if (left_pressed && !is_maxed)
{
window()->move(e->globalPos() - click_pos);
e->accept();
}else{
e->ignore();
}
}
void Title_Bar::mouseReleaseEvent( QMouseEvent *e )
{
left_pressed = false;
e->ignore();
}
void Title_Bar::show_small()
{
window()->showMinimized();
}
void Title_Bar::close_window()
{
window()->close();
}
void Title_Bar::mouseDoubleClickEvent( QMouseEvent *e )
{
show_max_restore();
left_pressed = false;
}
效果如图,最小化、最大化、关闭、菜单、双击标题栏最大化最小化都可以实现
下面继续美化,终于可以祭出Qt的大绝招–QSS
了。还是从网上找到的资源。添加到项目里去
QFile file(":/dark.qss");
file.open(QFile::ReadOnly | QFile::Text);
QTextStream stream(&file);
setStyleSheet(stream.readAll());
好了,初步的美化就有了。
加几个Qss
美化的控件吧。
QGridLayout* gridLayout = new QGridLayout;
gridLayout->setMargin(10);
QLabel* label = new QLabel("sdf");
label->setFont(QFont("微软雅黑",12));
gridLayout->addWidget(label,0,0);
QPushButton* btn = new QPushButton("sdf");
btn->setFont(QFont("微软雅黑",12));
gridLayout->addWidget(btn,0,1);
QCheckBox* check = new QCheckBox("615651651");
check->setFont(QFont("微软雅黑",12));
check->setChecked(true);
gridLayout->addWidget(check,0,2);
QComboBox* combo = new QComboBox;
combo->setFont(QFont("微软雅黑",12));
combo->addItem("sfsfsd");
combo->addItem("234234");
combo->addItem("78678");
gridLayout->addWidget(combo,0,3);
QLineEdit* line = new QLineEdit;
line->setFont(QFont("微软雅黑",12));
line->setText("LineText");
gridLayout->addWidget(line,0,4);
QListWidget *listWidget = new QListWidget(this);
listWidget->setFont(QFont("微软雅黑",12));
listWidget->insertItem(0,"列表1");
listWidget->insertItem(1,"列表2");
listWidget->insertItem(2,"列表3");
listWidget->insertItem(3,"列表4");
listWidget->insertItem(4,"列表5");
listWidget->setAlternatingRowColors(true);
gridLayout->addWidget(listWidget,1,0,2,2);
QGroupBox *groupBox = new QGroupBox(tr("按钮组"));
QRadioButton *radio1 = new QRadioButton(tr("&Radio button 1"));
QRadioButton *radio2 = new QRadioButton(tr("R&adio button 2"));
QRadioButton *radio3 = new QRadioButton(tr("Ra&dio button 3"));
radio1->setChecked(true);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(radio1);
vbox->addWidget(radio2);
vbox->addWidget(radio3);
vbox->addStretch(1);
groupBox->setLayout(vbox);
gridLayout->addWidget(groupBox,1,2,3,1);
QTableWidget *table = new QTableWidget(3,2);
table->setFont(QFont("微软雅黑",12));
table->setAlternatingRowColors(true);
table->setWindowTitle("VIP List");
QStringList headerList;
headerList << "No." << "姓名" ;
table->setHorizontalHeaderLabels(headerList);
//table->verticalHeader()->setVisible(false);
table->horizontalHeader()->setStretchLastSection(true);
table->setItem(0,0,new QTableWidgetItem("0"));
table->setItem(1,0,new QTableWidgetItem("1"));
table->setItem(2,0,new QTableWidgetItem("2"));
table->setItem(0,1,new QTableWidgetItem("小王"));
table->setItem(1,1,new QTableWidgetItem("小龙"));
table->setItem(2,1,new QTableWidgetItem("小李"));
gridLayout->addWidget(table,1,3,4,2);
layout->addLayout(gridLayout);
setLayout(layout);
效果是这样的
最后附上全部代码和资源
转载请注明出处