因为要写一个跨平台内网传输工具DKD,为了最大程度的代码复用,所以考虑使用QT,对QT不熟悉,10天的摸索,终于画出简易的仿QQ界面,开发环境为:qt creator+gcc,效果如下:
主窗口的区域切割为三部分:
主窗口类派生于QFrame
关键代码如下:
//without system titlebar
setWindowFlags(Qt::FramelessWindowHint);
setWindowFlags(Qt::WindowStaysOnTopHint);
//place window
QRect deskRect = QApplication::desktop()->availableGeometry();
this->move(deskRect.right()-280,30);
//new subclass widgets
m_titlebar = new TitleBar(this);
m_centerWgt = new CenterWidget(this);
m_bottomWgt = new BottomWidget(this);
m_skinmgr = new SkinMgr(this);
m_hostinfwnd = new HostInfWnd(this);
//layout
QVBoxLayout * pMainLayout = new QVBoxLayout(this);
pMainLayout->addWidget(m_titlebar,0,Qt::AlignTop);
pMainLayout->addWidget(m_centerWgt);
pMainLayout->addWidget(m_bottomWgt,0,Qt::AlignBottom);
pMainLayout->setSpacing(0);
pMainLayout->setContentsMargins(0,0,0,0);
setLayout(pMainLayout);
//qss
OnSkinChange(m_strMainSkin);
//signal handler
connect(m_titlebar,SIGNAL(evtClose()),this,SLOT(CloseEvtHandler()));
connect(m_titlebar,SIGNAL(evtMinWnd()),this,SLOT(showMinimized()));
connect(m_titlebar,SIGNAL(evtSkinMgr()),this,SLOT(SkinMgrHandler()));
connect(m_skinmgr,SIGNAL(SigSkinChange(const QString &)),this,SLOT(OnSkinChange(const QString&)));
connect(m_titlebar,SIGNAL(evtShowHostInf()),this,SLOT(OnShowHostInf()));
先不管细节,来看看标题栏的实现。
网上资料很多,qss可以轻松实现界面需要,窗口拖动,换肤方面网上都有代码,不多说,至于图片资源,我是用MultiExtractor从腾讯的PE文件里提取的,非商业用途,用下也没问题。
再说,底栏,底栏同标题栏一样简单,QQ的半透明效果是用一张比较透明的Png图片打底mask出来的,我也随便找了一张,实现了类似效果,也是QSS实现。但是在windows下会出现焦点按钮被虚线框住的情况,暂时我没管他。
主区域中的搜索框是一个子类化的QLineEeEdit实现的,我还没搞好他。
"tab"是用PUSHBUTTON实现的,有图片就简单,不多说。
剩下的列表控件原生QLISTWIDGET,通过方法setItemWidget实现,虽然方法笨,但是满足了需求。需要注意的细节有:item的Hover,pressed的背景设置,item的高度设置,和滚动条,滚动条我没深究,只是简单的设置了背景色,效果差强人意:
关于QLISTWDIGET的QSS如下
{
QString myss = QString(
"QListWidget::item:selected {background-color:rgb(252,235,171);}"
"QListWidget::item:hover:!selected {background-color:rgb(252,240,193);}"
"QListWidget::scrollbar {background-color:rgb(252,235,171);}"
);
m_richlist->setStyleSheet(myss);
m_richlist->verticalScrollBar()->setStyleSheet(
"QScrollBar:vertical {border: 2px solid grey;background:rgb(109,111,111)}"
);
m_richlist->setMouseTracking(true);
m_richlist->setAutoScroll(true);
for(int i=0;i<100;++i){
UsersListItem * myitem = new UsersListItem(m_richlist);
QListWidgetItem * Item = new QListWidgetItem();
m_richlist->addItem(Item);
Item->setSizeHint(myitem->sizeHint());
m_richlist->setItemWidget(Item,myitem);
}
}
UserListItem定义:
class UsersListItem : public QWidget
{
Q_OBJECT
public:
explicit UsersListItem(QWidget *parent = 0);
virtual QSize sizeHint() const
{
return QSize(100,48);
}
private:
QLabel * m_labAddress;
QLabel * m_labHeaderPic;
QLabel * m_labUser;
signals:
public slots:
};
QT新手,不多说话。下一步写功能实现的历程。