标签归档:tkinter

matplotlib错误-没有名为tkinter的模块

问题:matplotlib错误-没有名为tkinter的模块

当我运行以下代码时,我尝试通过Windows 10上的Pycharm IDE使用matplotlib软件包:

from matplotlib import pyplot

我收到以下错误:

ImportError: No module named 'tkinter'

我知道在python 2.x中它叫做Tkinter,但这不是问题-我刚安装了一个全新的python 3.5.1。

编辑:此外,我还尝试导入’tkinter’和’Tkinter’-这些都不起作用(都返回了我提到的错误消息)。

I tried to use the matplotlib package via Pycharm IDE on windows 10. when I run this code:

from matplotlib import pyplot

I get the following error:

ImportError: No module named 'tkinter'

I know that in python 2.x it was called Tkinter, but that is not the problem – I just installed a brand new python 3.5.1.

EDIT: in addition, I also tried to import ‘tkinter’ and ‘Tkinter’ – neither of these worked (both returned the error message I mentioned).


回答 0

sudo apt-get install python3-tk

然后,

>> import tkinter # all fine

编辑

对于Windows,我认为问题是您没有安装完整的Python软件包。由于Tkinter应该随Python一起提供。请参阅:http : //www.tkdocs.com/tutorial/install.html

我建议安装ipython,它也提供功能强大的shell和必要的软件包。

sudo apt-get install python3-tk

Then,

>> import tkinter # all fine

Edit:

For Windows, I think the problem is you didn’t install complete Python package. Since Tkinter should be shipped with Python out of box. See: http://www.tkdocs.com/tutorial/install.html

I suggest install ipython, which provides powerful shell and necessary packages as well.


回答 1

您可以使用

import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt

如果您tkinter根本不想使用。

%matplotlib inline如果要使用笔记本,也不要忘记在笔记本顶部使用。

编辑:agg是不同的后端,如tkintermatplotlib。

you can use

import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt

if you dont want to use tkinter at all.

Also dont forget to use %matplotlib inline at the top of your notebook if using one.

EDIT: agg is a different backend like tkinter for matplotlib.


回答 2

在Centos上,软件包名称和命令是不同的。您需要执行以下操作:

sudo yum install tkinter

解决问题。

On Centos, the package names and commands are different. You’ll need to do:

sudo yum install tkinter

To fix the problem.


回答 3

对于Windows用户,无需再次下载安装程序。只需执行以下操作:

  1. 进入开始菜单,输入“ 程序和功能”
  2. 选择Python版本(对我来说是Python 3.6.5(64位)),
  3. 右键单击,按更改
  4. 点击修改
  5. 选择td / tk和IDLE(将安装tkinter),然后单击下一步

等待安装,您就完成了。

For Windows users, there’s no need to download the installer again. Just do the following:

  1. Go to start menu, type Apps & features,
  2. Search for “python” in the search box,
  3. Select the Python version (e.g. Python 3.8.3rc1(32-bit)) and click Modify,
  4. On the Modify Setup page click Modify,
  5. Tick td/tk and IDLE checkbox (which installs tkinter) and click next.

Wait for installation and you’re done.


回答 4

我搜索此问题的几乎所有答案都说Windows上的Python随附了tkinter和tcl,并且我没有运气尝试使用pip或actviestate.com网站下载或安装它们。我最终发现,当我使用二进制安装程序安装python时,我没有选中与TCL和tkinter相关的模块。因此,我再次运行二进制安装程序,并选择了这次选择此选项来修改我的python版本。然后,无需手动执行任何操作。如果您转到python终端,则以下命令应显示与Python一起安装的tkinter版本:

import tkinter
import _tkinter
tkinter._test()

Almost all answers I searched for this issue say that Python on Windows comes with tkinter and tcl already installed, and I had no luck trying to download or install them using pip, or actviestate.com site. I eventually found that when I was installing python using the binary installer, I had unchecked the module related to TCL and tkinter. So, I ran the binary installer again and chose to modify my python version by this time selecting this option. No need to do anything manually then. If you go to your python terminal, then the following commands should show you version of tkinter installed with your Python:

import tkinter
import _tkinter
tkinter._test()

回答 5

如果您使用的是fedora,请先安装tkinter

sudo dnf install python3-tkinter

我不认为您以后需要导入tkinter我也建议您使用virtualenv

$ python3 -m venv myvenv
$ source myvenv/bin/activate

并使用pip添加必要的软件包

If you are using fedora then first install tkinter

sudo dnf install python3-tkinter

I don’t think you need to import tkinter afterwards I also suggest you to use virtualenv

$ python3 -m venv myvenv
$ source myvenv/bin/activate

And add the necessary packages using pip


回答 6

在CentOS 7和Python 3.4上,命令是 sudo yum install python34-tkinter

在具有Python 3.6的Redhat 7.4上,命令为 sudo yum install rh-python36-python-tkinter

On CentOS 7 and Python 3.4, the command is sudo yum install python34-tkinter

On Redhat 7.4 with Python 3.6, the command is sudo yum install rh-python36-python-tkinter


回答 7

对于Windows用户,请重新运行安装程序。选择修改。选中tcl / tk和IDLE框。此说明说“ Installs tkinter”

For windows users, re-run the installer. Select Modify. Check the box for tcl/tk and IDLE. The description for this says “Installs tkinter”


回答 8

在Ubuntu上,2018年初,python3.6-tkUbuntu的(xenial / 16.04)正态发行版上python-tk没有任何版本,因此即使您拥有较早的版本也无法使用。

我的解决方案是使用设置所有内容python 3.5

 sudo apt install python3.5-tk
 virtualenv --python=`which python3.5` python-env
 source python-env/bin/activate
 pip install -r requirements.txt

现在matplotlib可以找到tkinter

编辑

毕竟我只需要3.6,诀窍是:

sudo apt install tk-dev

然后 之后重建python3.6 tk-dev,例如:

./configure
make
make install

On Ubuntu, early 2018, there is no python3.6-tk on ubuntu’s (xenial/16.04) normal distributions, so even if you have earlier versions of python-tk this won’t work.

My solution was to use set everything up with python 3.5:

 sudo apt install python3.5-tk
 virtualenv --python=`which python3.5` python-env
 source python-env/bin/activate
 pip install -r requirements.txt

And now matplotlib can find tkinter.

EDIT:

I just needed 3.6 afterall, and the trick was to:

sudo apt install tk-dev

and then rebuild python3.6, after tk-dev, eg:

./configure
make
make install

回答 9

如果您使用的是python 3.6,则对我有用:

sudo apt-get install python3.6-tk

代替

sudo apt-get install python3-tk

适用于其他版本的python3

If you are using python 3.6, this worked for me:

sudo apt-get install python3.6-tk

instead of

sudo apt-get install python3-tk

Which works for other versions of python3


回答 10

对于像我这样的可怜人,使用python 3.7。您需要python3.7-tk包装。

sudo apt install python3.7-tk

$ python
Python 3.7.4 (default, Sep  2 2019, 20:44:09)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'tkinter'
>>> exit()

注意。python3-tk已安装。但是不是python3.7-tk

$ sudo apt install python3.7-tk
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  tix python3.7-tk-dbg
The following NEW packages will be installed:
  python3.7-tk
0 upgraded, 1 newly installed, 0 to remove and 34 not upgraded.
Need to get 143 kB of archives.
After this operation, 534 kB of additional disk space will be used.
Get:1 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu xenial/main amd64 python3.7-tk amd64 3.7.4-1+xenial2 [143
kB]
Fetched 143 kB in 0s (364 kB/s)
Selecting previously unselected package python3.7-tk:amd64.
(Reading database ... 256375 files and directories currently installed.)
Preparing to unpack .../python3.7-tk_3.7.4-1+xenial2_amd64.deb ...
Unpacking python3.7-tk:amd64 (3.7.4-1+xenial2) ...
Setting up python3.7-tk:amd64 (3.7.4-1+xenial2) ...

安装后,一切都很好。

$ python3
Python 3.7.4 (default, Sep  2 2019, 20:44:09)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> exit()

For the poor guys like me using python 3.7. You need the python3.7-tk package.

sudo apt install python3.7-tk

$ python
Python 3.7.4 (default, Sep  2 2019, 20:44:09)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'tkinter'
>>> exit()

Note. python3-tk is installed. But not python3.7-tk.

$ sudo apt install python3.7-tk
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  tix python3.7-tk-dbg
The following NEW packages will be installed:
  python3.7-tk
0 upgraded, 1 newly installed, 0 to remove and 34 not upgraded.
Need to get 143 kB of archives.
After this operation, 534 kB of additional disk space will be used.
Get:1 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu xenial/main amd64 python3.7-tk amd64 3.7.4-1+xenial2 [143
kB]
Fetched 143 kB in 0s (364 kB/s)
Selecting previously unselected package python3.7-tk:amd64.
(Reading database ... 256375 files and directories currently installed.)
Preparing to unpack .../python3.7-tk_3.7.4-1+xenial2_amd64.deb ...
Unpacking python3.7-tk:amd64 (3.7.4-1+xenial2) ...
Setting up python3.7-tk:amd64 (3.7.4-1+xenial2) ...

After installing it, all good.

$ python3
Python 3.7.4 (default, Sep  2 2019, 20:44:09)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> exit()

回答 11

在带有python 2.7的CentOS 6.5上,我需要这样做: yum install python27-tkinter

On CentOS 6.5 with python 2.7 I needed to do: yum install python27-tkinter


回答 12

有时(例如在osgeo4w发行版中)tkinter被删除。

尝试改变matplotlib后台编辑matplotlibrc位于文件[python install dir]/matplotlib/mpl-data/matplotlibrc变化的后台参数来自backend: TkAgg于其他类似的东西backend: Qt4Agg如下所述:http://matplotlib.org/faq/usage_faq.html#what-is-a-backend

Sometimes (for example in osgeo4w distribution) tkinter is removed.

Try changing matplotlib backend editing matplotlibrc file located in [python install dir]/matplotlib/mpl-data/matplotlibrc changing The backend parameter from backend: TkAgg to something other like backend: Qt4Aggas described here: http://matplotlib.org/faq/usage_faq.html#what-is-a-backend


回答 13

由于我在Ubuntu上使用Python 3.7,因此必须使用:

sudo apt-get install python3.7-tk

Since I’m using Python 3.7 on Ubuntu I had to use:

sudo apt-get install python3.7-tk

回答 14

也许您从源代码安装了python。在这种情况下,您可以在支持tcl / tk的情况下重新编译python。

  1. 从以下位置编译并安装tcl / tk http://www.tcl.tk/software/tcltk/download.html,我假设您在安装了python /home/xxx/local/tcl-tk/
# install tcl
wget -c https://prdownloads.sourceforge.net/tcl/tcl8.6.9-src.tar.gz
tar -xvzf tcl8.6.9-src.tar.gz
cd tcl8.6.9
./configure --prefix=/home/xxx/local/tcl-tk/
make
make install

# install tk
wget -c https://prdownloads.sourceforge.net/tcl/tk8.6.9.1-src.tar.gz
tar -xvzf tk8.6.9.1-src.tar.gz
cd tk8.6.9.1
./configure --prefix=/home/xxx/local/tcl-tk/
make
make install
  1. 使用支持的tcl / tk重新编译python,例如:
# download the source code of python and decompress it first.

cd <your-python-src-dir>
./configure --prefix=/home/xxx/local/python \
 --with-tcltk-includes=/home/xxx/local/tcl-tk/include \
 --with-tcltk-libs=/home/xxx/local/tcl-tk/lib
make 
make install

Maybe you installed python from source. In this case, you can recompile python with tcl/tk supported.

  1. Complie and install tcl/tk from http://www.tcl.tk/software/tcltk/download.html, I’ll suppose you installed python at /home/xxx/local/tcl-tk/.
# install tcl
wget -c https://prdownloads.sourceforge.net/tcl/tcl8.6.9-src.tar.gz
tar -xvzf tcl8.6.9-src.tar.gz
cd tcl8.6.9
./configure --prefix=/home/xxx/local/tcl-tk/
make
make install

# install tk
wget -c https://prdownloads.sourceforge.net/tcl/tk8.6.9.1-src.tar.gz
tar -xvzf tk8.6.9.1-src.tar.gz
cd tk8.6.9.1
./configure --prefix=/home/xxx/local/tcl-tk/
make
make install
  1. Recompile python with tcl/tk supported, for example:
