问题描述
我正在使用 Tkinter 在我的项目中创建聊天,例如抽搐。是否可以在消息中使用动画(不仅是)表情符号制作聊天小部件?
代码:
def print_mess(self,mess):
self.console.configure(state='normal')
self.console.insert(END,mess.formated_time() + " ",'timesign')
self.console.tag_config('timesign',foreground='#C0C0C0')
self.console.insert(END,mess.username,mess.username)
self.console.tag_config(mess.username,foreground=mess.usercolor)
self.console.insert(END,": ",'mess')
self.console.insert(END,mess.message + "\n",'mess')
self.console.tag_config('mess',foreground='#FFFFFF')
self.console.yview(END) # autoscroll
self.console.configure(state='disabled')
解决方法
有多种方法,一种方法是使用标签并使用 <head>
<style>
@import url('https://fonts.googleapis.com/css?family=Josefin+Sans:400,400i,600,600i');
html,body{
margin:0;
height:120%;
font-family: 'Josefin Sans',sans-serif;}
a{
text-decoration:none
}
.header{
position:relative;
overflow:hidden;
display:flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
align-content: flex-start;
height:50vw;
min-height:600px;
max-height:100%;
min-width:300px;
color:#eee;
}
.header:after{
content:"";
width:100%;
height:100%;
position:absolute;
bottom:0;
left:0;
z-index:-1;
background: linear-gradient(to bottom,rgba(0,0.12) 40%,rgba(27,32,48,1) 100%);
}
.header:before{
content:"";
width:100%;
height:300%;
position:absolute;
top:0;
left:0;
-webkit-backface-visibility: hidden;
-webkit-transform: translateZ(0); backface-visibility: hidden;
scale(1.0,1.0);
transform: translateZ(0);
background:#1B2030 url(asthetic_Bg_Image1.jpg) 50% 0 no-repeat;
background-size:100%;
background-attachment:fixed;
animation: grow 360s linear 10ms infinite;
transition:all 0.4s ease-in-out;
z-index:-2
}
.header a{
color:#eee
}
.menu{
display:block;
width:40px;
height:30px;
border:2px solid #fff;
border-radius:3px;
position:absolute;
right:20px;
top:20px;
text-decoration:none
}
.menu:after{
content:"";
display:block;
width:20px;
height:3px;
background:#fff;
position:absolute;
margin:0 auto;
top:5px;
left:0;
right:0;
box-shadow:0 8px,0 16px
}
.logo{
border:2px solid #fff;
border-radius:3px;
text-decoration:none;
display:inline-flex;
align-items:center;
align-content:center;
position: relative;
top: 1em;
left: 12em;
padding:0px 10px;
font-weight:900;
font-size:1.1em;
line-height:1;
box-sizing:border-box;
height:40px
}
.sides,.info{
flex: 0 0 auto;
width:50%
}
.info{
width:100%;
padding:15% 10% 0 10%;
text-align:center;
text-shadow:0 2px 3px rgba(0,0.2)
}
.author{
display:inline-block;
width:50px;
height:50px;
border-radius:50%;
background:url(https://i.imgur.com/6DLCsZcb.jpg) center repeat;
background-size:cover;
box-shadow:0 2px 3px rgba(0,0.3);
margin-bottom:3px
}
.info h4,.meta{
font-size:0.7em
}
.meta{
font-style:italic;
}
@keyframes grow{
0% { transform: scale(1) translateY(0px)}
50% { transform: scale(1.2) translateY(-200px)}
}
.content{
padding:5% 10%;
text-align:justify
}
button{
color:#333;
height: 5px;
border-radius:25px;
text-decoration:none;
display:inline-block;
padding:5px 10px;
font-weight:600
}
.btn{
}
.twtr{
margin-top:100px
}.btn.twtr:after{content:"\1F426";padding-left:5px}
.train2 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example1;
animation-duration: 4s;
right: 40em;
top:10em;
}
@keyframes example1 {
0% { right: 0em; top: 10em;}
100% { right:40em; top:10em;}
}
.train3 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example3;
animation-duration: 4s;
right: 100%; /* changed */
animation-fill-mode: forwards; /* added to make it stay at the final position */
top: 15em;
animation-delay: 2s;
}
@keyframes example3 {
0% { right: 100%; top:15em;} /* changed to put it completely left */
100% { right: 40em; top:15em;}
}
.train4 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example4;
animation-duration: 4s;
left: 35em;
top: 15em;
animation-delay: 2s;
}
@keyframes example4{
0% { left:0px; top:15em;}
100% { left:35em; top:15em;}
}
.train5 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example5;
animation-duration: 4s;
left: 35em;
top: 21em;
animation-delay: 6s;
}
@keyframes example5{
0% { left:0px; top:21em;}
100% { left:35em; top:21em;}
}
.train6 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example6;
animation-duration: 4s;
right: 40em;
top: 21em;
animation-delay: 6s;
}
@keyframes example6{
0% { right:0px; top:21em;}
100% { right:40em; top:21em;}
}
.train31 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example31;
animation-duration: 4s;
right: 40em;
top: 27em;
animation-delay: 10s;
}
@keyframes example31 {
0% { right:0px; top:27em;}
100% { right:40em; top:27em;}
}
.train41 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example41;
animation-duration: 4s;
left: 35em;
top: 27em;
animation-delay: 10s;
}
@keyframes example41{
0% { left:0px; top:27em;}
100% { left:35em; top: 27 em;}
}
.train11{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
animation-name: example11;
animation-duration: 4s;
right: 30em;
top:32em;
animation-delay: 14s;
}
@keyframes example11 {
0% { right:0px; top:32em;}
100% { right:30em; top:32em;}
}
.relax_tab{
height: 100vh;
background-color: red;
border-radius: 10px;
margin: 5px;
padding: 5px;
}
</style>
</head>
<body> <div class="header" style="text-align: center;">
<div class="sides" style="text-align: center;">
<a href="#" class="logo" style="text-align: center;">????????</a>
</div>
<div class="sides"> <a href="#" class="menu"> </a></div>
<div class="info">
<h4><a href="#category"></a></h4>
<a href="#relax_tab"> <button style="color:#333;
border:2px solid;
height: 37px;
border-radius:25px;
text-decoration:none;
background-color: transparent ;
color: white;
display:inline-block;
padding:5px 10px;
font-weight:600" class="train2">Relax</button></a>
<a href="#funny"> <button style="color:#333;
border:2px solid;
height: 37px;
background-color: transparent ;
color: white;
border-radius:25px;
text-decoration:none;
display:inline-block;
padding:5px 10px;
font-weight:600" class="train3">Funny</button></a>
<a href="#all_time"> <button style="color:#333;
border:2px solid;
height: 37px;
border-radius:25px;
text-decoration:none;
background-color: transparent ;
color: white;
display:inline-block;
padding:5px 10px;
font-weight:600" class="train4">All Time fav.</button></a>
<a href="#english"><button style="color:#333;
border:2px solid;
height: 37px;
background-color: transparent ;
color: white;
border-radius:25px;
text-decoration:none;
display:inline-block;
padding:5px 10px;
font-weight:600" class="train5">English</button></a>
<a href="#hindi"> <button style="color:#333;
border:2px solid;
height: 37px;
background-color: transparent ;
color: white;
border-radius:25px;
text-decoration:none;
display:inline-block;
background-color: transparent ;
color: white;
padding:5px 10px;
font-weight:600" class="train6">Hindi</button></a>
<a href="#chill"> <button style="color:#333;
border:2px solid;
height: 37px;
background-color: transparent ;
color: white;
border-radius:25px;
text-decoration:none;
display:inline-block;
padding:5px 10px;
font-weight:600" class="train31">Chill</button></a>
<a href="#sad"><button style="color:#333;
border:2px solid;
height: 37px;
border-radius:25px;
text-decoration:none;
display:inline-block;
background-color: transparent ;
color: white;
padding:5px 10px;
font-weight:600" class="train41">Sad</button></a>
<button style="color:#333;
border:2px solid;
height: 37px;
background-color: transparent ;
color: white;
border-radius:25px;
text-decoration:none;
display:inline-block;
padding:5px 10px;
font-weight:600" class="train11">Suggestions</button> </body>
示例:(拖放 gif。点击 gif 播放,修改它以满足您的需要)。
window_create()
另一种方法是使用
import tkinter as tk
from PIL import Image,ImageTk
import windnd
class Text(tk.Text):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.gif = {}
self.index = 0
self.delay = 20
self.currentlyPlaying = None
self.currentId = None
def insert_gif(self,path):
gif = GifMaker(path)
label = tk.Label(image=gif.frames[0],bd=3)
label.bind('<1>',lambda event: self.playGif(label))
self.window_create("end",window=label)
self.gif[label] = gif
self.playGif(label)
def playGif(self,label):
if self.currentlyPlaying is None:
self.currentlyPlaying = label
if self.currentlyPlaying != label: # makes sure only one gif is played at any time
self.index = 0
self.currentlyPlaying.configure(image=self.gif[self.currentlyPlaying].frames[0])
self.currentlyPlaying = label
self.after_cancel(self.currentId)
self.index += 1
if self.index == self.gif[self.currentlyPlaying].n_frames-1:
self.index = 0
self.currentlyPlaying.configure(image=self.gif[self.currentlyPlaying].frames[self.index])
if self.index != 0:
self.currentId = self.after(self.delay,self.playGif,self.currentlyPlaying)
class GifMaker:
def __init__(self,path):
self.path = path
self.image = Image.open(path)
self.n_frames = self.image.n_frames # number of frames
self.frames = []
self.duration = 0 # total duration of the gif
for x in range(self.n_frames):
img = ImageTk.PhotoImage(self.image.copy())
self.duration += self.image.info['duration']
self.frames.append(img)
self.image.seek(x)
self.delay = self.duration//self.n_frames
def dropped(file):
text.insert_gif(file[0])
root = tk.Tk()
text = Text()
text.pack(fill='both',expand=True)
windnd.hook_dropfiles(root,func=dropped)
root.mainloop()
创建图像并使用 .image_create()
更新图像。 (推荐)
.image_configure()
(通过添加类似上述方法的条件,确保在任何情况下只播放一个 gif)
输出: