【golang-GUI开发】struct tags系统(二)qt的自定义组件和构造函数

栏目: C++ · 发布时间: 6年前

内容简介:今天我们来讲讲自定义组件和它的构造函数。下面我们就来重点讲解自定义组件和它的构造函数吧。先上代码:

今天我们来讲讲自定义组件和它的构造函数。

在前面的文章里我们已经接触了好几个自定组件,这次的示例是一个自定义对话框,他有一个about按钮,点击按钮可以显示出Qt的信息或者用户输入的信息。这是效果图:

【golang-GUI开发】struct tags系统(二)qt的自定义组件和构造函数 【golang-GUI开发】struct tags系统(二)qt的自定义组件和构造函数 【golang-GUI开发】struct tags系统(二)qt的自定义组件和构造函数

下面我们就来重点讲解自定义组件和它的构造函数吧。

构造函数的声明

先上代码:

type MyDialog struct {
    widgets.QDialog
    
    _ func() `constructor:"init"`
    
    _ func(string) `signal:"showAbout"`
    _ func() `signal:"showAboutQt"`
    
    _ func(bool)   `slot:"aboutClicked,auto"`
    _ func(string) `slot:"enableAboutButton,auto"`
    
    label         *widgets.QLabel
    edit          *widgets.QLineEdit
    testCheck     *widgets.QCheckBox
    isDialogCheck *widgets.QCheckBox
    aboutButton   *widgets.QPushButton
    closeButton   *widgets.QPushButton
}

构造函数用 “ _ func() `constructor:"init"` ”

来声明,目前只支持无参数的构造函数,以后会逐步扩展。之后我们需要实现一个名字是 init 的类方法,这是构造函数的实体。

qt的moc系统遇到派生自QObject及其派生类的类时,会自动生成一个 New[type name] 的函数(type name也会被Title处理),它会返回一个已经初始化的指向自定义类型实例的指针,这个函数的参数类型会根据最先继承的QObject或是其派生类的 New[type name] 而定,举个例子:

假设我们的类继承自 QLineEdit ,在qt里有 NewQLineEdit(parent QWidget_ITF) ,那么我们这个类自动生成的 New[type name] 就会是 New[type name](parent QWidget_ITF) ;

再举个例子,我们的组件继承自QWidget,它有 NewQWidget(parent QWidget_ITF, fo core.Qt__WindowType) ,那么我们的类会自动生成 New[type name](parent QWidget_ITF, fo core.Qt__WindowType)

我们实现的init会被 New[type name] 自动调用。不过这里有个问题,如果我想实现自己的 New[type name] 函数呢,比如需要加上自己的配置参数,其实也很简单,我们再定义一个 New[type name]WithXXX 然后在其中调用 New[type name] 即可,向下面这样:

func NewYourTypeWithConfig(conf Config) *YourType {
    // 假设继承自QWidget
    obj := NewYourType(nil, 0)
    // 一些额外的初始化处理
    // 一般在init里进行界面的初始化,如果你的界面初始化依赖外部数据,那么可以不指定constructor,
    // 这样New[type name]就不会自动调用init,你可以在自定义函数里调用它。
    obj.conf = conf
  
    // obj.init()
}

这就是构造函数的全貌了,接着我们来看看界面的初始化,也就是我们要实现的init函数:

func (d *MyDialog) init() {
    d.label = widgets.NewQLabel2("About &Text:", d, 0)
    d.edit = widgets.NewQLineEdit(nil)
    // 将label和edit绑定
    d.label.SetBuddy(d.edit)
    
    d.testCheck = widgets.NewQCheckBox2("Test case", nil)
    // 选择显示自定义组件的About还是Qt的About
    d.isDialogCheck = widgets.NewQCheckBox2("Show &Dialog's about", nil)

    // 当用户输入要显示的内容时才可以点击
    d.aboutButton = widgets.NewQPushButton2("&About", nil)
    d.aboutButton.SetDefault(true)
    d.aboutButton.SetEnabled(false)
    
    d.closeButton = widgets.NewQPushButton2("&Close", nil)
    d.closeButton.ConnectClicked( func(_ bool) {
        d.Done(0)
    })
    
    d.edit.ConnectTextChanged(d.EnableAboutButton)
    d.aboutButton.ConnectClicked(d.aboutClicked)
    
    topLeftLayout := widgets.NewQHBoxLayout()
    topLeftLayout.AddWidget(d.label, 0, 0)
    topLeftLayout.AddWidget(d.edit, 0, 0)
    
    leftLayout := widgets.NewQVBoxLayout()
    leftLayout.AddLayout(topLeftLayout, 0)
    leftLayout.AddWidget(d.testCheck, 0, 0)
    leftLayout.AddWidget(d.isDialogCheck, 0, 0)
    
    rightLayout := widgets.NewQVBoxLayout()
    rightLayout.AddWidget(d.aboutButton, 0, 0)
    rightLayout.AddWidget(d.closeButton, 0, 0)
    rightLayout.AddStretch(0)
    
    mainLayout := widgets.NewQHBoxLayout()
    mainLayout.AddLayout(leftLayout, 0)
    mainLayout.AddLayout(rightLayout, 0)
    d.SetLayout(mainLayout)
    
    d.SetWindowTitle("about")
}

代码也很简单,初始化widgets之后使用 QBoxLayout 进行布局,然后连接一下 closeButton ,使用 QDialog::done 退出dialog。

我们设置 aboutButton 初始为不可点击状态,直到有输入内容存在在改变它的状态,这一步由自动连接的 enableAboutButton 槽来完成;

然后是点击 aboutButton 时会检查 isDialogCheck 的值来确定弹出哪种对话框,这一步由 aboutClicked 槽来完成:

func (d *MyDialog) aboutClicked(_ bool) {
    text := d.edit.Text()
    
    if d.isDialogCheck.IsChecked() {
        d.ShowAbout(text)
    } else {
        d.ShowAboutQt()
    }
}

func (d *MyDialog) enableAboutButton(text string) {
    if text != "" {
        d.aboutButton.SetEnabled(true)
    } else {
        d.aboutButton.SetEnabled(false)
    }
}

然后就是主函数,将显示About对话框的信号和相应的处理函数连接,然后显示我们的组件:

func main() {
    app := widgets.NewQApplication(len(os.Args), os.Args)
    
    dialog := NewMyDialog(nil, 0)
    // 显示About Qt
    dialog.ConnectShowAboutQt( func() {
        app.AboutQtDefault()
    })
    // 显示自定义内容的About
    dialog.ConnectShowAbout( func(text string) {
        widgets.NewQMessageBox(dialog).About(dialog, "About Dialog", text)
    })
    
    dialog.Show()
    
    app.Exec()
}

显示About Qt时的效果:

【golang-GUI开发】struct tags系统(二)qt的自定义组件和构造函数

怎么样,是不是很简单,下一篇文章里我们将结束对qt struct tags的探索,如果有任何疑问或者建议,欢迎在评论指出!

祝玩得愉快!


以上所述就是小编给大家介绍的《【golang-GUI开发】struct tags系统(二)qt的自定义组件和构造函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

一胜九败

一胜九败

柳井正 / 徐静波 / 中信出版社 / 2011-1-19 / 28.00元

优衣库成长的过程,就是一个历经了无数次失败的过程。他们经历过无法从银行融资的焦灼,经历过“衣服因低价热销,但人们买回去之后立即把商标剪掉”的难堪,经历过为上市冲刺而拼命扩张店铺的疯狂,也经历过被消费者冷落、疏离的苦痛……但正是从这些失败中学到的经验与教训,让柳井正走向了成功。 《一胜九败:优衣库风靡全球的秘密》就像是柳井正的错误集,在这里,他毫不隐晦地将公司业绩低迷的原因、进军海外失败的因素......一起来看看 《一胜九败》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具