0%

本篇日志主要讲述了如何在MacOSX和Linux上安装PGPLOT,以避免经历一些不必要的坑。

Ubuntu/Debain/Fedora/Mac/CentOS 安装PGPLOT

最简单的安装方式为使用我提供的docker镜像,参考AstroSoft

只需要下面的一个命令,即可使用。目前支持Ubuntu和CentOS两大发行版。

Ubuntu

1
$ docker run -it -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix shaoguangleo/ubuntu-pgplot

CentOS

1
$ docker run -it -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix shaoguangleo/centos-pgplot

开始

下面开始正文,源码安装。正常情况下,安装分为两个步骤:

  1. 安装图形库
  2. 配置环境变量
  3. 然后可以使用一些demo来测试程序是否正常运行

Mac 用户

Mac上最方便的安装PGPLOT的方法就是使用port,首先确认已经安装了port,然后执行:

1
$ port installed pgplot

不同的PGPLOT库 (libpgplot.* 和 libcpgplot.*) 安装在 /opt/local/lib 文件夹,X11 服务安装在 /opt/local/bin/pgxwin_server,其他一些文件安装在/opt/local/share/pgplot。

安装完成后,要确定下环境变量是否配置好,可以使用下述命令来检查:

1
2
$ echo $PGPLOT_DIR
$ echo $PGPLOT_DEV

如果环境变量没有设置,可以通过下属命令来设置:

1
2
$ export PGPLOT_DIR=/opt/local/lib
$ export PGPLOT_DEV=/Xserve

当然最好的方法就是把这些环境变量写在.bashrc文件中。

最后确保所有的示例程序工作正常。

1
2
3
4
$ /opt/local/share/pgplot/examples/pgdemo1
$ /opt/local/share/pgplot/examples/pgdemo2
$ /opt/local/share/pgplot/examples/pgdemo3
...

Linux 用户

在Linux系统中,从pgplot下载源码,在Linux里面手动编译的方式比较好,目前最新的版本为pgplot5.2。不过这里比较注意,一个前提条件就是X11文件是可用的,另外一个就是需要安装gfortran编辑器。

不同的系统支持的包不同,详细看下面的命令。

Fedora:

1
2
$ sudo yum install libX11-devel
$ sudo yum install gcc-gfortran

Ubuntu:

1
2
$ sudo apt-get install xorg-dev
$ sudo apt-get install gfortran

CentOS:

1
2
$ sudo yum install libX11-devel
$ sudo yum install gcc-gfortran

OpenSUSE:

1
2
$ sudo zypper install xorg-X11-devel
$ sudo zypper install gcc-fortran

Debian:

1
2
$ sudo apt-get install libX11-dev
$ sudo apt-get install gfortran

详细的安装步骤

  1. 下载源码 pgplot5.2
  2. 解压并将源码放在/usr/local/src/中
1
2
3
# cd /usr/local/src
# mv ~/Downloads/pgplot5.2.tar.gz .
# tar zxvf pgplot5.2.tar.gz
  1. 创建pgplot安装的路径:
1
2
# mkdir /usr/local/pgplot
# cd /usr/local/pgplot
  1. 拷贝 drivers.list 文件到安装目录:
1
# cp /usr/local/src/pgplot/drivers.list .
  1. 编辑drives.list文件,将下面的注释取消:
  • /PS
  • /VPS
  • /CPS
  • /VCPS
  • /XServe
  1. 创建makefile文件
1
# /usr/local/src/pgplot/makemake /usr/local/src/pgplot linux g77_gcc_aout

编辑makefile文件,并将FCOMPL=g77替换为FCOMPL=gfortran

  1. 编译源码:
1
2
3
# make
# make cpg
# make clean

确定环境变量已经设置:

1
2
$ export PGPLOT_DIR=/usr/local/pgplot
$ export PGPLOT_DEV=/Xserve

使用测试用例来检测安装已经完成。

1
2
3
4
$ /usr/local/pgplot/pgdemo1
$ /usr/local/pgplot/pgdemo2
$ /usr/local/pgplot/pgdemo3
...

在MacOSX平台上运行Docker GUI程序

在Linux平台上,运行Docker的GUI是很简单的事情,只要共享DISPLAY变量挂在/tmp/.X11-unix即可。