# download the source code of python and decompress it first.

cd <your-python-src-dir>
./configure --prefix=/home/xxx/local/python \
 --with-tcltk-includes=/home/xxx/local/tcl-tk/include \
 --with-tcltk-libs=/home/xxx/local/tcl-tk/lib
make 
make install

_tkinter.TclError:没有显示名称并且没有$ DISPLAY环境变量

问题:_tkinter.TclError:没有显示名称并且没有$ DISPLAY环境变量

我在服务器中运行一个简单的python脚本:

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randn(60)
y = np.random.randn(60)

plt.scatter(x, y, s=20)

out_png = 'path/to/store/out_file.png'
plt.savefig(out_png, dpi=150)

我尝试python example.py在已安装matplotlib 1.5.1的服务器中使用该命令,但失败并显示以下错误:

Traceback (most recent call last):
  File "example.py", line 7, in <module>
    plt.scatter(x, y, s=20)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 3241, in scatter
    ax = gca()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 928, in gca
    return gcf().gca(**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 578, in gcf
    return figure()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 527, in figure
**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 84, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 92, in new_figure_manager_given_figure
    window = Tk.Tk()
  File "/usr/local/lib/python2.7/lib-tk/Tkinter.py", line 1810, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

这是怎么回事

I am running a simple python script in the server:

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randn(60)
y = np.random.randn(60)

plt.scatter(x, y, s=20)

out_png = 'path/to/store/out_file.png'
plt.savefig(out_png, dpi=150)

I try to use the command python example.py in this server which has matplotlib 1.5.1 installed it fails with the error:

Traceback (most recent call last):
  File "example.py", line 7, in <module>
    plt.scatter(x, y, s=20)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 3241, in scatter
    ax = gca()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 928, in gca
    return gcf().gca(**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 578, in gcf
    return figure()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 527, in figure
**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 84, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 92, in new_figure_manager_given_figure
    window = Tk.Tk()
  File "/usr/local/lib/python2.7/lib-tk/Tkinter.py", line 1810, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

What is happening here?


回答 0

Matplotlib默认情况下选择Xwindows后端。您需要将matplotlib设置为不使用Xwindows后端。

将此代码添加到脚本的开头(在导入pyplot之前),然后重试:

import matplotlib
matplotlib.use('Agg')

或添加到.config/matplotlib/matplotlibrcbackend: Agg以使用非交互式后端。

echo "backend: Agg" > ~/.config/matplotlib/matplotlibrc

或者在连接到服务器时使用ssh -X remoteMachine命令来使用Xwindows。

您也可以尝试导出显示:export DISPLAY=mymachine.com:0.0

有关更多信息:https : //matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

Matplotlib chooses Xwindows backend by default. You need to set matplotlib to not use the Xwindows backend.

Add this code to the start of your script (before importing pyplot) and try again:

import matplotlib
matplotlib.use('Agg')

Or add to .config/matplotlib/matplotlibrc line backend: Agg to use non-interactive backend.

echo "backend: Agg" > ~/.config/matplotlib/matplotlibrc

Or when connect to server use ssh -X remoteMachine command to use Xwindows.

Also you may try to export display: export DISPLAY=mymachine.com:0.0.

For more info: https://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server


回答 1

您可以通过在.py脚本的非常开头添加这两行来解决此问题。

import matplotlib
matplotlib.use('Agg')

PS:如果在源代码的开头没有添加这两行,则错误仍然存​​在。

You can solve it by adding these two lines in the VERY beginning of your .py script.

import matplotlib
matplotlib.use('Agg')

PS: The error will still exists if these two lines are not added in the very beginning of the source code.


回答 2

为了加总答案,我在所需脚本的开头使用了它。因此它可以在不同的环境下平稳运行。

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

因为我不希望它总是使用'Agg'后端,所以仅当它通过Travis CI时才如此。

To add up on the answer, I used this at the beginning of the needed script. So it runs smoothly on different environments.

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

Because I didn’t want it to be alsways using the 'Agg' backend, only when it would go through Travis CI for example.


回答 3

我在尝试在Raspberry Pi上远程运行一个简单的tkinter应用程序时遇到了同样的问题。就我而言,我确实希望在pi显示器上显示tkinter GUI,但是我希望能够从主机通过SSH执行它。我也没有使用matplotlib,所以这不是造成我问题的原因。我可以通过将DISPLAY环境变量设置为错误来解决该问题,该错误表明了以下命令:

export DISPLAY=:0.0

可以在此处找到有关显示环境变量的功能以及语法为何如此奇怪的很好的解释:https : //askubuntu.com/questions/432255/what-is-display-environment-variable

I had this same issue trying to run a simple tkinter app remotely on a Raspberry Pi. In my case I did want to display the tkinter GUI on the pi display, but I want to be able to execute it over SSH from my host machine. I was also not using matplotlib, so that wasn’t the cause of my issue. I was able to resolve the issue by setting the DISPLAY environment variable as the error suggests with the command:

export DISPLAY=:0.0

A good explanation of what the display environment variable is doing and why the syntax is so odd can be found here: https://askubuntu.com/questions/432255/what-is-display-environment-variable


回答 4

另一个解决方案是安装Xvfb,然后将显示导出到该文件。即:

disp=:8
screen=0
geom=640x480x24
exec Xvfb $disp -screen $screen $geom 2>/tmp/Xvfb.log &

然后

$ export DISPLAY =:8

$ ./example.py

Another solution is to install Xvfb, and export your display to it. ie:

disp=:8
screen=0
geom=640x480x24
exec Xvfb $disp -screen $screen $geom 2>/tmp/Xvfb.log &

Then

$ export DISPLAY=:8

$ ./example.py


回答 5

在使用Xshell连接Linux服务器时,我也遇到了这个问题。

在寻找方法之后,我找到了Xming + Xshell来解决matplotlib的图像显示问题。

如果上述解决方案不能解决您的问题,请尝试在使用Xshell的条件下下载Xming。然后在Xshell中设置属性,SSH->隧道-> X11transfer->选择X DISPLAY localhost:0.0

I also met this problem while using Xshell to connect Linux server.

After seaching for methods, I find Xming + Xshell to solve image imshow problem with matplotlib.

If solutions aboved can’t solve your problem, just try to download Xming under the condition you’re using Xshell. Then set the attribute in Xshell, SSH->tunnel->X11transfer->choose X DISPLAY localhost:0.0


回答 6

为了查看图像,图解以及远程计算机的Windows上显示的所有内容,您需要像这样连接到它:

ssh -X user@hostname

这样,您就可以访问X服务器。X服务器是X窗口系统中的程序,可在本地计算机(即用户直接使用的计算机)上运行,并处理对这些计算机上的图形卡,显示屏和输入设备(通常是键盘和鼠标)的所有访问。

更多信息在这里

In order to see images, plots and anything displayed on windows on your remote machine you need to connect to it like this:

ssh -X user@hostname

That way you enable the access to the X server. The X server is a program in the X Window System that runs on local machines (i.e., the computers used directly by users) and handles all access to the graphics cards, display screens and input devices (typically a keyboard and mouse) on those computers.

More info here.


PySimpleGUI Python图形用户界面

用于人类的Python图形用户界面

将tkinter、Qt、WxPython和REMI(基于浏览器)GUI框架转换为更简单的界面。通过使用初学者理解的Python核心数据类型(列表和字典)简化了窗口定义。通过将事件处理从基于回调的模型更改为消息传递模型,可以进一步简化

您的代码不是必填项具有面向对象的体系结构,使包可以被更多的受众使用。虽然体系结构很容易理解,但它并不容易理解。必然限制您只处理简单的问题

但是,有些程序并不能很好地适用于PySimpleGUI。根据定义,PySimpleGUI实现底层GUI框架功能的子集。很难准确定义哪些程序适合PySimpleGUI,哪些不适合。这取决于你的计划的细节。复制Excel的每一个细节就是不太适合PySimpleGUI的一个例子

Japanese version of this readme

我想喝杯咖啡!它支持顾问、编辑、域名注册和PySimpleGUI成为一个蓬勃发展的项目所需的许多其他东西。每一笔捐款都是有帮助的,我们需要并感激帮助。


统计数据📈

PyPI统计信息和版本

Tk TK 2.7 Qt WxPython 网络(REMI)

GitHub统计信息

问题 提交活动 星星 文档


什么是PySimpleGUI❓

PySimpleGUI是一个Python包,它允许所有级别的Python程序员创建GUI。您可以使用包含小部件(在PySimpleGUI中称为“元素”)的“布局”来指定GUI窗口。您的布局用于创建一个窗口,该窗口使用4个受支持的框架之一来显示您的窗口并与之交互。支持的框架包括tkinter、Qt、WxPython或REMI。术语“包装器”有时用于这些类型的包裹

您的PySimpleGUI代码比直接使用底层框架编写的代码更简单、更短,因为PySimpleGUI为您实现了大部分“样板代码”。此外,还简化了接口,以便需要尽可能少的代码即可获得所需的结果。根据使用的程序和框架的不同,PySimpleGUI程序可能需要1/2到1/10的代码量才能直接使用其中一个框架创建相同的窗口

虽然目标是封装/隐藏您在其上运行的GUI框架使用的特定对象和代码,但如果需要,您可以直接访问框架的依赖小部件和窗口。如果尚未使用PySimpleGUIAPI公开或访问设置或功能,则不会将您与框架隔开。您可以扩展功能,而无需直接修改PySimpleGUI包本身

弥合“GUI鸿沟”

Python为编程社区带来了大量的人。项目的数量和涉及的领域之广令人难以置信。但通常情况下,除了少数人之外,所有人都无法接触到这些技术。大多数Python程序都是基于“命令行”的。这对于程序员来说不是问题,因为我们都习惯于通过文本界面与计算机交互。虽然程序员对命令行界面没有问题,但大多数“普通人”都有问题。这造成了一个数字鸿沟,一个“GUI鸿沟”

向程序添加GUI可使该程序向更广泛的受众开放。它变得更加平易近人。GUI还可以使与某些程序的交互变得更容易,即使对于那些熟悉命令行界面的人也是如此。最后,有些问题需要GUI


关于我👋

嗨,你们好!我是迈克。你会发现我就在这里,在PySimpleGUI GitHub上,解决问题,不断推动PySimpleGUI向前发展。我把白天、晚上和周末都奉献给了项目和PySimpleGUI用户。我们的成功最终是共享的。当你成功的时候我就成功了

虽然我是Python的新手,但我从70年代就开始编写软件了。我职业生涯的大部分时间都是在硅谷创造产品。我为PySimpleGUI带来了与我开发的公司产品相同的专业精神和奉献精神。你们现在是我的客户了

项目目标🥅

PySimpleGUI项目最重要的两个目标是:

  • 玩得开心
  • 你的成功

有趣的作为一个严肃项目的目标听起来很奇怪,但这是一个严肃的目标。我发现编写这些GUI程序非常有趣。其中一个原因是编写一个完整的解决方案所需的时间非常短。如果我们不享受这个过程,那么就会有人放弃

这里有大量的文档、一本食谱、100个可让您立即运行的演示程序、详细的通话参考资料、YouTube视频、在线特立尼达演示等等。所有人都在努力创造。有趣的经历

你的成功是一个共同的目标。PySimpleGUI是为开发人员构建的。你们是我的偷窥者。看到用户和PySimpleGUI共同努力的结果是意想不到的回报。使用文档和其他材料帮助构建您的应用程序。如果您遇到麻烦,打开Issue on the PySimpleGUI GitHub请看下面关于支撑的部分


教育资源📚

www.PySimpleGUI.org易于记忆,也是文档所在的位置。您将在顶部找到代表几个不同文档的选项卡。文档位于“Read the Docs”(阅读文档)上,因此每个文档都有一个目录,便于搜索

这里有100页的书面文档和100页的示例程序,它们将帮助您非常迅速地发挥作用。使用PySimpleGUI时,您可以在一个下午完成项目,而不需要几天或几周的投资来学习单个GUI包

示例1-单次窗口

这种类型的程序被称为“一次性”窗口,因为该窗口只显示一次,收集的值,然后关闭。它不会像在文字处理器中那样长时间保持打开状态

一个简单的PySimpleGUI程序剖析

PySimpleGUI程序分为5个部分

import PySimpleGUI as sg                        # Part 1 - The import

# Define the window's contents
layout = [  [sg.Text("What's your name?")],     # Part 2 - The Layout
            [sg.Input()],
            [sg.Button('Ok')] ]

# Create the window
window = sg.Window('Window Title', layout)      # Part 3 - Window Defintion
                                                
# Display and interact with the Window
event, values = window.read()                   # Part 4 - Event loop or Window.read call

# Do something with the information gathered
print('Hello', values[0], "! Thanks for trying PySimpleGUI")

# Finish up by removing from the screen
window.close()                                  # Part 5 - Close the Window

代码将生成此窗口


示例2-交互窗口

在本例中,我们的窗口将一直显示在屏幕上,直到用户关闭窗口或单击Quit按钮。您在前面看到的单次窗口与交互式窗口之间的主要区别在于增加了“事件循环”。事件循环从您的窗口读取事件和输入。应用程序的核心位于事件循环中

import PySimpleGUI as sg

# Define the window's contents
layout = [[sg.Text("What's your name?")],
          [sg.Input(key='-INPUT-')],
          [sg.Text(size=(40,1), key='-OUTPUT-')],
          [sg.Button('Ok'), sg.Button('Quit')]]

# Create the window
window = sg.Window('Window Title', layout)

# Display and interact with the Window using an Event Loop
while True:
    event, values = window.read()
    # See if user wants to quit or window was closed
    if event == sg.WINDOW_CLOSED or event == 'Quit':
        break
    # Output a message to the window
    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")

# Finish up by removing from the screen
window.close()

这是示例2生成的窗口

下面是在输入字段中输入值并单击确定按钮后的结果

让我们快速了解一下此示例与单一窗口之间的一些不同之处

首先,您会注意到布局中的不同之处。有两个变化尤其重要。其一是添加了key参数添加到Input元素和一个Text元素。一个key类似于元素的名称。或者,在Python术语中,它就像一个字典键。这个Input元素的键将在稍后的代码中用作字典键

另一个不同之处是增加了这个Text元素:

          [sg.Text(size=(40,1), key='-OUTPUT-')],

有两个参数,即key我们已经调查过了。这个size参数定义元素的大小(以字符为单位)。在这种情况下,我们表示这是Text元素宽40个字符,高1个字符。请注意,没有指定文本字符串,这意味着它将为空。您可以很容易地在创建的窗口中看到此空白行

我们还添加了一个按钮“退出”

Event Loop有我们熟悉的window.read()打电话

以下是Read IF语句:

    if event == sg.WINDOW_CLOSED or event == 'Quit':
        break

这段代码检查用户是否通过单击“X”或单击“Quit”按钮关闭了窗口。如果发生这两种情况中的任何一种,则代码将中断事件循环

如果窗口没有关闭,也没有单击Quit按钮,则继续执行。唯一可能发生的事情是用户单击了“确定”按钮。Event Loop中的最后一条语句如下所示:

    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")

此语句更新Text具有密钥的元素-OUTPUT-用一根绳子。window['-OUTPUT-']查找具有键的元素-OUTPUT-那把钥匙属于我们的空白处Text元素。一旦该元素从查找中返回,那么它的update方法被调用。几乎所有元素都有一个update方法。此方法用于更改元素的值或更改元素的某些配置

如果我们希望文本是黄色的,那么可以通过添加一个text_color参数添加到update方法,以便它读取:

    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI",
                              text_color='yellow')

在添加了text_color参数,这是我们新的结果窗口:

每个元素可用的参数都记录在call reference documentation以及文档字符串。PySimpleGUI提供了大量文档来帮助您了解所有可用的选项。如果您查找update方法,用于Text元素,您将找到该调用的以下定义:

正如您可以看到的,有几件事可以更改为Text元素。调用参考文档是一个有价值的资源,它将使PySimpleGUI、uhm、uhm中的编程变得简单


布局很好笑,哈哈!😆

您的窗口布局是“列表列表”(LOL)。窗户被分解成“行”。窗口中的每一行都会成为布局中的列表。将所有列表连接在一起,您就得到了一个布局。列表列表

这是与以前相同的布局,但增加了一个Text元素添加到每行,以便您可以更轻松地查看行是如何定义的:

layout = [  [sg.Text('Row 1'), sg.Text("What's your name?")],
            [sg.Text('Row 2'), sg.Input()],
            [sg.Text('Row 3'), sg.Button('Ok')] ]

此布局的每一行都是将在窗口的该行上显示的元素列表

与使用其他框架进行GUI编程相比,使用列表定义GUI有一些巨大的优势。例如,您可以使用Python的列表理解功能在一行代码中创建按钮网格

这3行代码:

import PySimpleGUI as sg

layout = [[sg.Button(f'{row}, {col}') for col in range(4)] for row in range(4)]

event, values = sg.Window('List Comprehensions', layout).read(close=True)

生成此窗口,该窗口具有4 x 4网格的按钮:

回想一下,“有趣”是该项目的目标之一。直接将Python强大的基本功能应用于GUI问题非常有趣。创建GUI不需要几页代码,只需要几行(通常是1行)代码

折叠代码

可以将窗口的代码压缩为一行代码。布局定义、窗口创建、显示和数据收集都可以用以下代码行编写:

event, values = sg.Window('Window Title', [[sg.Text("What's your name?")],[sg.Input()],[sg.Button('Ok')]]).read(close=True)

将显示相同的窗口,并返回与显示PySimpleGUI程序部分的示例相同的值。能够用这么少的资源做这么多事情,使您能够快速、轻松地将GUI添加到Python代码中。如果您想要显示某些数据并让用户进行选择,可以在一行代码中完成,而不是在一页代码中完成

通过使用速记别名,您可以使用更少的字符来节省更多的代码空间。所有元素都有一个或多个可以使用的较短名称。例如,Text元素可以简单地写为T这个Input元素可以写成I以及Button作为B这样,您的单行窗口代码就变成了:

event, values = sg.Window('Window Title', [[sg.T("What's your name?")],[sg.I()],[sg.B('Ok')]]).read(close=True)

代码可移植性

PySimpleGUI目前能够在4个Python GUI框架上运行。使用IMPORT语句指定要使用的框架。更改导入,您将更改底层GUI框架。对于某些程序,只需更改import语句即可在不同的GUI框架上运行。在上面的示例中,将导入从PySimpleGUIPySimpleGUIQtPySimpleGUIWxPySimpleGUIWeb将会改变框架

导入语句 结果窗口
PySimpleGUI
PySimpleGUIQt
PySimpleGUIWx
PySimpleGUIWeb

将GUI代码从一个框架移植到另一个框架(例如,将代码从tkinter移植到Qt)通常需要重写代码。PySimpleGUI旨在使您能够轻松地在框架之间移动。有时需要进行一些更改,但目标是以最少的更改获得高度可移植的代码

有些功能(如系统托盘图标)并非在所有端口上都可用。系统托盘图标功能在Qt和WxPython端口上可用。在tkinter上有一个模拟版本。PySimpleGUIWeb端口中不支持系统托盘图标

运行时环境

环境 支持
python Python 3.4+
操作系统 Windows、Linux、Mac
硬件 台式PC、笔记本电脑、Raspberry PI、运行PyDroid3的Android设备
在线 repli.it、Trin ket.com(两者都在浏览器中运行tkinter)
GUI框架 tkinter、pyside 2、WxPython、Remi

集成

在200多个“演示程序”中,您可以找到如何将许多流行的Python包集成到您的GUI中的示例

想要将Matplotlib绘图嵌入到您的窗口中吗?没问题,复制演示代码,立即将您的梦想的Matplotlib绘图放到您的GUI中

这些软件包和更多软件包已准备好放入您的GUI中,因为每个软件包都有演示程序或演示回放:

套餐 描述
Matplotlib 多种类型的图表和曲线图
OpenCV 计算机视觉(通常用于人工智能)
VLC 视频播放
金丝雀 物理引擎
Psutil(伪装) 系统环境统计信息
对虾 Reddit API
JSON PySimpleGUI包装了一个特殊的API来存储“用户设置”
天气 集成多个天气API,制作天气应用程序
米多 MIDI播放
美味的汤 Web抓取(GitHub问题观察器示例)

正在安装💾

安装PySimpleGUI的两种常见方式:

  1. 要从PyPI安装的PIP
  2. 下载文件PySimpleGUI.py并将其放入应用程序的文件夹中

PIP安装和升级

当前建议的调用pip命令的方法是使用Python将其作为模块运行。以前的命令是pippip3是直接放到命令行/shell上的。建议的方式

Windows的初始安装:

python -m pip install PySimpleGUI

Linux和MacOS的初始安装:

python3 -m pip install PySimpleGUI

要使用升级,请执行以下操作pip,您只需向该行添加2个参数--upgrade --no-cache-dir

Windows上的升级安装:

python -m pip install --upgrade --no-cache-dir PySimpleGUI

Linux和MacOS升级:

python3 -m pip install --upgrade --no-cache-dir PySimpleGUI

单文件安装

PySimpleGUI被创建为一个单独的.py文件,因此您可以非常容易地安装它,即使是在不像Raspberry PI那样没有连接到互联网的系统上也是如此。只需将PySimpleGUI.py文件放在与导入它的应用程序相同的文件夹中即可。Python在执行导入时将使用您的本地副本

仅使用.py文件进行安装时,您可以从PyPI获取该文件,或者如果要运行最新的未发布版本,则可以从GitHub下载该文件

要从PyPI安装,请下载控制盘或.gz文件并解压缩该文件。如果将.whl文件重命名为.zip,则可以像打开任何普通zip文件一样打开它。您将在其中一个文件夹中找到PySimpleGUI.py文件。将此文件复制到应用程序的文件夹中,即可完成

PySimpleGUI的tkinter版本的PyPI链接为:https://pypi.org/project/PySimpleGUI/#files

GitHub回购的最新版本可在此处找到:https://raw.githubusercontent.com/PySimpleGUI/PySimpleGUI/master/PySimpleGUI.py

现在你们中的一些人在想,“是的,但是,等等,拥有一个巨大的源文件是一个糟糕的想法”。而且,是的,有时候这可能是个糟糕的主意。在这种情况下,好处远远大于坏处。计算机科学中的许多概念都是权衡或主观的。正如一些人所希望的那样,并不是一切都是黑白分明的。很多时候,问题的答案是“视情况而定”。

画廊🎨

用户提交的GUI以及在GitHub上找到的图形用户界面的更正式图库的工作正在进行中,但在撰写本文时还没有完成。目前有2个地方可以集中查看截图。希望维基或其他机制能够很快发布,以公正地对待人们正在进行的令人惊叹的创作

用户提交的库

第一个是一个user submitted screenshots issue位于GitHub上。这是人们炫耀他们所做的东西的一种非正式方式。这不是很理想,但这是一个开始

海量擦除的GitHub图像

第二个是一个massive gallery of over 3,000 images摘自GitHub上据称使用PySimpleGUI的1000个项目。它没有经过手动过滤,而且有很多早期文档中使用的旧屏幕截图。但是,你可能会在那里发现一些能激发你想象力的东西


PySimpleGUI的用法🔨

以下各节展示了PySimpleGUI的一小部分用法。仅在GitHub上就有1000多个项目使用PySimpleGUI。真正令人惊讶的是,为这么多人打开了这样多的可能性。许多用户谈到以前尝试用Python创建GUI都失败了,但是当他们尝试PySimpleGUI时最终实现了他们的梦想

您的第一个GUI

当然,PySimpleGUI最好的用法之一就是让您为Python项目制作GUI。您可以从请求文件名这样的小操作开始。为此,您只需要对一个名为的“高级函数”进行一次调用popup有各种各样的弹出窗口,有些会收集信息

popup在其自身上会生成一个窗口来显示信息。您可以像打印一样传递多个参数。如果您想要获取信息,那么您将调用以popup_get_比如popup_get_filename

添加一行来获取文件名,而不是在命令行上指定文件名,可以将您的程序转换为“普通人”会感到舒服的程序

import PySimpleGUI as sg

filename = sg.popup_get_file('Enter the file you wish to process')
sg.popup('You entered', filename)

此代码将显示2个弹出窗口。一个用于获取文件名,该文件名可以浏览到输入框或粘贴到输入框中

另一个窗口将输出收集到的内容

雨量计式窗户

GUI框架的默认设置往往不会产生最美观的窗口。但是,只要注意一些细节,就可以做几件事来使窗口看起来很吸引人。PySimpleGUI使操作颜色和功能(如删除标题栏)变得更容易。其结果是,窗口看起来与典型的tkinter窗口不同

下面是一个示例,说明如何创建与Windows中典型的tkinter不同的窗口。在本例中,窗口的标题栏被删除。其结果是,窗口看起来与使用Raineter(桌面小部件程序)时发现的窗口非常相似

您还可以轻松地设置窗口的透明度。下面是相同Raineter样式的更多桌面小部件示例。有些是暗淡的,因为它们是半透明的。

这两种效果(移除标题栏和使窗口半透明)都是通过在创建窗口时设置两个参数来实现的。这是一个PySimpleGUI如何支持轻松访问功能的示例。因为PySimpleGUI代码可以跨GUI框架移植,所以这些相同的参数也适用于其他端口,如Qt

将示例1中的窗口创建调用更改为此行代码会生成类似的半透明窗口:

window = sg.Window('My window', layout, no_titlebar=True, alpha_channel=0.5)

游戏

虽然没有专门编写为游戏开发SDK,但PySimpleGUI使某些游戏的开发变得相当容易

这个象棋程序不仅下棋,而且还集成了Stockfish下棋人工智能

用户已经发布了几个版本的扫雷器

纸牌游戏可以很好地与PySimpleGUI配合使用,因为使用PySimpleGUI操作图像非常简单Graph元素

虽然没有专门编写为游戏开发SDK,但PySimpleGUI使某些游戏的开发变得相当容易

媒体捕获和播放

在GUI中捕获和显示网络摄像头中的视频只需要4行PySimpleGUI代码。更令人印象深刻的是,这4行代码可以与tkinter、qt和Web端口配合使用。您可以使用与使用tkinter显示图像相同的代码在浏览器中实时显示您的网络摄像头。

媒体播放,音频和视频,也可以使用VLC播放器实现。我们为您提供了一个演示应用程序,这样您就可以从一个可操作的示例开始。您在本自述中看到的所有内容都可以作为您自己创作的起点

人工智能

当AI和Python组合在一起时,它们长期以来一直是公认的超级大国。然而,经常缺少的是一种让用户使用GUI熟悉地与这些人工智能算法交互的方式

这些YOLO演示是一个很好的例子,说明了GUI如何在与AI算法的交互中产生巨大的差异。请注意这些窗口底部的两个滑块。这两个滑块更改了YOLO算法使用的几个参数

如果您仅使用命令行调整YOLO演示,则需要在启动应用程序时设置参数一次,查看它们的执行情况、停止应用程序、更改参数,最后使用新参数重新启动应用程序

将这些步骤与使用GUI可以完成的操作进行对比。GUI使您能够实时修改这些参数。您可以立即获得有关它们如何影响算法的反馈

有这么多已经发布的人工智能程序是命令行驱动的。这本身并不是一个巨大的障碍,但是要在命令行上键入/粘贴您想要着色的文件名,运行程序,然后在文件查看器中打开结果输出文件,这已经够“屁股痛”了

图形用户界面有能力改变用户体验,以填补“图形用户界面空白”。在此着色器示例中,用户只需提供一个装满图像的文件夹,然后单击图像即可上色并显示结果

进行着色的程序/算法是免费提供的,随时可以使用。缺少的是GUI可能带来的易用性


作图

使用PySimpleGUI,在GUI中显示数据和与数据交互非常简单。您有几个选择

您可以使用内置的绘图/绘图功能来生成自定义图形。此CPU使用情况监视器使用Graph元素

Matplotlib是Python用户的热门选择。PySimpleGUI可以让您将Matplotlib图形直接嵌入到GUI窗口中。如果您想保留Matplotlib交互功能,甚至可以将交互控件嵌入到您的窗口中

使用PySimpleGUI的颜色主题,您可以生成比大多数人在Matplotlib中创建的默认图表高一个档次的图表


前端

前面提到的“GUI差距”可以使用PySimpleGUI轻松解决。您甚至不需要拥有要添加GUI的程序的源代码。“前端”GUI是一种收集信息,然后将这些信息传递给命令行应用程序的图形用户界面

对于程序员来说,前端GUI是分发用户以前不愿使用的应用程序的绝佳方式,因为他们在使用命令行界面时感到不舒服。对于您无权访问其源代码的命令行程序,这些GUI是您唯一的选择

此示例是名为“Jump Cutter”的程序的前端。通过GUI收集参数,使用这些参数构造命令行,然后使用命令行程序的输出将命令执行到GUI界面。在此示例中,您可以看到执行的命令为黄色


覆盆子猪

因为PySimpleGUI与Python3.4兼容,所以它能够为您的Raspberry PI项目创建GUI。当它与触摸屏搭配使用时,效果特别好。如果PI没有连接监视器,您还可以使用PySimpleGUIWeb来控制PI


轻松访问高级功能

因为很容易访问许多底层GUI框架的功能,所以可以将各种功能拼凑在一起来创建与直接使用GUI框架生成的应用程序完全不同的应用程序

例如,不能使用tkinter或其他GUI包更改标题栏的颜色/外观,但使用PySimpleGUI可以很容易地创建窗口,就好像它们有一个自定义标题栏一样

令人难以置信的是,这个窗口正在使用tkinter来实现类似于屏幕保护程序的功能。

在windows上,tkinter可以从你的应用程序中完全移除背景。再一次,PySimpleGUI使访问这些功能变得微不足道。创建透明窗口需要向创建Window只需更改一个参数,即可生成具有以下效果的简单应用程序:

您可以通过单击全屏窗口与桌面上的所有内容进行交互


主题

厌倦了默认的灰色图形用户界面吗?PySimpleGUI只需调用theme功能。有150多种不同的颜色主题可供您选择:

对于大多数GUI框架,您必须为您创建的每个小部件指定颜色。PySimpleGUI会自动为元素上色,使其与您选择的主题相匹配

若要使用主题,请调用theme在创建窗口之前使用主题名称函数。您可以添加空格以提高可读性。要将主题设置为“Dark Grey 9”,请执行以下操作:

import PySimpleGUI as sg

sg.theme('dark grey 9')

这一行代码完全更改了窗口的外观:

主题更改了背景、文本、输入背景、输入文本和按钮颜色的颜色。在其他GUI包中,要像这样更改配色方案,您需要单独指定每个小部件的颜色,这需要对代码进行大量更改


支持💪

你的第一站应该是documentationdemo programs如果您还有问题或需要帮助。没问题。您可以免费获得帮助。简单地说file an Issue在PySimpleGUI GitHub资源库上,您将获得帮助

几乎所有的软件公司都有一个随附错误报告的表格。这是一笔不错的交易。填写表格,即可获得免费软件支持。此信息可帮助您有效地获得答案

除了请求PySimpleGUI和底层GUI框架的版本号等信息外,还向您提供了一份可能帮助您解决问题的项目清单

请填写这张表格你可能会觉得这毫无意义。这可能会感到痛苦,尽管只需要片刻的时间。它可以帮助您更快地获得解决方案。如果它不是帮助你快速回复和修复的有用和必要的信息,你就不会被要求填写它。“帮我帮你”

支持

我们非常感谢对该项目的财政支持。老实说,经济上的帮助是需要的。光是开着灯就很贵。域名注册、一长串的订阅、咨询帮助等,很快就会累积成一笔可观的经常性成本

PySimpleGUI的创建成本并不低。虽然这是一项热爱的劳动,但在几年的时间里,它是非常辛苦的,而且相当多的投资被投入,并将继续投入,创造出你今天看到的东西。

PySimpleGUI拥有开放源码许可,如果它能保持这种状态,那就太好了。如果您或您的公司(特别是如果您在公司中使用PySimpleGUI)通过使用PySimpleGUI获得经济利益,则您有能力延长您和其他用户的项目生命周期

给我买咖啡

给我买杯咖啡是公开支持开发者的一种很好的方式。它快速、简单,并且您的贡献会被记录下来,这样其他人就可以看到您是PySimpleGUI的支持者。您也可以选择将您的捐赠设置为私人捐赠

GitHub赞助商

这个GitHub recurring sponsorship就是如何在持续的基础上以不同级别的支持来赞助该项目。它是指有多少开放源码开发者能够获得企业级赞助

我们将非常感谢您在财政上对该项目的帮助。作为一名开放源码开发人员在财务上具有挑战性。YouTube视频创建者能够通过制作视频谋生。对于开源开发人员来说,这并不容易

谢谢你的谢谢

对于所有帮助过的人,无论以什么方式,我都非常非常感激

即使花点时间说一句“谢谢”也有帮助,而且你们中的很多人都这么做了。事实上,这是一个令人惊叹的数字。我珍视这些感谢,仅从文字中就能找到灵感。每一条信息都是一种小小的推动。它增加了一点能量,保持了整个项目的势头。我非常感谢所有以任何形式帮助过我的人

贡献👷

虽然PySimpleGUI目前是在开放源码许可下获得许可的,但项目本身的结构类似于专有产品。不接受拉取请求

对您来说,贡献代码的最佳方式之一是编写和发布应用程序。用户从看到其他用户构建的内容中获得灵感。这里有一组您可以执行的简单步骤–创建一个GitHub repo,发布代码,并在repo的自述文件中包含一个屏幕截图。然后回到PySimpleGUI资源库,在第10期或项目的Wiki中发布一个屏幕截图

如果缺少您需要的功能,或者您有要建议的增强功能,那么open an Issue

特别感谢🙏

这个版本的PySimpleGUI自述文件如果没有@M4cs他是一位出色的开发人员,自项目启动以来一直是PySimpleGUI的支持者。@israel-dryer是另一个长期的支持者,他已经编写了几个PySimpleGUI程序,推动了包功能的极限。以色列制造了唯一一艘使用图像作为棋盘的扫雷舰。@jason990420当他发布了第一款使用PySimpleGUI的纸牌游戏(如上图所示),以及第一款使用PySimpleGUI制作的扫雷舰游戏时,许多人都大吃一惊。@Chr0nicT是我合作过的最年轻的项目开发人员。这孩子经常让我吃惊。请求一种功能,比如PySimpleGUI GitHub从错误检查机器人发出的问题,不管涉及到什么技术,它都会简单地发生。我很幸运,我们被介绍认识了。总有一天他会被带走,但在那之前我们都受益于他的才华。日文版的自述文件在以下方面的帮助下得到了极大的改进@okajun35@nngogol对该项目产生了非常大的影响,在最初发布的第一年就参与了PySimpleGUI。他编写了一个设计器,提出了熟悉的窗口[键]查找语法,编写了创建文档的工具,设计了第一组文档字符串,以及使用PySimpleGUI代码本身生成在线文档的工具。如果没有这些人的帮助,PySimpleGUI就不会有今天的成就

使用PySimpleGUI的2200多个GitHub回购也应该得到“谢谢”,因为它是这就是推动这个项目引擎的灵感

隔夜在推特上发帖的海外用户是开始一天PySimpleGUI工作的电光。它们一直是让开发引擎启动并准备好每天运行的正能量源泉。为了表示感谢,本自述文件已翻译为Japanese

你们都是开放源码开发人员所希望的最好的用户社区

©版权所有2021 PySimpleGUI

如何使用Python创建可直接执行的跨平台GUI应用程序?

问题:如何使用Python创建可直接执行的跨平台GUI应用程序?

Python可在多种平台上工作,并且可用于桌面和Web应用程序,因此,我得出结论,有一种方法可以将其编译为Mac,Windows和Linux的可执行文件。

问题是我不知道从哪里开始或如何用它编写GUI,请问有人可以向我指出正确的方向吗?

Python works on multiple platforms and can be used for desktop and web applications, thus I conclude that there is some way to compile it into an executable for Mac, Windows and Linux.

The problem being I have no idea where to start or how to write a GUI with it, can anybody shed some light on this and point me in the right direction please?


回答 0

首先,您将需要一些具有Python绑定的GUI库,然后(如果需要)一些程序,它将Python脚本转换为独立的可执行文件。

具有Python绑定的跨平台GUI库(Windows,Linux,Mac)

当然,有很多,但是我在野外看到的最受欢迎的是:

完整列表位于http://wiki.python.org/moin/GuiProgramming

单个可执行文件(所有平台)

  • PyInstaller-最活跃的(也可以与一起使用PyQt
  • fbs-如果您在上方选择了Qt

单个可执行文件(Windows)

单个可执行文件(Linux)

  • 冻结 -与py2exe相同,但以Linux平台为目标

单个可执行文件(Mac)

  • py2app-再次像py2exe一样工作,但以Mac OS为目标

First you will need some GUI library with Python bindings and then (if you want) some program that will convert your python scripts into standalone executables.

Cross-platform GUI libraries with Python bindings (Windows, Linux, Mac)

Of course, there are many, but the most popular that I’ve seen in wild are:

Complete list is at http://wiki.python.org/moin/GuiProgramming

Single executable (all platforms)

  • PyInstaller – the most active(Could also be used with PyQt)
  • fbs – if you chose Qt above

Single executable (Windows)

  • py2exe – used to be the most popular

Single executable (Linux)

  • Freeze – works the same way like py2exe but targets Linux platform

Single executable (Mac)

  • py2app – again, works like py2exe but targets Mac OS

回答 1

另一个系统(尚未在接受的答案中提及)是PyInstaller,该系统在py2exe无法使用时可用于我的PyQt项目。我发现它更易于使用。

http://www.pyinstaller.org/

Pyinstaller基于Gordon McMillan的Python Installer。不再可用。

Another system (not mentioned in the accepted answer yet) is PyInstaller, which worked for a PyQt project of mine when py2exe would not. I found it easier to use.

http://www.pyinstaller.org/

Pyinstaller is based on Gordon McMillan’s Python Installer. Which is no longer available.


回答 2

pyfree.py是py2exe的替代工具,它可以为Windows和Linux生成可执行文件。它比py2exe更新,并且可以很好地处理鸡蛋。我发现它无需配置即可针对多种应用程序神奇地工作得更好。

An alternative tool to py2exe is bbfreeze which generates executables for windows and linux. It’s newer than py2exe and handles eggs quite well. I’ve found it magically works better without configuration for a wide variety of applications.


回答 3

还有PyGTK,它基本上是Gnome Toolkit的Python包装器。我发现比起Tkinter来,我的想法更容易缠起来,这是因为以前几乎没有GUI编程知识。它工作得很好,并且有一些很好的教程。不幸的是,目前还没有适用于Windows的Python 2.6安装程序,并且可能有一段时间没有安装。

There’s also PyGTK, which is basically a Python wrapper for the Gnome Toolkit. I’ve found it easier to wrap my mind around than Tkinter, coming from pretty much no knowledge of GUI programming previously. It works pretty well and has some good tutorials. Unfortunately there isn’t an installer for Python 2.6 for Windows yet, and may not be for a while.


回答 4

由于默认情况下现在几乎在所有非Windows操作系统上都安装了python,因此您真正需要确保的唯一事情就是已安装了您使用的所有非标准库。

话虽如此,有可能构建包括python解释器和您使用的任何库的可执行文件。但是,这可能会创建一个大型可执行文件。

MacOS X甚至在Xcode IDE中提供了对创建完整独立GUI应用程序的支持。这些可以由运行OS X的任何用户运行。

Since python is installed on nearly every non-Windows OS by default now, the only thing you really need to make sure of is that all of the non-standard libraries you use are installed.

Having said that, it is possible to build executables that include the python interpreter, and any libraries you use. This is likely to create a large executable, however.

MacOS X even includes support in the Xcode IDE for creating full standalone GUI apps. These can be run by any user running OS X.


回答 5

对于GUI本身:

PyQT几乎是参考。

开发快速用户界面的另一种方法是编写一个Web应用程序,使其在本地运行并在浏览器中显示该应用程序。

另外,如果您选择lubos hasko建议的Tkinter选项,则可能要尝试Portablepy使您的应用程序在Windows环境下运行而无需使用Python。

For the GUI itself:

PyQT is pretty much the reference.

Another way to develop a rapid user interface is to write a web app, have it run locally and display the app in the browser.

Plus, if you go for the Tkinter option suggested by lubos hasko you may want to try portablepy to have your app run on Windows environment without Python.


回答 6

我不确定这是否是最好的方法,但是当我在Windows上部署Ruby GUI应用程序(不是Python,但就.exe而言具有相同的“问题”)时,我只写了一个C#中的短启动程序,它调用我的主脚本。它编译为可执行文件,然后有一个应用程序可执行文件。

I’m not sure that this is the best way to do it, but when I’m deploying Ruby GUI apps (not Python, but has the same “problem” as far as .exe’s are concerned) on Windows, I just write a short launcher in C# that calls on my main script. It compiles to an executable, and I then have an application executable.


回答 7

# I'd use tkinter for python 3

import tkinter

tk = tkinter.Tk()
tk.geometry("400x300+500+300")
l = Label(tk,text="")
l.pack()
e = Entry(tk)
e.pack()

def click():
    e['text'] = 'You clicked the button'

b = Button(tk,text="Click me",command=click)
b.pack()

tk.mainloop()

# After this I would you py2exe
# search for the use of this module on stakoverflow
# otherwise I could edit this to let you know how to do it

py2exe

然后,您应该使用py2exe,例如,将运行该应用程序所需的所有文件都放入一个文件夹中,即使用户的计算机上没有python(我在说的是Windows …对于Apple os来说也没有必要我认为,由于可执行文件带有python,因此无需安装它。

建立这个档案

1)创建一个setup.py

使用此代码:

from distutils.core import setup
import py2exe

setup(console=['l4h.py'])

将其保存在文件夹中

2)将您的程序放在setup.py的同一文件夹中,在该文件夹中放入要使其可分发的程序:es:l4h.py

ps:更改文件名(从l4h更改为您想要的任何名称,这是一个示例)

3)从该文件夹运行cmd(在该文件夹上,右键单击+ Shift并在此处选择启动cmd)
4)在cmd:> python setup.py py2exe中编写
5)在dist文件夹中,您需要所有文件
6)您可以压缩并分发

