PyGobject(二十六)布局容器之Popover

Gtk.Popover

Gtk.Popover气泡布局,可以依附于其它部件,当点击其它部件的时候,弹出Popover气泡

继承关系

Gtk.Popover是Gtk.Bin的直接子类
这里写图片描述

Methods

方法修饰词方法名及参数
staticnew (relative_to)
staticnew_from_model (relative_to, model)
bind_model (model, action_namespace)
get_constrain_to ()
get_default_widget ()
get_modal ()
get_pointing_to ()
get_position ()
get_relative_to ()
get_transitions_enabled ()
set_constrain_to (constraint)
set_default_widget (widget)
set_modal (modal)
set_pointing_to (rect)
set_position (position)
set_relative_to (relative_to)
set_transitions_enabled (transitions_enabled)

Virtual Methods

do_closed ()

Properties

NameTypeFlagsShort Description
constrain-toGtk.PopoverConstraintr/w/enConstraint for the popover position
modalboolr/w/en点击其它区域是否可关闭,默认为True
pointing-toGdk.Rectangler/wpopover显示的矩形位置,相对于relative-to部件的位置
positionGtk.PositionTyper/w/enpopover的位置
relative-toGtk.Widgetr/wpopover依附于哪个部件
transitions-enabledboolr/w/en是否显示过渡效果,某人为True

Signals

NameShort Description
closed

例子

这里写图片描述
代码:

#!/usr/bin/env python3
# Created by xiaosanyu at 16/7/7
# section 030
TITLE = "Popover"
DESCRIPTION = """
Gtk.Popover is a bubble-like context window, primarily meant to provide context-dependent
information or options. Popovers are attached to a widget,
passed at construction time on Gtk.Popover.new(),
or updated afterwards through Gtk.Popover.set_relative_to(),
"""
import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, Gio, GLib
import os


class PopoverWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Popover Example")
        self.set_size_request(250, 200)
        box = Gtk.VBox(spacing=24)
        box.set_border_width(24)
        self.add(box)
        button = Gtk.ToggleButton("Button")
        popover = self.create_popover(button, Gtk.Label("This popover does not grab input"), Gtk.PositionType.TOP)
        # 点击其它区域不可关闭popover
        popover.set_modal(False)
        button.connect("toggled", self.toggle_changed_cb, popover)
        box.add(button)

        entry = Gtk.Entry()
        popover = self.create_complex_popover(entry, Gtk.PositionType.TOP)
        entry.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY, "edit-find")
        entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "edit-clear")

        entry.connect("icon-press", self.entry_icon_press_cb, popover)
        entry.connect("size-allocate", self.entry_size_allocate_cb, popover)
        box.add(entry)

        calendar = Gtk.Calendar()
        calendar.connect("day-selected", self.day_selected_cb)
        box.add(calendar)

    @staticmethod
    def create_popover(parent, child, pos):
        popover = Gtk.Popover(relative_to=parent)
        popover.set_position(pos)
        popover.add(child)
        popover.set_border_width(6)
        child.show()

        return popover

    def create_complex_popover(self, parent, pos):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(os.path.abspath(os.path.dirname(__file__)), '../../Data/popover.glade'))
        window = builder.get_object("window")
        content = window.get_child()
        content.get_parent().remove(content)
        popover = self.create_popover(parent, content, Gtk.PositionType.BOTTOM)
        return popover

    @staticmethod
    def toggle_changed_cb(button, popover):
        popover.set_visible(button.get_active())

    @staticmethod
    def entry_size_allocate_cb(entry, allocation, popover):

        if popover.is_visible():
            popover_pos = entry.popover_icon_pos
            rect = entry.get_icon_area(popover_pos)
            popover.set_pointing_to(rect)

    @staticmethod
    def entry_icon_press_cb(entry, icon_pos, event, popover):
        rect = entry.get_icon_area(icon_pos)
        popover.set_pointing_to(rect)
        popover.show()

        entry.popover_icon_pos = icon_pos

    def day_selected_cb(self, calendar):
        rect = Gdk.Rectangle()
        event = Gtk.get_current_event()

        if event.type != Gdk.EventType.BUTTON_PRESS:
            return

        event.button.x, event.button.y = event.button.window.coords_to_parent(event.button.x, event.button.y)
        allocation = calendar.get_allocation()
        rect.x = event.button.x - allocation.x
        rect.y = event.button.y - allocation.y
        rect.width = rect.height = 1

        entry = Gtk.Entry()
        entry.set_text("{}-{}-{}".format(*(calendar.get_date())))
        popover = self.create_popover(calendar, entry, Gtk.PositionType.BOTTOM)
        popover.set_pointing_to(rect)
        popover.show()


def main():
    win = PopoverWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()


if __name__ == "__main__":
    main()

代码解析

button = Gtk.ToggleButton("Button")

创建一个ToggleButton

popover = self.create_popover(button, Gtk.Label("This popover does not grab input"), Gtk.PositionType.TOP)