Mac OS X 稍微有些复杂,如下所示。

安装基础软件

socat

socat用于创建两个节点的双向数据流通信。

1
2
$ brew install socat
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"

Xquartz

Xquartz为Mac OS X系统上的X窗口系统。

1
$ brew install Caskroom/cask/xquartz

打开Xquartz软件,偏好设置->安全性->勾选允许从网络客户端连接

运行

1
$ docker run -e DISPLAY=192.168.1.4:0 shaoguangleo/ubuntu-astrosoft

其中IP地址为本机的IP地址,注意修

其中IP可用通过下面的命令来获取:

1
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')

另外一种方法

在MacOSX上运行,

1
2
3
$xhost +127.0.0/1
#或者
$xhost +localhost

确保localhost允许X11转发

然后在docker镜像内部执行显示映射

1
2
$ export DISPLAY=$IP:0
$ docker run -it -e DISPLAY=$IP:0 shaoguangleo/ubuntu-astrosoft

ARM芯片

Apple在2021年发布了搭载ARM芯片的操作系统,会出现linux/arm64/v8不执行的提示,可以通过下面的方式来解决。

1
$ export DOCKER_DEFAULT_PLATFORM=linux/amd64 

或者使用指定的参数--platform=linux/amd64 来编译或者运行amd的镜像与版本。

参考:cflags - How to add ‘-march=’ as default option to gcc? - Stack Overflow

在Linux平台上,运行Docker的GUI是很简单的事情,只要共享DISPLAY变量挂在/tmp/.X11-unix,
并且开放控制X server的访问权限即可。

在宿主机上运行命令

1
$ xhost +

此时就可以使用docker的图形界面了,比如测试如下:

1
2
3
4
5
$ docker run -it -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix shaoguangleo/centos-pgplot

然后输入

# /usr/local/pgplot/pgdemo1

见证奇迹。

Docker Data Management

There are two methods to handle Docker data.

Method 1 : Data Volume

1
$ docker run -v /local/path:/docker/path shaoguangleo/ubuntu:lateset

Also , you can mount several directories at the same time.

1
$ docker run -v /local/path:/docker/path -v /local/path2:/docker/path2 -v /local/path3:/docker/path3 shaoguangleo/ubuntu:lateset

By default the data volume can be read and write, you can specify the parameter point out.

For example: Just read

1
$ docker run -v /local/path:/docker/path:ro shaoguangleo/ubuntu:lateset

Method 2 : Data Volume Container

First create a data volume container and mount to /dbdata

1
$ docker run -it -v /dbdata shaoguangleo/ubuntu:lateset

Then we can using --volumes-from to mount the dbdata through many dockers.

1
2
3
$ docker run -it --volumes-from dbdata --name db1 ubuntu
$ docker run -it --volumes-from dbdata --name db2 ubuntu
$ docker run -it --volumes-from dbdata --name db3 ubuntu

So we can modify some file in dbdata which can immediately work in other dockers.

Docker backup/restore data

By the way, we can also using docker to backup or restore data.

backup

1
$ docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata

restore

1
2
$ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
$ docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

Set up the wordpress using Docker

First set up the enviroment

Method 1 : using docker

1
2
sudo docker run --name db --env MYSQL_ROOT_PASSWORD=example -d mariadb
sudo docker run --name MyWordPress --link db:mysql -p 8080:80 -d wordpress

Method 2 : using docker-compose

1
2
3
4
5
6
7
8
9
10
wordpress:
image: wordpress
links:
- db:mysql
port:
- 8080:80
db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: example

Now run

1
access http://ip:8080

PyQt教程

PyQt是一个GUI组件包,是Qt的一个Python接口,十分强大,并且可跨平台。

PyQt是一个Python编程和Qt库的瑞士军刀。

本教程将指导如何使用PyQt.

PyQt教程

PyQt是一个GUI组件包,跨平台,支持Windows,Linux和MacOSX。

PyQt的API包括非界面的QtCore,界面的QtGui和其他一些诸如QtXml、QtSvg、QtSql等。

PyQt有两个版本,目前为5.5版本。

PyQt5 最简单的hello world

简介