py安装程序

从cmd安装

**

点安装pyinstaller

**

从文件所在的文件夹中的cmd运行它

**

pyinstaller file.py

**

# I'd use tkinter for python 3

import tkinter

tk = tkinter.Tk()
tk.geometry("400x300+500+300")
l = Label(tk,text="")
l.pack()
e = Entry(tk)
e.pack()

def click():
    e['text'] = 'You clicked the button'

b = Button(tk,text="Click me",command=click)
b.pack()

tk.mainloop()

# After this I would you py2exe
# search for the use of this module on stakoverflow
# otherwise I could edit this to let you know how to do it

py2exe

Then you should use py2exe, for example, to bring in one folder all the files needed to run the app, even if the user has not python on his pc (I am talking of windows… for the apple os there is no need of an executable file, I think, as it come with python in it without any need of installing it.

Create this file

1) Create a setup.py

with this code:

from distutils.core import setup
import py2exe

setup(console=['l4h.py'])

save it in a folder

2) Put your program in the same folder of setup.py put in this folder the program you want to make it distribuitable: es: l4h.py

ps: change the name of the file (from l4h to anything you want, that is an example)

3) Run cmd from that folder (on the folder, right click + shift and choose start cmd here)
4) write in cmd:>python setup.py py2exe
5) in the dist folder there are all the files you need
6) you can zip it and distribute it

