永远的GitHub地址: https://github.com/JianBiHua/go_360_safe
前面两节代码写的我郁闷,怎么感觉是在写QT,跟GO没多大关系呀…
还好这节终于用到了QT的一些东西,嘿嘿.
先上个效果图,掌掌眼,看这个界面是不跟360安全卫士更像了,呵呵。
上面我将它封装了两个类,一个是左边的8个功能ToolButton,另一个就是右侧的简笔画等同志们了.
还是上代码, 代码里面有详细注释的
封装的ToolButton,这里面有GO的知识点了.
- 看parent/widget首字母小写, 这个是私有变量的意思哈, 私有的作用域只能在ToolButton里面使用。
- 剩下的是共有的意思, 共有的则能通过toolButton指针使用。
- NewToolButton/NewToolButton2,大家发现木有,这两个函数名字就多了一个2,参数也不一样,为啥不写成一样的?多态呀!C++等高级语言里面都有,但是可惜了GO不支持,所以你会发现代码里很多以数字结尾的函数。
- ConnectClicked 这个函数,很特别,它传入一个函数,实际上是一个函数指针而已,后面的代码肯定会大量用到,不会的话百度下“传参函数”
type ToolButton struct {
// 父控件,用于显示ToolButton
parent *widgets.QWidget
// 显示文字
Text string
// 显示图片
Icon string
// 图片的宽高
Icon_width int
// 图片的高度
Icon_height int
// QToolButton控件
widget *widgets.QToolButton
// 一个用户标志位,区分是那个QToolButton被点击
UserObject int
}
// 默认的款到单元
const WIDTH_UNIT = 50
// 析构函数,创建一个ToolButton
func NewToolButton (parent *widgets.QWidget, text, icon string, width, height int) *ToolButton {
var tb = ToolButton{parent,text, icon, width, height, nil, -1}
tb.init()
return &tb
}
// 析构函数,创建一个ToolButton
func NewToolButton2 (parent *widgets.QWidget, text, icon string) *ToolButton {
var tb = ToolButton{parent,text, icon, WIDTH_UNIT, WIDTH_UNIT, nil, -1}
tb.init()
return &tb
}
// init
// 初始化变量函数
func (tb *ToolButton) init () {
tb.showWidget ()
}
// showWidget
// 显示ToolButton
func (tb *ToolButton) showWidget () {
tb.widget = widgets.NewQToolButton(tb.parent)
action := widgets.NewQAction(nil)
action.SetText(tb.Text)
action.SetIcon(gui.NewQIcon5(tb.Icon))
//
tb.widget.SetDefaultAction(action)
tb.widget.SetIconSize(core.NewQSize2(tb.Icon_width, tb.Icon_height))
tb.widget.SetToolButtonStyle(core.Qt__ToolButtonTextUnderIcon);
}
// Widget
// 返回QToolButton对象。
func (tb *ToolButton) Widget () *widgets.QToolButton {
return tb.widget;
}
// ConnectClicked
// 当点击时调用。
func (tb *ToolButton) ConnectClicked (fClicked func (tbutton *ToolButton)) {
tb.widget.ConnectClicked(func(checked bool) {
// 被点击时返回
fClicked (tb)
})
}
// SetUserObject
// 设置一个用户变量
func (tb *ToolButton) SetUserObject (flag int) {
tb.UserObject = flag
}
// SetChecked
// 设置是否被选中,选中则为高亮状态。
//
// 解释一下:
// 本来是不需要这样去修改stylesheet的。
// 直接在qss里面加入: (意思是:page_selected属性为真是,使用该样式,否则使用默认样式 )
// *[page_selected="true"] { /* italicize selected tabs */
// background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
// stop:0 rgba(0, 0, 0, 0),
// stop:1 rgba(0, 0, 0, 32));
// }
// 而代码中只需要:
// tb.widget.SetProperty("page_selected", core.NewQVariant11(true))
// 或者:
// tb.widget.SetProperty("page_selected", core.NewQVariant11(true))
// 但是似乎无法运行,不知道哪里不对。呵呵,只能先这样了.
func (tb *ToolButton) SetChecked (checked bool) {
tb.widget.SetProperty("page_selected", core.NewQVariant11(true))
if !checked {
// 这个是默认背景色,
tb.widget.SetStyleSheet(`border: 0px;
border-radius: 0px;
background-color: #00000000;
color:rgb(255, 255, 255);
padding-top: 5px;
padding-bottom: 20px;`)
} else {
// 这个是一个渐变色的背景,点击时的效果。
// 具体怎么用,自行百度吧
// 解释下:
// x1:0, y1:0, x2:0, y2:1 代表纵向绘图
// stop:0 rgba(0, 0, 0, 0) 从透明色
// stop:1 rgba(0, 0, 0, 32) 到0.32半透明色
tb.widget.SetStyleSheet(`background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 rgba(0, 0, 0, 0),
stop:1 rgba(0, 0, 0, 32));`)
}
}
简笔画兄弟们的封装类如下
这个封装类,里面就简单很多了,就加了三个控件而已,还有大量注释。
到之后会在这个封装类中扩充新功能。
type WidgetLog struct {
// 父类控件
parent *widgets.QWidget
// 显示的控件
widget *widgets.QWidget
}
// NewWidgetLog
// 一样的自定义析构函数
func NewWidgetLog (p *widgets.QWidget) *WidgetLog {
wl := WidgetLog {p, nil}
wl.init ()
return &wl
}
// init
// 一样的初始化函数。
func (wl *WidgetLog) init () {
wl.showWidgets ()
}
// showWidgets
// 显示控件
// 为啥我要把这块定义成一个Widget,而不是一个一个创建并显示呢,
// 因为我要给他添加鼠标事件,用于弹出登陆对话框
func (wl *WidgetLog) showWidgets () {
//
wl.widget = widgets.NewQWidget(wl.parent, core.Qt__Widget)
// 添加偶的章子
nameLabel := widgets.NewQLabel2("简笔画", wl.widget,core.Qt__Widget)
// 第三个参数是加粗用的,第四个斜体.
nameLabel.SetFont(gui.NewQFont2("宋体", 30, 100, false))
nameLabel.SetGeometry2(10, 0, 100, 30)
nameLabel.SetObjectName("WidgetLog_Label")
nameLabel.SetAlignment(core.Qt__AlignHCenter)
// 添加登陆360账号
loginLabel := widgets.NewQLabel2("登陆360账号", wl.widget,core.Qt__Widget)
// 第三个参数是加粗用的,第四个斜体.
loginLabel.SetFont(gui.NewQFont2("微软雅黑", 12, 100, false))
loginLabel.SetGeometry2(10, 30, 100, 30)
loginLabel.SetObjectName("WidgetLog_Label")
// 水平居中
loginLabel.SetAlignment(core.Qt__AlignHCenter)
// 添加360图标
iconWidget := widgets.NewQWidget(wl.widget, core.Qt__Widget)
iconWidget.SetGeometry2(110, 0, 60, 60)
iconWidget.SetStyleSheet("border-image: url(resources/icon_w.png)")
}
//
func (wl *WidgetLog) Widget () *widgets.QWidget {
return wl.widget
}
两个封装类有了,怎么搞成图片中的样子呢,接着往上节代码中加东西喽。
注释很详细.
讲解下下面的Go语言的知识点
- var toolButtons [8]*ToolButton 这是一个数组,一个能存储8个ToolButton指针的数组
- toolButtons_icon_name/toolButtons_name同样是数组,string数组,这两个是根据{}中的像的个数创建出来的数组,当然这两个在这里也是长度为8
- ToolButtonType_HOME 这些东西是什么呢,相当于C里面的枚举,通过iota这个去定义的,这个东西起始为0,到了ToolButtonType_HORSE自加变成了1,依次类推;可以百度下itoa, 这个用法还有别的.
- 这样就显示到界面上了,如果只是这样是没有下面的白色部分的,界面肯定还是绿色滴
// 用一用GO的数组喽
var toolButtons [8]*ToolButton
// 图片名称
var toolButtons_icon_name = [...]string{
"resources/tab/tab_home.png",
"resources/tab/tab_horse.png",
"resources/tab/tab_clear.png",
"resources/tab/tab_fix.png",
"resources/tab/tab_optimize.png",
"resources/tab/tab_actions.png",
"resources/tab/tab_market.png",
"resources/tab/tab_app.png"}
// 名称
var toolButtons_name = [...]string{
"电脑体验",
"木马查杀",
"电脑清理",
"系统修复",
"优化加速",
"功能大全",
"电360商城",
"软件管家"}
// 在用用GO的枚举吧,哈哈
const (
// 电脑体验
ToolButtonType_HOME = iota
// 木马扫描
ToolButtonType_HORSE
// 电脑清除
ToolButtonType_CLEAR
// 系统修复
ToolButtonType_FIX
// 功能大全
ToolButtonType_ACTIONS
// 优化加速
ToolButtonType_YOUHUA
// 360商城
ToolButtonType_MARKET
// 软件管家
ToolButtonType_APP
)
// showToolBarsLayout show toolbars layout
// 显示工具按钮
func (mw *MainWindow) showToolBarsLayout() {
widget := widgets.NewQWidget(mw.window, 0)
// 设置一个QVboxLayout布局
widget.SetLayout(widgets.NewQVBoxLayout())
widget.SetGeometry2(0, 30, WIDTH, 90)
// 添加8个ToolButton
for i := 0; i< PAGE_COUNT; i++ {
// 创建ToolButton
toolButtons[i] = NewToolButton2 (widget, toolButtons_name[i],
toolButtons_icon_name[i])
// 设置显示位置
toolButtons[i].Widget().SetGeometry2(20+90*i, 0, 90, 90)
// 设置点击状态
toolButtons[i].SetChecked (i==0)
// 按下时执行
toolButtons[i].ConnectClicked(mw.onToolButtonDidClicked)
// 设置一个用户标识
toolButtons[i].SetUserObject(i)
}
// 显示我的章子,
// 名人作画都会盖个章,则也学学名人,盖个章呗 呵呵。
wl := NewWidgetLog(widget)
wl.Widget().SetGeometry2(740, 15, 300, 90)
}
最后一部分代码,
这个就是下面的白色部分了,这个有啥用?
后面的代码会讲解.
func (mw *MainWindow) showStackedWidget () {
mw.stackWidget = widgets.NewQStackedWidget(mw.window)
mw.stackWidget.SetGeometry2(0, 120, WIDTH, HEIGHT-120)
mw.stackWidget.SetCurrentIndex(0)
mw.stackWidget.SetStyleSheet("background: #FFFFFF")
}
最后定义了三个常量
这个宽高是截取360安全卫士的宽高,当然你也可以自己改个宽高,修改代码就是了.
const WIDTH = 920
const HEIGHT = 580
const PAGE_COUNT = 8