创建一个简单的GUi程序,需要包括下面几个步骤:

  1. 导入QtWidgets模组
  2. 创建一个Application
  3. QWidget用于创建顶层窗口,然后增加一个QLabel
  4. 设置标签的内容为Hello World
  5. 设置窗口的尺寸和位置
  6. 进入主循环

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
from PyQt5 import QtGui, QtWidgets

def window():
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
b = QtWidgets.QLabel(w)
b.setText("Hello World")
w.setGeometry(100,100,200,50)
b.move(50,20)
w.setWindowTitle("PyQt HelloWorld")
w.show()
sys.exit(app.exec_())


if __name__ == '__main__':
window()

效果图

参考https://semver.org/

语义化版本 2.0.0

摘要

版本格式:主版本号.次版本号.修订号,版本号递增规则如下:

  1. 主版本号:当你做了不兼容的 API 修改,
  2. 次版本号:当你做了向下兼容的功能性新增,
  3. 修订号:当你做了向下兼容的问题修正。

先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

简介

在软件管理的领域里存在着被称作“依赖地狱”的死亡之谷,系统规模越大,加入的包越多,你就越有可能在未来的某一天发现自己已深陷绝望之中。

在依赖高的系统中发布新版本包可能很快会成为噩梦。如果依赖关系过高,可能面临版本控制被锁死的风险(必须对每一个依赖包改版才能完成某次升级)。而如果依赖关系过于松散,又将无法避免版本的混乱(假设兼容于未来的多个版本已超出了合理数量)。当你专案的进展因为版本依赖被锁死或版本混乱变得不够简便和可靠,就意味着你正处于依赖地狱之中。

作为这个问题的解决方案之一,我提议用一组简单的规则及条件来约束版本号的配置和增长。这些规则是根据(但不局限于)已经被各种封闭、开放源码软件所广泛使用的惯例所设计。为了让这套理论运作,你必须先有定义好的公共 API 。这可以透过文件定义或代码强制要求来实现。无论如何,这套 API 的清楚明了是十分重要的。一旦你定义了公共 API,你就可以透过修改相应的版本号来向大家说明你的修改。考虑使用这样的版本号格式:X.Y.Z (主版本号.次版本号.修订号)修复问题但不影响API 时,递增修订号;API 保持向下兼容的新增及修改时,递增次版本号;进行不向下兼容的修改时,递增主版本号。

我称这套系统为“语义化的版本控制”,在这套约定下,版本号及其更新方式包含了相邻版本间的底层代码和修改内容的信息。

语义化版本控制规范(SemVer)

以下关键词 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照 RFC 2119 的叙述解读。(译注:为了保持语句顺畅, 以下文件遇到的关键词将依照整句语义进行翻译,在此先不进行个别翻译。)

1.

使用语义化版本控制的软件必须(MUST)定义公共 API。该 API 可以在代码中被定义或出现于严谨的文件内。无论何种形式都应该力求精确且完整。

2.

标准的版本号必须(MUST)采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止(MUST NOT)在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号。每个元素必须(MUST)以数值来递增。例如:1.9.1 -> 1.10.0 -> 1.11.0。

3.

标记版本号的软件发行后,禁止(MUST NOT)改变该版本软件的内容。任何修改都必须(MUST)以新版本发行。

4.

主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。

5.

1.0.0 的版本号用于界定公共 API 的形成。这一版本之后所有的版本号更新都基于公共 API 及其修改内容。

6.

修订号 Z(x.y.Z | x > 0)必须(MUST)在只做了向下兼容的修正时才递增。这里的修正指的是针对不正确结果而进行的内部修改。

7.

次版本号 Y(x.Y.z | x > 0)必须(MUST)在有向下兼容的新功能出现时递增。在任何公共 API 的功能被标记为弃用时也必须(MUST)递增。也可以(MAY)在内部程序有大量新功能或改进被加入时递增,其中可以(MAY)包括修订级别的改变。每当次版本号递增时,修订号必须(MUST)归零。

8.

主版本号 X(X.y.z | X > 0)必须(MUST)在有任何不兼容的修改被加入公共 API 时递增。其中可以(MAY)包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须(MUST)归零。

9.

先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。数字型的标识符禁止(MUST NOT)在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。

10.

版本编译元数据可以(MAY)被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。当判断版本的优先层级时,版本编译元数据可(SHOULD)被忽略。因此当两个版本只有在版本编译元数据有差别时,属于相同的优先层级。范例:1.0.0-alpha+001、1.0.0+20130313144700、1.0.0-beta+exp.sha.5114f85。