Pyinstaller

Install it from cmd

**

pip install pyinstaller

**

Run it from the cmd from the folder where the file is

**

pyinstaller file.py

**


回答 8

PySimpleGUI包装了tkinter并在Python 3和2.7上运行。它还可以在Qt,WxPython和Web浏览器中运行,并且所有平台都使用相同的源代码。

您可以创建自定义GUI,以利用在tkinter中找到的所有相同窗口小部件(滑块,复选框,单选按钮等)。该代码往往非常紧凑和可读。

#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
    import PySimpleGUI as sg
else:
    import PySimpleGUI27 as sg

layout = [[ sg.Text('My Window') ],
          [ sg.Button('OK')]]

window = sg.Window('My window').Layout(layout)
button, value = window.Read()

PySimpleGUI文档中所述,要生成.EXE文件,请运行:

pyinstaller -wF MyGUIProgram.py

PySimpleGUI wraps tkinter and works on Python 3 and 2.7. It also runs on Qt, WxPython and in a web browser, using the same source code for all platforms.

You can make custom GUIs that utilize all of the same widgets that you find in tkinter (sliders, checkboxes, radio buttons, …). The code tends to be very compact and readable.

#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
    import PySimpleGUI as sg
else:
    import PySimpleGUI27 as sg

layout = [[ sg.Text('My Window') ],
          [ sg.Button('OK')]]

