Найти - Пользователи
Полная версия: Запуск окна на PyQt5 из Tkinter
Начало » GUI » Запуск окна на PyQt5 из Tkinter
1
wladimirbel
Есть Desktop приложение на tkinter, делаю окно для открытия и просмотра email.
В tkinter только html получается просмотреть, а письмо в том виде в котором оно приходит приходится отправлять в браузер.
Я хочу открывать и смотреть почту в своем окне. Решил использовать для этого QWebEngineView из PyQt5, который запускаю из tkinter.
Проблема: Первый раз запускается и отрабатывает как нужно, при повторном запуске, программа полностью вылетает. Пробовал запускать через Thread в отдельном потоке, но результат тот же. Пробовал переименовывать поток, используя random - тоже не помогло.
Выход вижу либо переписывать заново всю прогу на PyQt5, либо сделать отдельное приложение на PyQt и запускать отдельно, но задумка теряется.
Что почитать или в каком направлении идти что бы скрестить все-таки их?

Добавил пример с минимальным кодом при котором воспроизводится проблема

 import tkinter as tk
from PyQt5.QtWebEngineWidgets import *
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtCore import *
import sys
class Main(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.init_main()
    def init_main(self):
        self.label = tk.Label(self, text='После первого нажатия на кнопку все отрабатывает,\n'
                                         ' потом закрываем окно \n'
                                         'и повторно жмем кнопку и программа рушится\n')
        self.label.pack(side=tk.TOP)
        self.btn = tk.Button(self, text='Нажми меня', command=self.open_read_mail)
        self.btn.pack(side=tk.TOP)
    def open_read_mail(self):
        # self.filepath = 'https://www.example.com'  # 'file:///__Страшно_горят_цены_в_21vek___/index.html'
        # web_text = self.filepath
        web = Web()   # web_text
        web.open()
class Web:
    def __init__(self, url='https://www.example.com', title='Входящее сообщение'):
        self.title = title
        self.url = url
    def init_child(self):
        self.app = QtWidgets.QApplication(sys.argv)
        self.centralwidget = QtWidgets.QWidget()
        self.centralwidget.setObjectName("centralwidget")
        self.centralwidget.setGeometry(QtCore.QRect(150, 50, 700, 600))
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(70, 10, 600, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(70, 40, 600, 20))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(70, 70, 600, 371))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.web = QWebEngineView(self.frame)
        self.web.setWindowTitle(self.title)
        self.web.load(QUrl(self.url))
        self.web.resize(600, 550)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(40, 10, 21, 16))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(30, 40, 31, 16))
        self.label_2.setObjectName("label_2")
        self.label.setText("От:")
        self.label_2.setText("Тема:")
        qbtn = QtWidgets.QPushButton('Quit', self.centralwidget)
        qbtn.clicked.connect(self.close_window)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(1, 60)
    def close_window(self):
        self.centralwidget.close()
        #sys.exit(0)
    def open(self):
        self.init_child()
        self.centralwidget.show()
        self.app.exec()
        #sys.exit()
if __name__ == "__main__":
    root = tk.Tk()
    app = Main(root)
    app.pack()
    root.geometry("400x200+100+100")
    root.resizable(True, True)
    root.mainloop()
Rodegast
> Запуск окна на PyQt5 из Tkinter

Забудь про Tkinter.
PEHDOM
wladimirbel вы пытаетесь скрестить ежа и трепетную лань. Мало того что запускаете в одном процессе два обработчика событий: ткинтер и qt, но также пытаетесь создать несколько QApplication, чего архитектура qt неприемлет. QApplication, как горец, должен остаться быть только один!
вот тако оно работает:
 #
import tkinter as tk
from PyQt5.QtWebEngineWidgets import *
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtCore import *
import sys
class Main(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.init_main()
        self.web = Web()
    def init_main(self):
        self.label = tk.Label(self, text='После первого нажатия на кнопку все отрабатывает,\n'
                                         ' потом закрываем окно \n'
                                         'и повторно жмем кнопку и программа рушится\n')
        self.label.pack(side=tk.TOP)
        self.btn = tk.Button(self, text='Нажми меня', command=self.open_read_mail)
        self.btn.pack(side=tk.TOP)
    def open_read_mail(self):
        # self.filepath = 'https://www.example.com'  # 'file:///__Страшно_горят_цены_в_21vek___/index.html'
        # web_text = self.filepath
          # web_text
        self.web.open()
class Web:
    def __init__(self, url='https://www.example.com', title='Входящее сообщение'):
        self.title = title
        self.url = url
        self.app = QtWidgets.QApplication(sys.argv)
    def init_child(self):
        self.centralwidget = QtWidgets.QWidget()
        self.centralwidget.setObjectName("centralwidget")
        self.centralwidget.setGeometry(QtCore.QRect(150, 50, 700, 600))
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(70, 10, 600, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(70, 40, 600, 20))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(70, 70, 600, 371))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.web = QWebEngineView(self.frame)
        self.web.setWindowTitle(self.title)
        self.web.load(QUrl(self.url))
        self.web.resize(600, 550)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(40, 10, 21, 16))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(30, 40, 31, 16))
        self.label_2.setObjectName("label_2")
        self.label.setText("От:")
        self.label_2.setText("Тема:")
        qbtn = QtWidgets.QPushButton('Quit', self.centralwidget)
        qbtn.clicked.connect(self.close_window)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(1, 60)
    def close_window(self):
        self.centralwidget.close()
        #sys.exit(0)
    def open(self):
        self.init_child()
        self.centralwidget.show()
        self.app.exec()
        #sys.exit()
if __name__ == "__main__":
    root = tk.Tk()
    app = Main(root)
    app.pack()
    root.geometry("400x200+100+100")
    root.resizable(True, True)
    root.mainloop()

Но это костыль, вы всеравно не сможете открыть несколько окон qt одновременно потому что когда окно qt открыто окно ткинтера “заморожено”. Всеже правильнее будет делать все на одном фреймоврке или тк или qt, скрещивать их последнее дело, совсем уж от безысходности, и нужно понимать в первую очередь, что вы делаете.

ЗЫ можно запускать qt в отдельном процессе,(не потоке!). тогда окно ткинтера не будет замораживаться. Но тогда вам придеться заморачиваться с передачей данных между процессами.
makis13
Продажа легковых прицепов и фаркопов в Ростове на Дону
Купить прицеп в ЛНР, Купить прицеп в ДНР, Купить прицеп в ДНР, купить прицеп в Луганске, купить прицеп в Донецке, купить фаркоп в ЛНР, купить фаркоп в ДНР, купить фаркоп в Луганске, купить фаркоп в Донецке, Продажа легковых прицепов, продажа прицепов, Фаркоп, тсу, прицеп, легковой прицеп,подкатное колесо, опорное колесо прицепа, блок согласования, электрика фаркопа, опорные стойки прицепа, прицеп бортовой, прицеп лодочный, коммерческий прицеп, прицеп эвакуатор, прицеп для катера, прицеп для лодок пвх, прицеп для гидроцикла, прицеп самосвальный, прицеп оцинкованный, прицеп мзса, купить прицеп в Ростове, купить прицеп в Ростове на Дону, купить фаркоп в Ростове, купить фаркоп в Ростове на Дону, купить прицеп в Аксае, купить фаркоп в Аксае
https://pricepi.su/
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB