Как открыть веб-браузер в окне tkinter

#python #tkinter

Вопрос:

Я знаю, что эта проблема решалась раньше, но я не мог найти решение, которое имело бы отношение к моему проекту. Мой проект-это редактор/интерпретатор HTML, который использует webbrowser модуль для запуска данного HTML-кода в веб-браузере. Я хочу иметь возможность открывать веб-браузер в моем окне tkinter, а не в реальном браузере. Как я могу реализовать это в своей программе? Кое — что из моего кода:

 import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
from tkinter import messagebox
import webbrowser
import os

window = tk.Tk()
window.title("HTML Editor")
window.configure(bg="grey")
window.state("zoomed")
title = tk.Label(window, text="HTML Editor", font=("Arial Rounded MT Bold", 40, "underline"), bg="grey")
title.place(x=400, y=20)


def run_code():
    window_title = window.title()
    index = window_title.index("-")   2
    window_title = window_title[index::]

    with open(window_title, "w") as path:
        content = text_box.get("1.0", tk.END)
        path.write(content)

    basename = os.path.basename(window_title)
    new_file = open(basename, "w")
    new_file.write(content)
    new_file.close()
    webbrowser.open_new_tab("file:///"   os.getcwd()   "/"   basename)


def get_stringvar(event):
    line = text_box.get("insert linestart", "insert")
    if (line[-1] == ">") and ("<" in line):
        new_line = "</"   line[line.rindex("<")   1:-1]   ">"
        text_box.insert("insert", new_line)
        text_box.mark_set("insert", f"insert-{len(new_line)}c")
        return "break"


def file_func():
    frame.pack(side="left", fill="y")
    text_box.pack(side="left", fill="both", expand=True)
    scroll_bar.pack(side="left", fill="y")
    run_b.pack(padx=50, pady=(100, 5), anchor="n")


create = tk.Button(window, text="Create a new file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
                   command=save_file)
create.place(x=420, y=200)
open_e = tk.Button(window, text="Open an existing file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
                   command=open_file)
open_e.place(x=420, y=350)

window.protocol("WM_DELETE_WINDOW", on_closing)
frame = tk.Frame(window, bd=2, relief="raised")

text_box = tk.Text(window, font=("Flux-Regular", 12), fg="black")
text_box.bind("<Tab>", get_stringvar)

scroll_bar = tk.Scrollbar(window, command=text_box.yview)

run_b = tk.Button(frame, text="Run", width=6, height=2, bg="white", command=run_code)

text_box.configure(yscrollcommand=scroll_bar.set)

window.mainloop()
 

Комментарии:

1. @Sujay, я видел, как это делали другие, но я не знаю, как я могу применить то, что они сделали в моем проекте

2. @Рони, где ты это видел?

3. @Sujay, я поискал свой вопрос, и появилось несколько страниц, посвященных этой проблеме. Я просмотрел все страницы, но не знал, как применить решения в своей собственной программе

4. @Sujay, я нашел решение. Я опубликую это в качестве ответа

5. как я знаю tkinter , для этого нет хорошего модуля. У него есть какой-то модуль, который может отображаться HTML , но имеет проблемы, CSS и он не может работать JavaScript . Его можно было бы лучше использовать PyQt вместо tkinter . В конечном итоге проверьте CEF Python на Chromium Embedded Framework наличие . Похоже, у него есть пример для tkinter

Ответ №1:

Я нашел ответ на свой вопрос после еще нескольких исследований. Мое решение не включает в себя открытие веб-браузера, но оно включает использование модуля tkhtmlview для запуска HTML-кода. Я также добавил Toplevel виджет для отображения выходных данных. Код:

 import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
from tkinter import messagebox
import os
from tkhtmlview import HTMLLabel

window = tk.Tk()
window.title("HTML Editor")
window.configure(bg="grey")
window.state("zoomed")
title = tk.Label(window, text="HTML Editor", font=("Arial Rounded MT Bold", 40, "underline"), bg="grey")
title.place(x=400, y=20)


def run_code():
    window_title = window.title()
    index = window_title.index("-")   2
    window_title = window_title[index::]

    with open(window_title, "w") as path:
        content = text_box.get("1.0", tk.END)
        path.write(content)

    basename = os.path.basename(window_title)
    new_file = open(basename, "w")
    new_file.write(content)
    new_file.close()
    window2 = tk.Toplevel(window)
    window.configure(bg="white")
    window2.title("Console")
    window2.state("zoomed")
    my_label = HTMLLabel(window2, html=content)
    my_label.place(x=0, y=10)


def get_stringvar(event):
    line = text_box.get("insert linestart", "insert")
    if (line[-1] == ">") and ("<" in line):
        new_line = "</"   line[line.rindex("<")   1:-1]   ">"
        text_box.insert("insert", new_line)
        text_box.mark_set("insert", f"insert-{len(new_line)}c")
        return "break"


def file_func():
    frame.pack(side="left", fill="y")
    text_box.pack(side="left", fill="both", expand=True)
    scroll_bar.pack(side="left", fill="y")
    run_b.pack(padx=50, pady=(100, 5), anchor="n")


create = tk.Button(window, text="Create a new file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
                   command=save_file)
create.place(x=420, y=200)
open_e = tk.Button(window, text="Open an existing file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
                   command=open_file)
open_e.place(x=420, y=350)

window.protocol("WM_DELETE_WINDOW", on_closing)
frame = tk.Frame(window, bd=2, relief="raised")

text_box = tk.Text(window, font=("Flux-Regular", 12), fg="black")
text_box.bind("<Tab>", get_stringvar)

scroll_bar = tk.Scrollbar(window, command=text_box.yview)

run_b = tk.Button(frame, text="Run", width=6, height=2, bg="white", command=run_code)

text_box.configure(yscrollcommand=scroll_bar.set)

window.mainloop()
 

Редактировать: @TheLizzard сказал мне, что tkhtmlview это несовместимо с js и css, поэтому я просто буду придерживаться webbrowser модуля.

Комментарии:


1. если вы хотите получить данные с какого-либо веб-сайта, вы можете использовать sth like html = request.get(url).text или sth like, а затем html будете содержать весь html этого сайта (не забудьте import requests также, если вам интересно, вот учебник Кори Шафера о requests том, как )

2. кроме того, вы на самом деле не можете открыть веб-браузер в своем приложении, поскольку веб-браузер сам по себе является автономным приложением, вы можете использовать описанный выше метод, чтобы получить содержимое веб-сайта и отобразить его в tkinter, а затем у вас будет веб-браузер (что в некотором роде кажется тем, к чему вы стремитесь).

3. @Matiiss, хорошая идея! Я собираюсь посмотреть видео, чтобы узнать о запросах и о том, как их реализовать. Большое вам спасибо!

4. @Matiiss, у меня есть вопрос по поводу запросов. Что делать, если ссылка или изображение являются частью вывода? Смогу ли я отобразить его в окне tkinter?

5. @Roni В соответствии с этим tkhtmlview также должен поддерживать изображения. Также обратите внимание, что поддержка JS отсутствует, поэтому большинство веб-страниц будут загружаться неправильно.