11.

版本的优先层级指的是不同版本在排序时如何比较。判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译元数据不在这份比较的列表中)。由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较,例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定。例如:1.0.0-alpha < 1.0.0。有相同主版本号、次版本号及修订号的两个先行版本号,其优先层级必须(MUST)透过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:只有数字的标识符以数值高低比较,有字母或连接号时则逐字以 ASCII 的排序来比较。数字的标识符比非数字的标识符优先层级低。若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。范例:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。

为什么要使用语义化的版本控制?

这并不是一个新的或者革命性的想法。实际上,你可能已经在做一些近似的事情了。问题在于只是“近似”还不够。如果没有某个正式的规范可循,版本号对于依赖的管理并无实质意义。将上述的想法命名并给予清楚的定义,让你对软件使用者传达意向变得容易。一旦这些意向变得清楚,弹性(但又不会太弹性)的依赖规范就能达成。

举个简单的例子就可以展示语义化的版本控制如何让依赖地狱成为过去。假设有个名为“救火车”的函式库,它需要另一个名为“梯子”并已经有使用语义化版本控制的包。当救火车创建时,梯子的版本号为 3.1.0。因为救火车使用了一些版本 3.1.0 所新增的功能, 你可以放心地指定依赖于梯子的版本号大等于 3.1.0 但小于 4.0.0。这样,当梯子版本 3.1.1 和 3.2.0 发布时,你可以将直接它们纳入你的包管理系统,因为它们能与原有依赖的软件兼容。

作为一位负责任的开发者,你理当确保每次包升级的运作与版本号的表述一致。现实世界是复杂的,我们除了提高警觉外能做的不多。你所能做的就是让语义化的版本控制为你提供一个健全的方式来发行以及升级包,而无需推出新的依赖包,节省你的时间及烦恼。

如果你对此认同,希望立即开始使用语义化版本控制,你只需声明你的函式库正在使用它并遵循这些规则就可以了。请在你的 README 文件中保留此页连结,让别人也知道这些规则并从中受益。

FAQ

在 0.y.z 初始开发阶段,我该如何进行版本控制?

最简单的做法是以 0.1.0 作为你的初始化开发版本,并在后续的每次发行时递增次版本号。

如何判断发布 1.0.0 版本的时机?

当你的软件被用于正式环境,它应该已经达到了 1.0.0 版。如果你已经有个稳定的 API 被使用者依赖,也会是 1.0.0 版。如果你很担心向下兼容的问题,也应该算是 1.0.0 版了。

这不会阻碍快速开发和迭代吗?

主版本号为零的时候就是为了做快速开发。如果你每天都在改变 API,那么你应该仍在主版本号为零的阶段(0.y.z),或是正在下个主版本的独立开发分支中。

对于公共 API,若即使是最小但不向下兼容的改变都需要产生新的主版本号,岂不是很快就达到 42.0.0 版?

这是开发的责任感和前瞻性的问题。不兼容的改变不应该轻易被加入到有许多依赖代码的软件中。升级所付出的代价可能是巨大的。要递增主版本号来发行不兼容的改版,意味着你必须为这些改变所带来的影响深思熟虑,并且评估所涉及的成本及效益比。

为整个公共 API 写文件太费事了!

为供他人使用的软件编写适当的文件,是你作为一名专业开发者应尽的职责。保持专案高效一个非常重要的部份是掌控软件的复杂度,如果没有人知道如何使用你的软件或不知道哪些函数的调用是可靠的,要掌控复杂度会是困难的。长远来看,使用语义化版本控制以及对于公共 API 有良好规范的坚持,可以让每个人及每件事都运行顺畅。

万一不小心把一个不兼容的改版当成了次版本号发行了该怎么办?

一旦发现自己破坏了语义化版本控制的规范,就要修正这个问题,并发行一个新的次版本号来更正这个问题并且恢复向下兼容。即使是这种情况,也不能去修改已发行的版本。可以的话,将有问题的版本号记录到文件中,告诉使用者问题所在,让他们能够意识到这是有问题的版本。

如果我更新了自己的依赖但没有改变公共 API 该怎么办?

由于没有影响到公共 API,这可以被认定是兼容的。若某个软件和你的包有共同依赖,则它会有自己的依赖规范,作者也会告知可能的冲突。要判断改版是属于修订等级或是次版等级,是依据你更新的依赖关系是为了修复问题或是加入新功能。对于后者,我经常会预期伴随着更多的代码,这显然会是一个次版本号级别的递增。

如果我变更了公共 API 但无意中未遵循版本号的改动怎么办呢?(意即在修订等级的发布中,误将重大且不兼容的改变加到代码之中)

自行做最佳的判断。如果你有庞大的使用者群在依照公共 API 的意图而变更行为后会大受影响,那么最好做一次主版本的发布,即使严格来说这个修复仅是修订等级的发布。记住, 语义化的版本控制就是透过版本号的改变来传达意义。若这些改变对你的使用者是重要的,那就透过版本号来向他们说明。

我该如何处理即将弃用的功能?

弃用现存的功能是软件开发中的家常便饭,也通常是向前发展所必须的。当你弃用部份公共 API 时,你应该做两件事:(1)更新你的文件让使用者知道这个改变,(2)在适当的时机将弃用的功能透过新的次版本号发布。在新的主版本完全移除弃用功能前,至少要有一个次版本包含这个弃用信息,这样使用者才能平顺地转移到新版 API。

语义化版本对于版本的字串长度是否有限制呢?

没有,请自行做适当的判断。举例来说,长到 255 个字元的版本已过度夸张。再者,特定的系统对于字串长度可能会有他们自己的限制。

关于

语义化版本控制的规范是由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werner 所建立。

如果您有任何建议,请到 GitHub 上提出您的问题

许可证

知识共享 署名 3.0 (CC BY 3.0)

Button 窗口部件

Button(按钮)窗口部件是一个标准的 Tkinter 窗口部件,用来实现各种按钮。

按钮能够包含文本或图象,并与一个 Python 函数或方法相关联。当这个按钮被按下时,Tkinter 自动调用相关联的函数或方法。

按钮仅能显示一种字体,但是这个文本可以跨行。另外,这个文本中的一个字母可以有__下划线__,例如标明一个快捷键。默认情况,Tab 键用于将焦点移动到一个按钮部件。

一、那么什么时候用按钮部件呢?

简而言之,按钮部件用来让用户说“马上给我执行这个任务”,通常我们用显示在按钮上的文本或图象来提示。 按钮通常用在工具条中或应用程序窗口中,并且用来接收或忽略输入在对话框中的数据。

关于按钮和输入的数据的配合,可以参看 Checkbutton 和 Radiobutton 部件。

二、样式

普通的按钮很容易被创建,仅仅指定按钮的内容(文本、位图、图象)和一个当按钮被按下时的回调函数即可:

1
b = Button(master, text="OK", command=self.ok) 

没有回调函数的按钮是没有用的,当你按下这个按钮时它什么也不做。你可能在开发一个应用程序的时候想实现这种按钮,比如为了不干扰你的 beta 版的测试者:

1
b = Button(master, text="Help", state=DISABLED) 

如果你没有指定尺寸,按钮的大小将正好能够容纳它的内容。你可以用 padx 和 pady 选项来增加内容与按钮 边框的间距。你也可以用 height 和 width 选项来显式地设置按钮的尺寸。如果你在按钮中显示文本,那么这些选项将以文本的单位为定义按钮的尺寸。如果你替而代之显示图象,那么按钮的尺寸将是象素 (或其它的屏幕单位)。你实际上甚至能够用象素单位来定义文本按钮的尺寸,但这可能带来意外的结果。下面是指定尺寸 的一段例子代码:

1
2
f = Frame(master, height=32, width=32) f.pack_propagate(0) # don't shrink
b = Button(f, text="Sure!") b.pack(fill=BOTH, expand=1)

按钮能够显示多行文本(但只能用一种字体)。 你可以使用多行或 wraplength 选项来使按钮自己调整文本。 当调整文本时,使用 anchor,justify,也可加上 padx 选项来得到你所希望的格式。一个例子如下:

1
b = Button(master, text=longtext, anchor=W, justify=LEFT, padx=2) 

为了使一个普通的按钮看起来像凹入的,例如你想去实现某种类型的工具框,你可简单地将 relief 的值从 “RAISED“改变为”SUNKEN:

