Уведомления

Группа в Telegram: @pythonsu

#1 Май 8, 2021 15:22:06

wladimirbel
Зарегистрирован: 2021-05-08
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск окна на PyQt5 из Tkinter

Есть 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()

Отредактировано wladimirbel (Май 8, 2021 15:23:25)

Офлайн

#2 Май 9, 2021 22:59:06

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Запуск окна на PyQt5 из Tkinter

> Запуск окна на PyQt5 из Tkinter

Забудь про Tkinter.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#3 Май 10, 2021 07:51:16

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Запуск окна на PyQt5 из Tkinter

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 в отдельном процессе,(не потоке!). тогда окно ткинтера не будет замораживаться. Но тогда вам придеться заморачиваться с передачей данных между процессами.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Май 10, 2021 07:59:10)

Офлайн

#4 Сен. 17, 2021 10:19:01

makis13
От: Ростов на Дону
Зарегистрирован: 2021-09-17
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск окна на PyQt5 из Tkinter

Продажа легковых прицепов и фаркопов в Ростове на Дону
Купить прицеп в ЛНР, Купить прицеп в ДНР, Купить прицеп в ДНР, купить прицеп в Луганске, купить прицеп в Донецке, купить фаркоп в ЛНР, купить фаркоп в ДНР, купить фаркоп в Луганске, купить фаркоп в Донецке, Продажа легковых прицепов, продажа прицепов, Фаркоп, тсу, прицеп, легковой прицеп,подкатное колесо, опорное колесо прицепа, блок согласования, электрика фаркопа, опорные стойки прицепа, прицеп бортовой, прицеп лодочный, коммерческий прицеп, прицеп эвакуатор, прицеп для катера, прицеп для лодок пвх, прицеп для гидроцикла, прицеп самосвальный, прицеп оцинкованный, прицеп мзса, купить прицеп в Ростове, купить прицеп в Ростове на Дону, купить фаркоп в Ростове, купить фаркоп в Ростове на Дону, купить прицеп в Аксае, купить фаркоп в Аксае
https://pricepi.su/



Продажа легковых прицепов и фаркопов в Ростове на Дону
Купить прицеп в ЛНР, Купить прицеп в ДНР, Купить прицеп в ДНР, купить прицеп в Луганске, купить прицеп в Донецке, купить фаркоп в ЛНР, купить фаркоп в ДНР, купить фаркоп в Луганске, купить фаркоп в Донецке, Продажа легковых прицепов, продажа прицепов, Фаркоп, тсу, прицеп, легковой прицеп,подкатное колесо, опорное колесо прицепа, блок согласования, электрика фаркопа, опорные стойки прицепа, прицеп бортовой, прицеп лодочный, коммерческий прицеп, прицеп эвакуатор, прицеп для катера, прицеп для лодок пвх, прицеп для гидроцикла, прицеп самосвальный, прицеп оцинкованный, прицеп мзса, купить прицеп в Ростове, купить прицеп в Ростове на Дону, купить фаркоп в Ростове, купить фаркоп в Ростове на Дону, купить прицеп в Аксае, купить фаркоп в Аксае
https://pricepi.su/

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version