创建一个create_popover方法,创建popover

 @staticmethod
def create_popover(parent, child, pos):
    popover = Gtk.Popover(relative_to=parent)
    popover.set_position(pos)
    popover.add(child)
    popover.set_border_width(6)
    child.show()

    return popover

指定popover要依附的部件,和它其中要显示的子部件。
第一个popover,要依附的是一个ToggleButton,子部件是一个Label

entry = Gtk.Entry()
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY, "edit-find")      entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "edit-clear")

创建一个Entry,设置左右两个图表分别为“查找”和“清除”

popover = self.create_complex_popover(entry, Gtk.PositionType.TOP)

调用create_complex_popover方法创建第二个popover

def create_complex_popover(self, parent, pos):
    builder = Gtk.Builder()       
    builder.add_from_file(
               os.path.join(os.path.abspath(
               os.path.dirname(__file__)), 
               '../../Data/popover.glade'))
    window = builder.get_object("window")
    content = window.get_child()
    content.get_parent().remove(content)

    popover = self.create_popover(parent, content, Gtk.PositionType.BOTTOM)
    return popover

从popover.glade文件中创建布局,布局文件内容为

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Wed Nov 13 16:45:55 2013 -->
<interface>
  <!-- interface-requires gtk+ 3.10 -->
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name Name -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes">Item 1</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 2</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 3</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 4</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 5</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 6</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 7</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 8</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 9</col>
      </row>
      <row>
        <col id="0" translatable="yes">Item 10</col>
      </row>
    </data>
  </object>
  <object class="GtkWindow" id="window">
    <child>
      <object class="GtkBox" id="box">
        <property name="visible">1</property>
        <property name="orientation">vertical</property>
        <property name="spacing">6</property>
        <child>
          <object class="GtkEntry" id="entry1">
            <property name="visible">1</property>
            <property name="can_focus">1</property>
            <property name="primary_icon_name">edit-find</property>
            <property name="secondary_icon_name">edit-clear</property>
          </object>
        </child>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow1">
            <property name="visible">1</property>
            <property name="can_focus">1</property>
            <property name="shadow_type">in</property>
            <property name="max-content-height">100</property>
            <child>
              <object class="GtkTreeView" id="treeview1">
                <property name="visible">1</property>
                <property name="can_focus">1</property>
                <property name="vexpand">1</property>
                <property name="model">liststore1</property>
                <property name="headers_visible">0</property>
                <property name="enable_search">0</property>
                <property name="search_column">2</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="column1">
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderer1"/>
                      <attributes>
                        <attribute name="text">0</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
entry.connect("icon-press", self.entry_icon_press_cb, popover)

绑定”icon-press”(点击图标)信号到entry_icon_press_cb方法

 @staticmethod
def entry_icon_press_cb(entry, icon_pos, event, popover):
    rect = entry.get_icon_area(icon_pos)
    popover.set_pointing_to(rect)
    popover.show()

    entry.popover_icon_pos = icon_pos

rect = entry.get_icon_area(icon_pos)
获取点击图标的区域
popover.set_pointing_to(rect)
popover.show()

设置popover显示的位置,并显示
entry.popover_icon_pos = icon_pos
标记当前点击的是哪个图标

entry.connect("size-allocate", self.entry_size_allocate_cb, popover)     

绑定”size-allocate”(entry大小变化)信号到entry_size_allocate_cb方法

@staticmethod
def entry_size_allocate_cb(entry, allocation, popover):
    if popover.is_visible():
        popover_pos = entry.popover_icon_pos
        rect = entry.get_icon_area(popover_pos)
        popover.set_pointing_to(rect)

当窗口大小改变时,如果popover是显示状态,重新设置它的显示位置。

最后创建一个Calendar(日历部件)

calendar = Gtk.Calendar()
calendar.connect("day-selected", self.day_selected_cb)

并且绑定”day-selected”信号到day_selected_cb方法上

def day_selected_cb(self, calendar):
    rect = Gdk.Rectangle()
    event = Gtk.get_current_event()

    if event.type != Gdk.EventType.BUTTON_PRESS:
        return

    event.button.x, event.button.y = event.button.window.coords_to_parent(event.button.x, event.button.y)
    allocation = calendar.get_allocation()
    rect.x = event.button.x - allocation.x
    rect.y = event.button.y - allocation.y
    rect.width = rect.height = 1

    entry = Gtk.Entry()
    entry.set_text("{}-{}-{}".format(*(calendar.get_date())))
    popover = self.create_popover(calendar, entry, Gtk.PositionType.BOTTOM)
    popover.set_pointing_to(rect)
    popover.show()

rect = Gdk.Rectangle()
创建一个矩形
根据当前按钮点击的位置,设置矩形的坐标
最后调用create_popover方法创建一个popover,显示当前点击的日期





代码下载地址:http://download.csdn.net/detail/a87b01c14/9594728

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanxiaochengyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值