window = sg.Window('My window').Layout(layout)
button, value = window.Read()

As explained in the PySimpleGUI Documentation, to build the .EXE file you run:

pyinstaller -wF MyGUIProgram.py


回答 9

您不需要编译为Mac / Windows / Linux python。它是一种解释语言,因此您只需要在您选择的系统上安装Python解释器即可(这三个平台都可用)。

至于可以跨平台工作的GUI库,Python的Tk / Tcl小部件库可以很好地工作,我相信跨平台就足够了。

Tkinter是Tk / Tcl的python接口

从python项目网页:

Tkinter不是唯一的Python GuiProgramming工具包。但是,它是最常用的一种,并且几乎是唯一可以在Unix,Mac和Windows之间移植的一种

You don’t need to compile python for Mac/Windows/Linux. It is an interpreted language, so you simply need to have the Python interpreter installed on the system of your choice (it is available for all three platforms).

As for a GUI library that works cross platform, Python’s Tk/Tcl widget library works very well, and I believe is sufficiently cross platform.

Tkinter is the python interface to Tk/Tcl

From the python project webpage:

Tkinter is not the only GuiProgramming toolkit for Python. It is however the most commonly used one, and almost the only one that is portable between Unix, Mac and Windows


回答 10

您可以appJar用于基本的GUI开发。

from appJar import gui

num=1

def myfcn(btnName):   
    global num
    num +=1
    win.setLabel("mylabel", num)

win = gui('Test')

win.addButtons(["Set"],  [myfcn])
win.addLabel("mylabel", "Press the Button")

win.go()

请参阅appJar网站上的文档

pip install appjar通过命令行进行安装。

You can use appJar for basic GUI development.

from appJar import gui

num=1

def myfcn(btnName):   
    global num
    num +=1
    win.setLabel("mylabel", num)

win = gui('Test')

win.addButtons(["Set"],  [myfcn])
win.addLabel("mylabel", "Press the Button")

win.go()

See documentation at appJar site.

Installation is made with pip install appjar from command line.


回答 11

!!! KIVY !!!

看到没有人提到Kivy,我感到非常惊讶!!!

我曾经使用Tkinter进行过一个项目,尽管他们确实提倡它有很多改进,但仍然给我Windows 98的感觉,所以我改用Kivy

我一直在关注一个教程系列如果有帮助, …

只是为了了解一下奇异果的外观,请看以下内容(我正在从事的项目):

而且我现在差不多已经工作了一个星期了!您问Kivy有什么好处?检查一下一下

我之所以选择它,是因为它的外观以及它也可以在移动设备中使用。

!!! KIVY !!!

I was amazed seeing that no one mentioned Kivy!!!

I have once done a project using Tkinter, although they do advocate that it has improved a lot, it still gives me a feel of windows 98, so I switched to Kivy.

I have been following a tutorial series if it helps…

Just to give an idea of how kivy looks, see this (The project I am working on):

And I have been working on it for barely a week now ! The benefits for Kivy you ask? Check this

The reason why I chose this is, its look and that it can be used in mobile as well.


Tqdm-一个用于Python和CLI的快速、可扩展的进度条

TQDM

tqdm派生自阿拉伯语单词塔卡杜姆(تقدّم)可以是“进步”的意思,在西班牙语中是“我非常爱你”的缩写(德马西亚多)

立即使您的循环显示一个智能进度表-只需用tqdm(iterable),你就完了!

from tqdm import tqdm
for i in tqdm(range(10000)):
    ...

76%|████████████████████████        | 7568/10000 [00:33<00:10, 229.00it/s]

trange(N)还可以用作以下操作的便捷快捷方式tqdm(range(N))

它还可以作为带有管道的模块执行:

$ seq 9999999 | tqdm --bytes | wc -l
75.2MB [00:00, 217MB/s]
9999999

$ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
    > backup.tgz
 32%|██████████▍                      | 8.89G/27.9G [00:42<01:31, 223MB/s]

开销很低–每次迭代约60 ns(80 ns,tqdm.gui),并针对性能回归进行单元测试。相比之下,久负盛名的ProgressBar具有800 ns/ITER开销

除了开销低之外,tqdm使用智能算法预测剩余时间并跳过不必要的迭代显示,这在大多数情况下可以忽略不计的开销

tqdm可在任何平台(Linux、Windows、Mac、FreeBSD、NetBSD、Solaris/SunOS)、任何控制台或GUI中运行,并且与IPython/Jupyter笔记本电脑也很友好

tqdm不需要任何依赖项(甚至不需要curses!),只有Python和一个支持carriage return \rline feed \n控制字符


Installation

Latest PyPI stable release


pip install tqdm

Latest development release on GitHub

拉入并安装预发行版devel分支机构:

pip install "git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm"

Latest Conda release

conda install -c conda-forge tqdm

Latest Snapcraft release

有3个频道可供选择:

snap install tqdm  # implies --stable, i.e. latest tagged release
snap install tqdm  --candidate  # master branch
snap install tqdm  --edge  # devel branch

请注意,snap二进制文件仅供CLI使用(而不是import-可用),并自动设置bash制表符完成

Latest Docker release

docker pull tqdm/tqdm
docker run -i --rm tqdm/tqdm --help

Other

还有其他(非官方的)地方tqdm可以下载,特别是对于CLI使用:


Changelog

所有更改的列表可在GitHub的版本上获得:,在wiki,或在website

Usage

tqdm是非常多才多艺的,可以有多种用途。下面给出了三个主要的原因

Iterable-based

包装tqdm()围绕任何可迭代:

from tqdm import tqdm
from time import sleep

text = ""
for char in tqdm(["a", "b", "c", "d"]):
    sleep(0.25)
    text = text + char

trange(i)是一个特殊的优化实例tqdm(range(i))

from tqdm import trange

for i in trange(100):
    sleep(0.01)

循环外的实例化允许手动控制tqdm()

pbar = tqdm(["a", "b", "c", "d"])
for char in pbar:
    sleep(0.25)
    pbar.set_description("Processing %s" % char)

Manual

手动控制tqdm()使用with声明:

with tqdm(total=100) as pbar:
    for i in range(10):
        sleep(0.1)
        pbar.update(10)

如果可选变量total(或使用可迭代的len()),则显示预测统计信息

with也是可选的(您可以直接将tqdm()赋给一个变量,但在这种情况下,不要忘记delclose()在结尾处:

pbar = tqdm(total=100)
for i in range(10):
    sleep(0.1)
    pbar.update(10)
pbar.close()

Module

也许最奇妙的用法就是tqdm是在脚本中还是在命令行上。简单地插入tqdm(或python -m tqdm)之间的管道将通过所有stdinstdout将进度打印到时stderr

下面的示例演示了如何计算当前目录中所有Python文件中的行数,其中包括计时信息

$ time find . -name '*.py' -type f -exec cat \{} \; | wc -l
857365

real    0m3.458s
user    0m0.274s
sys     0m3.325s

$ time find . -name '*.py' -type f -exec cat \{} \; | tqdm | wc -l
857366it [00:03, 246471.31it/s]
857365

real    0m3.585s
user    0m0.862s
sys     0m3.358s

请注意,通常的论点是tqdm也可以指定

$ find . -name '*.py' -type f -exec cat \{} \; |
    tqdm --unit loc --unit_scale --total 857366 >> /dev/null
100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s]

备份一个大目录吗?

$ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
  > backup.tgz
 44%|██████████████▊                   | 153M/352M [00:14<00:18, 11.0MB/s]

这还可以进一步美化:

$ BYTES="$(du -sb docs/ | cut -f1)"
$ tar -cf - docs/ \
  | tqdm --bytes --total "$BYTES" --desc Processing | gzip \
  | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \
  > ~/backup.tgz
Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s]
Compressed:  42%|█████████▎            | 148M/352M [00:14<00:19, 10.9MB/s]

或使用7-zip在文件级完成:

$ 7z a -bd -r backup.7z docs/ | grep Compressing \
  | tqdm --total $(find docs/ -type f | wc -l) --unit files \
  | grep -v Compressing
100%|██████████████████████████▉| 15327/15327 [01:00<00:00, 712.96files/s]

已经输出基本进度信息的现有CLI程序将受益于tqdm%s--update--update_to标志:

$ seq 3 0.1 5 | tqdm --total 5 --update_to --null
100%|████████████████████████████████████| 5.0/5 [00:00<00:00, 9673.21it/s]
$ seq 10 | tqdm --update --null  # 1 + 2 + ... + 10 = 55 iterations
55it [00:00, 90006.52it/s]

FAQ and Known Issues

最常见的问题与多行输出过多有关,而不是整齐的单行进度条

  • 一般控制台:需要回车支持(CR\r)
  • 嵌套进度条:
    • 一般控制台:需要支持将光标上移到上一行。例如,IDLEConEmuPyCharm(亦请参阅herehere,以及here)缺乏全力支持
    • Windows:另外可能需要Python模块colorama要确保嵌套条位于各自的行内,请执行以下操作
  • Unicode:
    • 报告支持Unicode的环境将具有稳定、平滑的进度条。后备方案是一个ascii-仅限栏
    • Windows控制台通常只部分支持Unicode,因此often require explicit ascii=True(亦请参阅here)。这是因为普通宽度的Unicode字符错误地显示为“宽”,或者某些Unicode字符未呈现
  • 包裹生成器:
    • 生成器包装函数倾向于隐藏可迭代的长度tqdm不会
    • 替换tqdm(enumerate(...))使用enumerate(tqdm(...))tqdm(enumerate(x), total=len(x), ...)同样的道理也适用于numpy.ndenumerate
    • 替换tqdm(zip(a, b))使用zip(tqdm(a), b)甚至是zip(tqdm(a), tqdm(b))
    • 同样的道理也适用于itertools
    • 一些有用的方便函数可以在下面的tqdm.contrib
  • Hanging pipes in python2:使用时tqdm在CLI上,您可能需要使用Python 3.5+才能正确缓冲
  • No intermediate output in docker-compose:使用docker-compose run而不是docker-compose uptty: true

如果您遇到任何其他困难,请浏览并归档

Documentation

(自2016年5月19日起)

class tqdm():
  """
  Decorate an iterable object, returning an iterator which acts exactly
  like the original iterable, but prints a dynamically updating
  progressbar every time a value is requested.
  """

  def __init__(self, iterable=None, desc=None, total=None, leave=True,
               file=None, ncols=None, mininterval=0.1,
               maxinterval=10.0, miniters=None, ascii=None, disable=False,
               unit='it', unit_scale=False, dynamic_ncols=False,
               smoothing=0.3, bar_format=None, initial=0, position=None,
               postfix=None, unit_divisor=1000):

Parameters

  • 可迭代的:可迭代,可选
    可重复使用进度条进行装饰。保留为空可手动管理更新
  • 说明:字符串,可选
    进度栏的前缀
  • 总计:整型或浮点型,可选
    预期迭代次数。如果未指定,则在可能的情况下使用len(可迭代)。如果为FLOAT(“inf”)或作为最后手段,则仅显示基本进度统计信息(无ETA,无进度条)。如果gui为True并且此参数需要后续更新,请指定初始任意大正数,例如9e9
  • 离开吧:布尔值,可选
    如果为[default:true],则在迭代终止时保留进度条的所有痕迹。如果None,只有在以下情况下才会离开position0
  • 文件:io.TextIOWrapperio.StringIO,可选
    指定输出进度消息的位置(默认值:sys.stderr)。用途file.write(str)file.flush()方法。有关编码信息,请参见write_bytes
  • 乙二醇:整型,可选
    整个输出消息的宽度。如果指定,则动态调整进度条的大小以保持在此范围内。如果未指定,则尝试使用环境宽度。后备宽度为10米,对计数器和统计数据没有限制。如果为0,则不打印任何仪表(仅打印统计数据)
  • 最小间隔:浮动,可选
    最小进度显示更新间隔[默认值:0.1]秒
  • 最大间隔:浮动,可选
    最大进度显示更新间隔[默认值:10]秒。自动调整miniters与…相对应mininterval在长时间显示更新延迟之后。仅在以下情况下才有效dynamic_miniters或者启用了监视器线程
  • 小型矿车:整型或浮点型,可选
    最小进度显示更新间隔,以迭代为单位。如果为0且dynamic_miniters,将自动调整为等于mininterval(CPU效率更高,适用于紧密循环)。如果>0,将跳过指定迭代次数的显示。调整此选项,然后mininterval以获得非常有效的循环。如果快速迭代和慢速迭代(网络、跳过项目等)的进度都不稳定,则应该将miniters设置为1
  • ASCII:布尔值或字符串,可选
    如果未指定或为False,则使用Unicode(平滑块)填充仪表。备用方法是使用ASCII码字符“123456789#”
  • 禁用:布尔值,可选
    是否禁用整个进度栏包装[默认值:false]。如果设置为None,则在非TTY上禁用
  • 单位:字符串,可选
    将用于定义每个迭代的单位的字符串[默认值:it]
  • 单位_刻度:Bool、int或Float,可选
    如果为1或True,则迭代次数将自动减少/缩放,并将添加遵循国际单位制标准的公制前缀(千、兆等)[默认值:FALSE]。如果有任何其他非零数,将缩放totaln
  • 动态参数(_N):布尔值,可选
    如果设置,则会不断更改ncolsnrows到环境(允许调整窗口大小)[默认值:FALSE]
  • 平滑:浮动,可选
    速度估计的指数移动平均平滑系数(在GUI模式中忽略)。范围从0(平均速度)到1(当前/瞬时速度)[默认值:0.3]
  • 条形图格式(_F):字符串,可选
    指定自定义条形字符串格式。可能会影响性能。[默认值:‘{l_bar}{bar}{r_bar}’],其中l_bar=‘{desc}:{percentage:3.0f}%|’,r_bar=‘|{n_fmt}/{total_fmt}[{elapsed}<{reaving},’{rate_fmt}{postfix}]‘’可能的变量:l_bar,bar,r_bar,n,n_fmt,total,total_fmt,百分比,已用rate_noinv、rate_noinv_fmt、rate_inv、rate_inv_fmt、后缀、unit_ditor、剩余、剩余_s、eta。请注意,如果{desc}为空,则会在{desc}之后自动删除尾随的“:”
  • 首字母:整型或浮点型,可选
    初始计数器值。重新启动进度条时非常有用[默认值:0]。如果使用浮点,请考虑指定{n:.3f}或类似于bar_format,或指定unit_scale
  • 职位:整型,可选
    如果未指定,请指定自动打印此条形图的行偏移量(从0开始)。一次管理多个条形图非常有用(例如,从线程)
  • 后缀:DICT或*,可选
    指定要在条末尾显示的其他统计信息。呼叫set_postfix(**postfix)如果可能(DICT)
  • 单位_除数:浮动,可选
    [默认值:1000],除非忽略unit_scale是真的吗?
  • 写入字节(_B):布尔值,可选
    如果(默认值:无)和file未指定,则将使用Python 2写入字节。如果True还将写入字节。在所有其他情况下,将默认为Unicode
  • 锁定参数(_A):元组,可选
    已传递给refresh用于中间输出(初始化、迭代和更新)
  • n行:整型,可选
    屏幕高度。如果指定,则隐藏此边界之外的嵌套条。如果未指定,则尝试使用环境高度。退而求其次是20
  • 颜色:字符串,可选
    条形图颜色(例如“绿色”、“#00ff00”)
  • 延迟:浮动,可选
    在经过[默认值:0]秒之前不显示

Extra CLI Options

  • 神志不清:CHR,可选
    分隔字符[默认值:‘n’]。使用“0”表示NULL。注:在Windows系统上,Python将‘n’转换为‘rn’
  • buf_size:整型,可选
    字符串缓冲区大小(以字节为单位)[默认值:256]在以下情况下使用delim已指定
  • 字节数:布尔值,可选
    如果为true,将计算字节数,忽略delim和Defaultunit_scale为了真的,unit_divisor设置为1024,并且unit到“B”
  • T形三通:布尔值,可选
    如果为true,则通过stdin对两个人都是stderrstdout
  • 更新:布尔值,可选
    如果为true,则将输入视为新经过的迭代,即要传递到的数字update()请注意,这很慢(~2e5 it/s),因为每个输入都必须解码为数字
  • 更新目标(_T):布尔值,可选
    如果为true,则将输入视为已用迭代总数,即要分配给的数字self.n请注意,这很慢(~2e5 it/s),因为每个输入都必须解码为数字
  • 空:布尔值,可选
    如果为true,将丢弃输入(无标准输出)
  • 人工路径:字符串,可选
    要安装tqdm手册页的目录
  • 压缩路径:字符串,可选
    放置tqdm完成的目录
  • 日志:字符串,可选
    严重|致命|错误|警告(ING)|[默认值:‘INFO’]|DEBUG|NOTSET

Returns

  • 输出:修饰迭代器
class tqdm():
  def update(self, n=1):
      """
      Manually update the progress bar, useful for streams
      such as reading files.
      E.g.:
      >>> t = tqdm(total=filesize) # Initialise
      >>> for current_buffer in stream:
      ...    ...
      ...    t.update(len(current_buffer))
      >>> t.close()
      The last line is highly recommended, but possibly not necessary if
      ``t.update()`` will be called in such a way that ``filesize`` will be
      exactly reached and printed.

      Parameters
      ----------
      n  : int or float, optional
          Increment to add to the internal counter of iterations
          [default: 1]. If using float, consider specifying ``{n:.3f}``
          or similar in ``bar_format``, or specifying ``unit_scale``.

      Returns
      -------
      out  : bool or None
          True if a ``display()`` was triggered.
      """

  def close(self):
      """Cleanup and (if leave=False) close the progressbar."""

  def clear(self, nomove=False):
      """Clear current bar display."""

  def refresh(self):
      """
      Force refresh the display of this bar.

      Parameters
      ----------
      nolock  : bool, optional
          If ``True``, does not lock.
          If [default: ``False``]: calls ``acquire()`` on internal lock.
      lock_args  : tuple, optional
          Passed to internal lock's ``acquire()``.
          If specified, will only ``display()`` if ``acquire()`` returns ``True``.
      """

  def unpause(self):
      """Restart tqdm timer from last print time."""

  def reset(self, total=None):
      """
      Resets to 0 iterations for repeated use.

      Consider combining with ``leave=True``.

      Parameters
      ----------
      total  : int or float, optional. Total to use for the new bar.
      """

  def set_description(self, desc=None, refresh=True):
      """
      Set/modify description of the progress bar.

      Parameters
      ----------
      desc  : str, optional
      refresh  : bool, optional
          Forces refresh [default: True].
      """

  def set_postfix(self, ordered_dict=None, refresh=True, **tqdm_kwargs):
      """
      Set/modify postfix (additional stats)
      with automatic formatting based on datatype.

      Parameters
      ----------
      ordered_dict  : dict or OrderedDict, optional
      refresh  : bool, optional
          Forces refresh [default: True].
      kwargs  : dict, optional
      """

  @classmethod
  def write(cls, s, file=sys.stdout, end="\n"):
      """Print a message via tqdm (without overlap with bars)."""

  @property
  def format_dict(self):
      """Public API for read-only member access."""

  def display(self, msg=None, pos=None):
      """
      Use ``self.sp`` to display ``msg`` in the specified ``pos``.

      Consider overloading this function when inheriting to use e.g.:
      ``self.some_frontend(**self.format_dict)`` instead of ``self.sp``.

      Parameters
      ----------
      msg  : str, optional. What to display (default: ``repr(self)``).
      pos  : int, optional. Position to ``moveto``
        (default: ``abs(self.pos)``).
      """

  @classmethod
  @contextmanager
  def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs):
      """
      stream  : file-like object.
      method  : str, "read" or "write". The result of ``read()`` and
          the first argument of ``write()`` should have a ``len()``.

      >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj:
      ...     while True:
      ...         chunk = fobj.read(chunk_size)
      ...         if not chunk:
      ...             break
      """

  @classmethod
  def pandas(cls, *targs, **tqdm_kwargs):
      """Registers the current `tqdm` class with `pandas`."""

