【问题标题】:How I can Add Scrollbar in frame tkinter (Python)如何在框架 tkinter (Python) 中添加滚动条
【发布时间】:2021-12-24 07:15:54
【问题描述】:

您好,我一直在尝试使用 tkinterpython 创建我的小项目,但我尝试了所有方法在 frame 中添加 scrollbar,但不幸的是我无法做到。

谁能帮帮我?

from tkinter import *
from tkinter import messagebox
import urllib.error, urllib.parse ,urllib.request
from bs4 import BeautifulSoup 

b="#0c1231"

root = Tk()
root.title("Stock World")
root.geometry("1350x722+5+5")
root.configure(bg=b)

fr  = Frame(root)
fr.configure(bg=b)
fr.place(relx=0.01,rely=0.11,width=1310,height=635)

我一直在尝试通过单击从网站和不同页面获取股票访问权限。

def get_web_result():
    for i in range(1,2):
        try:
            lnk="https://www.moneycontrol.com/broker-research/latestResearchReport/"+str(i)
            url = urllib.request.urlopen(lnk)
        except:
            messagebox.showwarning("Notification","Check your internet connection and try again later !!!")

        bs = BeautifulSoup(url,"html.parser")
        tg = bs('tbody')
        
        for line in tg:
            lne = line.text
            fopen = open("stock.txt","w")
            f = fopen.writelines(lne.strip())

    i=i+1

    fopen = open("stock.txt","r")
    fopen = fopen.readlines()
    x=0.01
    y=0.02
    a=1
    for l in fopen:
        if len(l)>0:
            if a==1: #date
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.005,rely=y)

            elif a==2: #company
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.09,rely=y)

            elif a==3: #broker
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.20,rely=y)

            elif a==4: #buy or sell
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.31,rely=y)

            elif a==5: #report price
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.38,rely=y)

            elif a==6: #cmp
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.475,rely=y)

            elif a==7: #target price
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.56,rely=y)

            elif a==8: #profit
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.62,rely=y)

            elif a==9: #realized return
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.70,rely=y)

            elif a==10: #sensex return
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.81,rely=y)

            elif a==11:  #
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.98,rely=y)

            elif a==12:  #
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.99,rely=y)

            elif a==13:  #
                lb = Label(fr,text=l, font=("arial",10),fg="white",bg=b)
                lb.place(relx=0.99,rely=y)


        else:
            pass

        a=a+1
        if a == 14:
            y=y+0.03
            a=1

以上代码在tkinter窗口上显示输出。

lf = "{Arial} 13 bold"

money_ctrl = Button(root,text = "Get Result....!!!",font=("Bahnschrift",13,"bold"),fg="white",bg="#363ddb",command = get_web_result)
money_ctrl.place(relx=0.01,rely=0.01,width=490)

date_lb =Label(root,text="Date",font=lf ,fg="#ffc202",bg=b)
date_lb.place(relx=0.03,rely=0.075)

stockname_lb =Label(root,text="Company",font=lf ,fg="#ffc202",bg=b)
stockname_lb.place(relx=0.10,rely=0.075)

broker_lb =Label(root,text="Broker",font=lf ,fg="#ffc202",bg=b)
broker_lb.place(relx=0.21,rely=0.075)

bors_lb =Label(root,text="Buy/Sell",font=lf ,fg="#ffc202",bg=b)
bors_lb.place(relx=0.30,rely=0.075)

prs_lb =Label(root,text="Report Price",font=lf ,fg="#ffc202",bg=b)
prs_lb.place(relx=0.37,rely=0.075)

cmpp_lb =Label(root,text="CMP",font=lf ,fg="#ffc202",bg=b)
cmpp_lb.place(relx=0.47,rely=0.075)

tgt_lb =Label(root,text="Target price",font=lf ,fg="#ffc202",bg=b)
tgt_lb.place(relx=0.53,rely=0.075)

pf_lb =Label(root,text="Profit %",font=lf ,fg="#ffc202",bg=b)
pf_lb.place(relx=0.62,rely=0.075)

rr_lb =Label(root,text="Realized Return",font=lf ,fg="#ffc202",bg=b)
rr_lb.place(relx=0.68,rely=0.075)

