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

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

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

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

在前面的文章里我们已经接触了好几个自定组件,这次的示例是一个自定义对话框,他有一个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的自定义组件和构造函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Programming Concurrency on the JVM

Programming Concurrency on the JVM

Venkat Subramaniam / The Pragmatic Bookshelf / 2011-6-1 / USD 35.00

Concurrency on the Java platform has evolved, from the synchronization model of JDK to software transactional memory (STM) and actor-based concurrency. This book is the first to show you all these con......一起来看看 《Programming Concurrency on the JVM》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具