def trange(*args, **tqdm_kwargs):
    """
    A shortcut for `tqdm(xrange(*args), **tqdm_kwargs)`.
    On Python3+, `range` is used instead of `xrange`.
    """

Convenience Functions

def tqdm.contrib.tenumerate(iterable, start=0, total=None,
                            tqdm_class=tqdm.auto.tqdm, **tqdm_kwargs):
    """Equivalent of `numpy.ndenumerate` or builtin `enumerate`."""

def tqdm.contrib.tzip(iter1, *iter2plus, **tqdm_kwargs):
    """Equivalent of builtin `zip`."""

def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):
    """Equivalent of builtin `map`."""

Submodules

class tqdm.notebook.tqdm(tqdm.tqdm):
    """IPython/Jupyter Notebook widget."""

class tqdm.auto.tqdm(tqdm.tqdm):
    """Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`."""

class tqdm.asyncio.tqdm(tqdm.tqdm):
  """Asynchronous version."""
  @classmethod
  def as_completed(cls, fs, *, loop=None, timeout=None, total=None,
                   **tqdm_kwargs):
      """Wrapper for `asyncio.as_completed`."""

class tqdm.gui.tqdm(tqdm.tqdm):
    """Matplotlib GUI version."""

class tqdm.tk.tqdm(tqdm.tqdm):
    """Tkinter GUI version."""

class tqdm.rich.tqdm(tqdm.tqdm):
    """`rich.progress` version."""

class tqdm.keras.TqdmCallback(keras.callbacks.Callback):
    """Keras callback for epoch and batch progress."""

class tqdm.dask.TqdmCallback(dask.callbacks.Callback):
    """Dask callback for task progress."""

contrib

这个tqdm.contrib软件包还包含实验模块:

  • tqdm.contrib.itertools:周围有薄薄的包装纸itertools
  • tqdm.contrib.concurrent:周围有薄薄的包装纸concurrent.futures
  • tqdm.contrib.discord:发布到Discord机器人
  • tqdm.contrib.telegram:发布到Telegram机器人
  • tqdm.contrib.bells:自动启用所有可选功能
    • autopandasdiscordtelegram

Examples and Advanced Usage

Description and additional stats

自定义信息可以在上动态显示和更新tqdm带有条形图的条形图descpostfix参数:

from tqdm import tqdm, trange
from random import random, randint
from time import sleep

with trange(10) as t:
    for i in t:
        # Description will be displayed on the left
        t.set_description('GEN %i' % i)
        # Postfix will be displayed on the right,
        # formatted automatically based on argument's datatype
        t.set_postfix(loss=random(), gen=randint(1,999), str='h',
                      lst=[1, 2])
        sleep(0.1)

with tqdm(total=10, bar_format="{postfix[0]} {postfix[1][value]:>8.2g}",
          postfix=["Batch", dict(value=0)]) as t:
    for i in range(10):
        sleep(0.1)
        t.postfix[1]["value"] = i / 2
        t.update()

使用时要记住的要点{postfix[...]}bar_format字符串:

  • postfix还需要以兼容格式作为初始参数传递,并且
  • postfix将自动转换为字符串(如果它是dict-类物体。要防止此行为,请在键不是字符串的字典中插入额外的项

附加内容bar_format参数也可以通过重写format_dict,并且可以使用以下命令修改栏本身ascii

from tqdm import tqdm
class TqdmExtraFormat(tqdm):
    """Provides a `total_time` format parameter"""
    @property
    def format_dict(self):
        d = super(TqdmExtraFormat, self).format_dict
        total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
        d.update(total_time=self.format_interval(total_time) + " in total")
        return d

for i in TqdmExtraFormat(
      range(9), ascii=" .oO0",
      bar_format="{total_time}: {percentage:.0f}%|{bar}{r_bar}"):
    if i == 4:
        break
00:00 in total: 44%|0000.     | 4/9 [00:00<00:00, 962.93it/s]

请注意,{bar}还支持格式说明符[width][type]

  • width
    • 未指定(默认):自动填充ncols
    • int >= 0:固定宽度替代ncols逻辑
    • int < 0:从自动缺省值中减去
  • type
    • a:ASCII(ascii=True覆盖)
    • u:unicode(ascii=False覆盖)
    • b:空白(ascii=" "覆盖)

这意味着可以使用以下方法创建具有右对齐文本的固定栏:bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"

Nested progress bars

tqdm支持嵌套进度条。下面是一个示例:

from tqdm.auto import trange
from time import sleep

for i in trange(4, desc='1st loop'):
    for j in trange(5, desc='2nd loop'):
        for k in trange(50, desc='3rd loop', leave=False):
            sleep(0.01)

要手动控制定位(例如,用于多处理),您可以指定position=n哪里n=0对于最外面的酒吧,n=1下一个,以此类推。不过,最好还是检查一下tqdm无需手动即可工作position第一

from time import sleep
from tqdm import trange, tqdm
from multiprocessing import Pool, RLock, freeze_support

L = list(range(9))

def progresser(n):
    interval = 0.001 / (n + 2)
    total = 5000
    text = "#{}, est. {:<04.2}s".format(n, interval * total)
    for _ in trange(total, desc=text, position=n):
        sleep(interval)

if __name__ == '__main__':
    freeze_support()  # for Windows support
    tqdm.set_lock(RLock())  # for managing output contention
    p = Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),))
    p.map(progresser, L)

请注意,在Python3中,tqdm.write是否线程安全:

from time import sleep
from tqdm import tqdm, trange
from concurrent.futures import ThreadPoolExecutor

L = list(range(9))

def progresser(n):
    interval = 0.001 / (n + 2)
    total = 5000
    text = "#{}, est. {:<04.2}s".format(n, interval * total)
    for _ in trange(total, desc=text):
        sleep(interval)
    if n == 6:
        tqdm.write("n == 6 completed.")
        tqdm.write("`tqdm.write()` is thread-safe in py3!")

if __name__ == '__main__':
    with ThreadPoolExecutor() as p:
        p.map(progresser, L)

Hooks and callbacks

tqdm可以轻松支持回调/挂钩和手动更新。下面是一个包含以下内容的示例urllib

“urllib.urlsearche“文档

[.]
如果存在,将调用一次钩子函数
关于网络连接的建立和每次挡路阅读后的一次
之后。将向挂钩传递三个参数;块计数
到目前为止已传输的挡路大小(以字节为单位)和文件的总大小
[.]
import urllib, os
from tqdm import tqdm
urllib = getattr(urllib, 'request', urllib)

class TqdmUpTo(tqdm):
    """Provides `update_to(n)` which uses `tqdm.update(delta_n)`."""
    def update_to(self, b=1, bsize=1, tsize=None):
        """
        b  : int, optional
            Number of blocks transferred so far [default: 1].
        bsize  : int, optional
            Size of each block (in tqdm units) [default: 1].
        tsize  : int, optional
            Total size (in tqdm units). If [default: None] remains unchanged.
        """
        if tsize is not None:
            self.total = tsize
        return self.update(b * bsize - self.n)  # also sets self.n = b * bsize

eg_link = "https://caspersci.uk.to/matryoshka.zip"
with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
              desc=eg_link.split('/')[-1]) as t:  # all optional kwargs
    urllib.urlretrieve(eg_link, filename=os.devnull,
                       reporthook=t.update_to, data=None)
    t.total = t.n

灵感来自twine#242中的功能替代examples/tqdm_wget.py

建议使用miniters=1每当迭代速度存在潜在较大差异时(例如,通过补丁连接下载文件)

包装读/写方法

要通过类似文件的对象测量吞吐量,请执行以下操作readwrite方法,使用CallbackIOWrapper

from tqdm.auto import tqdm
from tqdm.utils import CallbackIOWrapper

with tqdm(total=file_obj.size,
          unit='B', unit_scale=True, unit_divisor=1024) as t:
    fobj = CallbackIOWrapper(t.update, file_obj, "read")
    while True:
        chunk = fobj.read(chunk_size)
        if not chunk:
            break
    t.reset()
    # ... continue to use `t` for something else

或者,使用更简单的wrapattr便利函数,该函数将压缩两个urllibCallbackIOWrapper下面是示例:

import urllib, os
from tqdm import tqdm