ss =Label(root,text="Sensex Return",font=lf ,fg="#ffc202",bg=b)
ss.place(relx=0.79,rely=0.075)

root.mainloop()

谢谢。

【问题讨论】:

  • 您不能使用scrollbar 滚动Frame。您只能将Frame 放在Canvas 上并滚动Canvas。但它需要更多的代码。见 GitHub:scrolled-frame-canvas/
  • @furas:您还可以滚动 Text 小部件。
  • @BryanOakley 你说得对,我忘了Text也可以用create_windowLabelFrame

标签: python python-3.x tkinter scrollbar tkinter-layout


【解决方案1】:

您不能使用Scrollbar 滚动Frame

您可以将ScrollbarCanvasListboxText 一起使用。

您也可以将Frame 放在CanvasText 上,这样您就可以将Frame 放在CanvasText 上并滚动CanvasText,它会滚动Frame


但是有更简单的方法。你可以把Frame放在ScrolledText上,不用加Scrollbar


要将小部件放在ScrolledText(或Canvas)上,您必须使用window_create() 而不是pack()/grid()/place()

我还在ScrolledText 中设置了state='disable',这样您就无法在ScrolledText 中编辑和删除文本和小部件,也不会意外删除Frame

import tkinter as tk
from tkinter.scrolledtext import ScrolledText

root = tk.Tk()

text = ScrolledText(root, state='disable')
text.pack(fill='both', expand=True)

frame = tk.Frame(text)
text.window_create('1.0', window=frame)

for number in range(30):
    l = tk.Label(frame, text='Input:', bg='red')
    l.grid(row=number, column=0, sticky='we')
    l = tk.Label(frame, text=number, bg='green')
    l.grid(row=number, column=1, sticky='we')
    
root.mainloop()  


编辑:

从页面读取数据的版本

import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import urllib.request
from bs4 import BeautifulSoup
import csv

# --- classes ---

#class MyWidget(tk.Frame):
#    pass

# --- functions ---

def get_data(pages=3):

    data = []

    for page in range(1, pages+1):
        print('--- page:', page, '---')
        
        try:
            url = f"https://www.moneycontrol.com/broker-research/latestResearchReport/{page}"
            response = urllib.request.urlopen(url)
        except Exception as ex:
            print('ex:', ex)
            messagebox.showwarning("Notification", "Check your internet connection and try again later !!!")

        soup = BeautifulSoup(response.read(), "html.parser")
        all_rows = soup.find('tbody').find_all('tr')
        for number, row in enumerate(all_rows, 1):
            print('row:', number)
            all_cells = row.find_all('td')
            all_cells = [x.get_text(strip=True) for x in all_cells]
            data.append(all_cells)

    return data

# --- main ---

data = get_data()

header = ['Date', 'Company', 'Broker', 'Reco', 'Price on Report dt.', 'CMP', 'Target Price', 'Profit Ptial %', 'Realized Return', 'Sensex Return', 'PDF']

with open('output.csv', 'w') as fh:
    csv_writer = csv.writer(fh)
    csv_writer.writerow(header)
    csv_writer.writerows(data)

root = tk.Tk()

text = ScrolledText(root, state='disable')
text.pack(fill='both', expand=True)

frame = tk.Frame(text)
text.window_create('1.0', window=frame)

for row_number, row in enumerate(data):
    for col_number, (name, color) in enumerate([('Date', 'red'), ('Company', 'green'), ('Broker', 'yellow')]):
        value = row[col_number]
        l = tk.Label(frame, text=f'{name}: {value}', bg=color)
        l.grid(row=row_number, column=col_number, sticky='we')
    
root.mainloop()

结果:


我正在考虑创建自己的小部件 MyWidget 来显示单行数据 - 然后我可以显示许多 MyWidget - 但我跳过了这个想法。

如果要进行一些计算,最好将其保留为pandas.DataFrame,然后您可以将其显示为表格pandastable 也许它会更快地显示它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 2020-11-26
    • 2017-03-24
    • 2013-04-17
    相关资源
    最近更新 更多