三、方法

Button 窗口部件支持标准的 Tkinter 窗口部件接口,加上下面的方法:

  • flash():频繁重画按钮,使其在活动和普通样式下切换
  • invoke() :调用与按钮相关联的命令
  • 下面的方法与你实现自己的按钮绑定有关:

tkButtonDown(), tkButtonEnter(), tkButtonInvoke(), tkButtonLeave(), tkButtonUp() 这些方法可以用在定制事件绑定中,所有这些方法接收 0 个或多个形参。

四、选项

Button 窗口部件支持下面的选项:

activebackground, activeforeground

类型:颜色;
说明:当按钮被激活时所使用的颜色。

anchor

类型:常量;
说明:控制按钮上内容的位置。使用N, NE, E, SE, S, SW, W, NW, or CENTER这些值之一。默认值 是 CENTER。

background (bg), foreground (fg)

类型:颜色;
说明:按钮的颜色。默认值与特定平台相关。

bitmap

类型:位图;
说 明:显示在窗口部件中的位图。如果 image 选项被指定了,则这个选项被忽略。下面的位图在所有平台上 都有 效:error, gray75, gray50, gray25, gray12, hourglass, info, questhead, question, 和 warning.

这后面附加的位图仅在 Macintosh 上有效:document, stationery, edition, application, accessory, folder, pfolder, trash, floppy, ramdisk, cdrom, preferences, querydoc, stop, note, 和 caution.

1
borderwidth (bd)

类型:整数; 说明:按钮边框的宽度。默认值与特定平台相关。但通常是 1 或 2 象素。

command

类型:回调; 说明:当按钮被按下时所调用的一个函数或方法。所回调的可以是一个函数、方法或别的可调用的 Python 对 象。

cursor

类型:光标;
说明:当鼠标移动到按钮上时所显示的光标。

default

类型:常量;
说明:如果设置了,则按钮为默认按钮。注意这个语法在Tk 8.0b2中已改变。

disabledforeground
类型:颜色;
说明:当按钮无效时的颜色。

font

类型:字体;
说明:按钮所使用的字体。按钮只能包含一种字体的文本。

highlightbackground, highlightcolor

类型:颜色;
说明:控制焦点所在的高亮边框的颜色。当窗口部件获得焦点的时候,边框为 highlightcolor 所指定的颜 色。否则边框为 highlightbackground 所指定的颜色。默认值由系统所定。

highlightthickness

类型:距离; 说明:控制焦点所在的高亮边框的宽度。默认值通常是 1 或 2 象素。

image

类型:图象;
说明:在部件中显示的图象。如果指定,则 text 和 bitmap 选项将被忽略。

justify

类型:常量;

说明:定义多行文本如何对齐。可取值有:LEFT, RIGHT, 或 CENTER。

padx, pady

类型:距离;
说明:指定文本或图象与按钮边框的间距。

relief

类型:常量;
说明:边框的装饰。通常按钮按下时是凹陷的,否则凸起。另外的可能取值有 GROOVE, RIDGE, 和 FLAT。

state

类型:常量;
说明:按钮的状态:NORMAL, ACTIVE 或 DISABLED。默认值为 NORMAL。

takefocus

类型:标志;
说明:表明用户可以 Tab 键来将焦点移到这个按钮上。默认值是一个空字符串,意思是如果按钮有按键绑定的 话,它可以通过所绑定的按键来获得焦点。

text

类型:字符串;
说明:显示在按钮中的文本。文本可以是多行。如果 bitmaps 或 image 选项被使用,则 text 选项被忽略。

textvariable

类型:变量;
说明:与按钮相关的 Tk 变量(通常是一个字符串变量)。如果这个变量的值改变,那么按钮上的文本相应更新。

underline

类型:整数; 说明:在文本标签中哪个字符加下划线。默认值为-1,意思是没有字符加下划线。

width, height

类型:距离; 说明:按钮的尺寸。如果按钮显示文本,尺寸使用文本的单位。如果按钮显示图象,尺寸以象素为单位(或屏 幕的单位)。如果尺寸没指定,它将根据按钮的内容来计算。

wraplength

类型:距离; 说明:确定一个按钮的文本何时调整为多行。它以屏幕的单位为单位。默认不调整。