eg_link = "https://caspersci.uk.to/matryoshka.zip"
response = getattr(urllib, 'request', urllib).urlopen(eg_link)
with tqdm.wrapattr(open(os.devnull, "wb"), "write",
                   miniters=1, desc=eg_link.split('/')[-1],
                   total=getattr(response, 'length', None)) as fout:
    for chunk in response:
        fout.write(chunk)

这个requests等价物几乎完全相同:

import requests, os
from tqdm import tqdm

eg_link = "https://caspersci.uk.to/matryoshka.zip"
response = requests.get(eg_link, stream=True)
with tqdm.wrapattr(open(os.devnull, "wb"), "write",
                   miniters=1, desc=eg_link.split('/')[-1],
                   total=int(response.headers.get('content-length', 0))) as fout:
    for chunk in response.iter_content(chunk_size=4096):
        fout.write(chunk)

自定义回调

tqdm以智能地跳过不必要的显示而闻名。要使自定义回调利用这一点,只需使用update()这设置为True如果一个display()已被触发

from tqdm.auto import tqdm as std_tqdm

def external_callback(*args, **kwargs):
    ...

class TqdmExt(std_tqdm):
    def update(self, n=1):
        displayed = super(TqdmExt, self).update(n):
        if displayed:
            external_callback(**self.format_dict)
        return displayed

asyncio

请注意,break当前未被异步迭代器捕获。这意味着tqdm在这种情况下,无法自行清理:

from tqdm.asyncio import tqdm

async for i in tqdm(range(9)):
    if i == 2:
        break

取而代之的是,或者调用pbar.close()手动或使用上下文管理器语法:

from tqdm.asyncio import tqdm

with tqdm(range(9)) as pbar:
    async for i in pbar:
        if i == 2:
            break

Pandas Integration

由于大众的需求,我们增加了对pandas–这里有一个例子DataFrame.progress_applyDataFrameGroupBy.progress_apply

import pandas as pd
import numpy as np
from tqdm import tqdm

df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))

# Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm`
# (can use `tqdm.gui.tqdm`, `tqdm.notebook.tqdm`, optional kwargs, etc.)
tqdm.pandas(desc="my bar!")

# Now you can use `progress_apply` instead of `apply`
# and `progress_map` instead of `map`
df.progress_apply(lambda x: x**2)
# can also groupby:
# df.groupby(0).progress_apply(lambda x: x**2)

如果您对这是如何工作的(以及如何为您自己的回调修改它)感兴趣,请参阅examples文件夹或导入模块,然后运行help()

Keras Integration

一个keras也可以回调:

from tqdm.keras import TqdmCallback

...

model.fit(..., verbose=0, callbacks=[TqdmCallback()])

Dask Integration

一个dask也可以回调:

from tqdm.dask import TqdmCallback

with TqdmCallback(desc="compute"):
    ...
    arr.compute()

# or use callback globally
cb = TqdmCallback(desc="global")
cb.register()
arr.compute()

IPython/Jupyter Integration

IPython/Jupyter通过tqdm.notebook子模块:

from tqdm.notebook import trange, tqdm
from time import sleep

for i in trange(3, desc='1st loop'):
    for j in tqdm(range(100), desc='2nd loop'):
        sleep(0.01)

除了……之外tqdm功能方面,该子模块提供原生Jupyter小部件(与IPythonv1-v4和Jupyter兼容)、完全工作的嵌套条和颜色提示(蓝色:正常、绿色:已完成、红色:错误/中断、浅蓝色:无ETA);如下所示



这个notebook版本支持总宽度的百分比或像素(例如:ncols='100%'ncols='480px')

也可以让tqdm自动选择控制台或笔记本电脑版本,方法是使用autonotebook子模块:

from tqdm.autonotebook import tqdm
tqdm.pandas()

请注意,这将发出一个TqdmExperimentalWarning如果在笔记本中运行,因为它不能区分jupyter notebookjupyter console使用auto而不是autonotebook要取消显示此警告,请执行以下操作

请注意,笔记本将在创建它的单元格中显示该条。这可能是与使用它的单元格不同的单元格。如果这也不是我们想要的,

  • 将栏的创建延迟到必须显示它的单元格,或者
  • 使用创建条形图display=False,并且在稍后的蜂窝呼叫中display(bar.container)
from tqdm.notebook import tqdm
pbar = tqdm(..., display=False)
# different cell
display(pbar.container)

这个keras回调有一个display()同样可以使用的方法:

from tqdm.keras import TqdmCallback
cbk = TqdmCallback(display=False)
# different cell
cbk.display()
model.fit(..., verbose=0, callbacks=[cbk])

另一种可能是拥有一个不断重复使用的条(靠近笔记本顶部)(使用reset()而不是close())。因此,笔记本版本(与CLI版本不同)不会自动调用close()在此基础上Exception

from tqdm.notebook import tqdm
pbar = tqdm()
# different cell
iterable = range(100)
pbar.reset(total=len(iterable))  # initialise with new `total`
for i in iterable:
    pbar.update()
pbar.refresh()  # force print final status but don't `close()`

Custom Integration

要更改默认参数(如进行dynamic_ncols=True),只需使用内置的Python魔术:

from functools import partial
from tqdm import tqdm as std_tqdm
tqdm = partial(std_tqdm, dynamic_ncols=True)

要进一步自定义,请参见tqdm可以从继承以创建自定义回调(与TqdmUpTo示例above)或用于自定义前端(例如,诸如笔记本或绘图包之类的GUI)。在后一种情况下:

  1. def __init__()要呼叫,请执行以下操作super().__init__(..., gui=True)禁用端子的步骤status_printer创作
  2. 重新定义:close()clear()display()

考虑超载display()使用,例如,使用self.frontend(**self.format_dict)而不是self.sp(repr(self))

继承的一些子模块示例:

Dynamic Monitor/Meter

您可以使用tqdm作为一个不是单调递增的韵律。这可能是因为n减少(例如CPU使用情况监视器)或total变化

递归搜索文件就是一个例子。这个total是到目前为止找到的对象数,而n是属于文件(而不是文件夹)的那些对象的数量:

from tqdm import tqdm
import os.path

def find_files_recursively(path, show_progress=True):
    files = []
    # total=1 assumes `path` is a file
    t = tqdm(total=1, unit="file", disable=not show_progress)
    if not os.path.exists(path):
        raise IOError("Cannot find:" + path)

    def append_found_file(f):
        files.append(f)
        t.update()

    def list_found_dir(path):
        """returns os.listdir(path) assuming os.path.isdir(path)"""
        listing = os.listdir(path)
        # subtract 1 since a "file" we found was actually this directory
        t.total += len(listing) - 1
        # fancy way to give info without forcing a refresh
        t.set_postfix(dir=path[-10:], refresh=False)
        t.update(0)  # may trigger a refresh
        return listing

    def recursively_search(path):
        if os.path.isdir(path):
            for f in list_found_dir(path):
                recursively_search(os.path.join(path, f))
        else:
            append_found_file(path)

    recursively_search(path)
    t.set_postfix(dir=path)
    t.close()
    return files

使用update(0)是一种方便的方式来让tqdm决定何时触发显示刷新以避免控制台垃圾邮件

Writing messages

这是一项正在进行的工作(请参见#737)

因为tqdm使用简单的打印机制显示进度条,您不应该在终端中使用print()当进度条打开时

在终端中写入消息而不与其发生任何冲突tqdm条形图显示,a.write()提供了一种方法:

from tqdm.auto import tqdm, trange
from time import sleep

bar = trange(10)
for i in bar:
    # Print using tqdm class method .write()
    sleep(0.1)
    if not (i % 3):
        tqdm.write("Done task %i" % i)
    # Can also use bar.write()

默认情况下,这将打印到标准输出sys.stdout但是您可以使用file论点。例如,这可用于将写入日志文件或类的消息重定向

Redirecting writing

如果使用可以将消息打印到控制台的库,请通过替换print()使用tqdm.write()可能不是我们想要的。在这种情况下,重定向sys.stdouttqdm.write()是一种选择

要重定向,请执行以下操作sys.stdout,创建一个类似文件的类,该类将把任何输入字符串写入tqdm.write(),并提供参数file=sys.stdout, dynamic_ncols=True

下面给出了一个可重用的规范示例:

from time import sleep
import contextlib
import sys
from tqdm import tqdm
from tqdm.contrib import DummyTqdmFile


@contextlib.contextmanager
def std_out_err_redirect_tqdm():
    orig_out_err = sys.stdout, sys.stderr
    try:
        sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err)
        yield orig_out_err[0]
    # Relay exceptions
    except Exception as exc:
        raise exc
    # Always restore sys.stdout/err if necessary
    finally:
        sys.stdout, sys.stderr = orig_out_err

def some_fun(i):
    print("Fee, fi, fo,".split()[i])

# Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)
with std_out_err_redirect_tqdm() as orig_stdout:
    # tqdm needs the original stdout
    # and dynamic_ncols=True to autodetect console width
    for i in tqdm(range(3), file=orig_stdout, dynamic_ncols=True):
        sleep(.5)
        some_fun(i)

# After the `with`, printing is restored
print("Done!")

Redirecting logging

类似于sys.stdout/sys.stderr如上所述,控制台logging也可以重定向到tqdm.write()

警告:如果还重定向sys.stdout/sys.stderr,请务必重定向logging如果需要,先来

中提供了帮助器方法tqdm.contrib.logging例如:

import logging
from tqdm import trange
from tqdm.contrib.logging import logging_redirect_tqdm

LOG = logging.getLogger(__name__)

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    with logging_redirect_tqdm():
        for i in trange(9):
            if i == 4:
                LOG.info("console logging redirected to `tqdm.write()`")
    # logging restored

Monitoring thread, intervals and miniters

tqdm实施一些技巧来提高效率和降低管理费用

  • 避免不必要的频繁条刷新:mininterval定义每次刷新之间等待的时间。tqdm始终在后台更新,但它将仅在mininterval
  • 减少检查系统时钟/时间的调用次数
  • mininterval比起配置更直观miniters巧妙的调整系统dynamic_miniters将自动调整miniters与时间相适应的迭代次数mininterval从本质上讲,tqdm将在不实际检查时间的情况下检查是否到了打印时间。通过手动设置,仍可绕过此行为miniters

但是,请考虑快速迭代和慢速迭代相结合的情况。在几次快速迭代之后,dynamic_miniters将设置miniters变成了一个大数目。当迭代速率随后减慢时,miniters将保持较大,从而降低显示更新频率。要解决此问题,请执行以下操作:

  • maxinterval定义显示刷新之间的最长时间。并发监视线程检查过期的更新,并在必要时强制更新

监视线程不应该有明显的开销,并且默认情况下保证至少每10秒更新一次。该值可以通过设置monitor_interval任何tqdm实例(即t = tqdm.tqdm(...); t.monitor_interval = 2)。可以通过设置在应用程序范围内禁用监视线程tqdm.tqdm.monitor_interval = 0在实例化任何tqdm钢筋

Merch

你可以买到tqdm branded merch现在!

Contributions

所有源代码都托管在GitHub欢迎投稿

请参阅CONTRIBUTING有关详细信息,请参阅文件

做出重大贡献的开发人员,按SLOC(幸存的代码行,git fame-wMC --excl '\.(png|gif|jpg)$'),包括:

名字 ID号 SLOC 注意事项
卡斯珀·达·科斯塔-路易斯 casperdcl ~81% 主要维护人员
斯蒂芬·拉罗克 lrq3000 ~10% 团队成员
马丁·祖格诺尼 martinzugnoni ~3% 他说:
理查德·谢里登 richardsheridan ~1% 他说:
陈广硕 chengs ~1% 他说:
凯尔·阿尔滕多夫 altendky <1% 他说:
马修·史蒂文斯 mjstevens777 <1% 他说:
哈德琳·玛丽 hadim <1% 团队成员
伊万·伊万诺夫 obiwanus <1% 他说:
丹尼尔·潘特莱特 danielpanteleit <1% 他说:
乔纳斯·哈格 jonashaag <1% 他说:
詹姆斯·E·金三世 jeking3 <1% 他说:
诺姆·约拉夫-拉斐尔 noamraph <1% 原作者
米哈伊尔·科罗博夫 kmike <1% 团队成员

Ports to Other Languages

有关列表,请访问this wiki page

LICENCE

开源(OSI批准):

引文信息:

(自2016年5月19日起)