Найти - Пользователи
Полная версия: PyQt создание всплывающего окна
Начало » GUI » PyQt создание всплывающего окна
1 2
modos189
Не пойму как создать новое окно. Вернее настроить его. Создать получается, но в тот же момент оно пропадает.

class Ui_MainWindowq(object):
    def setupUi(self, MainWindowq):
        MainWindowq.setObjectName("MainWindowq")
        MainWindowq.resize(212, 145)
        self.centralwidget = QtGui.QWidget(MainWindowq)
        self.centralwidget.setObjectName("centralwidget")
        MainWindowq.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(MainWindowq)

это пустое окно, для теста.

Вызываю после сигнала из старого окна:

		MainWindow = QtGui.QMainWindow()
		ui = Ui_MainWindowq()
		ui.setupUi(MainWindow)
		MainWindow.show()

Подскажите пожалуйста что надо исправить, чтобы оно не пропадало в тот же момент?
reclosedev
modos189
Вызываю после сигнала из старого окна:
Не очень понятно откуда оно вызывается. Приложите полный пример. Но, предполагаю, проблема в том, что MainWindow создается без задания ему родителя (parent) и на него не сохраняется ссылка. Еще возможно не запускается event loop через exec_.

Кстати, еще в прошлом вашем топике заметил, что вероятно вы не правильно используете сгенерированный в QtDesigner код. Вносить в него изменения нет смысла, файл перезаписывается каждый раз.

В документации есть раздел по использованию сгенерированного кода Using Qt Designer
Попробуйте сделать как там, проблемы должны пропасть.
modos189
код программы:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import platform
import os
import ConfigParser
import urllib
import getpass
import shutil
import datetime
from PyQt4 import QtCore, QtGui
server = "http://modostroi.ru/mpm/"
urllib.urlretrieve(server+'menecraft_info_package.ini', filename='menecraft_info_package.ini') # скачиваем список пакетов
pth = os.path.expanduser('~')+'/' # путь до домашней папки
#mkdir(pth+'.minecraft')
class Ui_MainWindow(object):
	def setupUi(self, MainWindow):
		MainWindow.setObjectName("MainWindow")
		MainWindow.resize(500, 476)
		self.centralwidget = QtGui.QWidget(MainWindow)
		self.centralwidget.setObjectName("centralwidget")
		self.tabWidget = QtGui.QTabWidget(self.centralwidget)
		self.tabWidget.setGeometry(QtCore.QRect(0, 0, 501, 431))
		self.tabWidget.setObjectName("tabWidget")
		self.tab = QtGui.QWidget()
		self.tab.setObjectName("tab")
		self.listWidget = QtGui.QListWidget(self.tab)
		self.listWidget.setGeometry(QtCore.QRect(10, 10, 171, 381))
		self.listWidget.setToolTip("")
		self.listWidget.setAutoFillBackground(True)
		self.listWidget.setObjectName("listWidget")
		
		menecraft_list_package = ConfigParser.ConfigParser()
		menecraft_list_package.read('menecraft_info_package.ini')
		f = menecraft_list_package.sections()
		for line in f:
			QtGui.QListWidgetItem(self.listWidget)
		
		QtCore.QObject.connect(self.listWidget, QtCore.SIGNAL("clicked(QModelIndex)"),	self.desc)
		
		self.pushButton_1 = QtGui.QPushButton(self.tab)
		self.pushButton_1.setGeometry(QtCore.QRect(190, 350, 201, 41))
		self.pushButton_1.setObjectName("pushButton_1")
		QtCore.QObject.connect(self.pushButton_1, QtCore.SIGNAL("clicked()"),	self.select_minecraft_version)
		self.pushButton_2 = QtGui.QPushButton(self.tab)
		self.pushButton_2.setGeometry(QtCore.QRect(400, 350, 91, 41))
		self.pushButton_2.setObjectName("pushButton_2")
		self.textBrowser = QtGui.QTextBrowser(self.tab)
		self.textBrowser.setGeometry(QtCore.QRect(190, 11, 301, 331))
		self.textBrowser.setObjectName("textBrowser")
		self.tabWidget.addTab(self.tab, "")
		self.tab_2 = QtGui.QWidget()
		self.tab_2.setObjectName("tab_2")
		self.tabWidget.addTab(self.tab_2, "")
		MainWindow.setCentralWidget(self.centralwidget)
		self.menubar = QtGui.QMenuBar(MainWindow)
		self.menubar.setGeometry(QtCore.QRect(0, 0, 500, 25))
		self.menubar.setObjectName("menubar")
		self.menu675 = QtGui.QMenu(self.menubar)
		self.menu675.setObjectName("menu675")
		MainWindow.setMenuBar(self.menubar)
		self.statusbar = QtGui.QStatusBar(MainWindow)
		self.statusbar.setObjectName("statusbar")
		MainWindow.setStatusBar(self.statusbar)
		self.action7686 = QtGui.QAction(MainWindow)
		self.action7686.setObjectName("action7686")
		self.action = QtGui.QAction(MainWindow)
		self.action.setObjectName("action")
		self.menu675.addAction(self.action7686)
		self.menu675.addAction(self.action)
		self.menubar.addAction(self.menu675.menuAction())
		self.retranslateUi(MainWindow)
		self.tabWidget.setCurrentIndex(0)
		QtCore.QMetaObject.connectSlotsByName(MainWindow)
	def retranslateUi(self, MainWindow):
		MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
		__sortingEnabled = self.listWidget.isSortingEnabled()
		self.listWidget.setSortingEnabled(False)
		
		menecraft_list_package = ConfigParser.ConfigParser()
		menecraft_list_package.read('menecraft_info_package.ini')
		f = menecraft_list_package.sections()
		i=0
		for line in f:
			self.listWidget.item(i).setText(QtGui.QApplication.translate("MainWindow", line, None, QtGui.QApplication.UnicodeUTF8))
			i+=1
		self.listWidget.setSortingEnabled(__sortingEnabled)
		self.pushButton_1.setText(QtGui.QApplication.translate("MainWindow", "Установить", None, QtGui.QApplication.UnicodeUTF8))
		self.pushButton_2.setText(QtGui.QApplication.translate("MainWindow", "Подробнее", None, QtGui.QApplication.UnicodeUTF8))
		self.textBrowser.setHtml(QtGui.QApplication.translate("MainWindow", "<!DOCTYPE html>\n<html><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">слева выберите версию для установки</body></html>", None, QtGui.QApplication.UnicodeUTF8))
		self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("MainWindow", "Minecraft", None, QtGui.QApplication.UnicodeUTF8))
		self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QtGui.QApplication.translate("MainWindow", "Модификации", None, QtGui.QApplication.UnicodeUTF8))
		self.menu675.setTitle(QtGui.QApplication.translate("MainWindow", "Справка", None, QtGui.QApplication.UnicodeUTF8))
		self.action7686.setText(QtGui.QApplication.translate("MainWindow", "О программе", None, QtGui.QApplication.UnicodeUTF8))
		self.action.setText(QtGui.QApplication.translate("MainWindow", "Как пользоваться", None, QtGui.QApplication.UnicodeUTF8))
		
		
		
		
		
		
	def select_minecraft_version(self):
		for item in self.listWidget.selectedItems():
			select_version = item.text()
		select_version = str(select_version)
		mkdir('cache')
		mkdir('cache/minecraft')
		mkdir('cache/minecraft/temp')
		
		menecraft_info_package = ConfigParser.ConfigParser()
		menecraft_info_package.read('menecraft_info_package.ini')
		
		url = menecraft_info_package.get(select_version, 'url')
		filename = menecraft_info_package.get(select_version, 'filename')
		
		print 'качаем'
		
		urllib.urlretrieve(url, filename='cache/minecraft/'+filename) # качаем майнкрафт
		
		os.system('cp cache/minecraft/1_0_0_reliase_client.zip cache/minecraft/temp/1_0_0_reliase_client.zip')
		qazwsx = filename.split('.')
		if (qazwsx[1]=='zip'):
			os.system('cd cache/minecraft/temp/ && unzip '+filename)
		elif (qazwsx[1]=='7z'):
			os.system('cd cache/minecraft/temp/ && 7z x '+filename)
		
		backup()
		
		os.system('mv cache/minecraft/temp/.minecraft/bin '+pth+'.minecraft/bin')
		
		remove('cache/minecraft/temp/')
		
	def desc(self, QModelIndex):
		for item in self.listWidget.selectedItems():
			select_version = item.text()
		menecraft_info_package = ConfigParser.ConfigParser()
		menecraft_info_package.read('menecraft_info_package.ini')
		desc = menecraft_info_package.get(str(select_version), 'desc')
		
		self.textBrowser.setHtml(QtGui.QApplication.translate("MainWindow", "<!DOCTYPE html>\n<html><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"+desc+"</body></html>", None, QtGui.QApplication.UnicodeUTF8))
# --------------------- ниже пытаюсь открыть новое окно ----------------------------
		MainWindow = QtGui.QMainWindow()
		ui = Ui_MainWindowq()
		ui.setupUi(MainWindow)
		MainWindow.show()
class Ui_MainWindowq(object):
    def setupUi(self, MainWindowq):
        MainWindowq.setObjectName("MainWindowq")
        MainWindowq.resize(212, 145)
        self.centralwidget = QtGui.QWidget(MainWindowq)
        self.centralwidget.setObjectName("centralwidget")
        MainWindowq.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(MainWindowq)
# --------------------- дальше работающий код ----------------------------
def remove(patch):
	if os.path.exists(patch)==True:
		os.system('rm -R '+patch)
def mkdir(patch):
	if os.path.exists(patch)==False:
		os.mkdir(patch)
def backup():
	if os.path.exists(pth+'.minecraft/bin'):
		mkdir(pth+'.minecraft/backup')
		os.rename(pth+'.minecraft/bin', pth+'.minecraft/backup/'+str(datetime.now()))
if __name__ == "__main__":
	app = QtGui.QApplication(sys.argv)
	MainWindow = QtGui.QMainWindow()
	ui = Ui_MainWindow()
	ui.setupUi(MainWindow)
	MainWindow.show()
	sys.exit(app.exec_())

для теста функция вызывается при выборе любого пункта в списке.

“Вносить в него изменения нет смысла, файл перезаписывается каждый раз.”
после изменений в QtDesigner я провожу сверку со своей программой и переношу только новое

пытался сделать по аналогии с первым окном
reclosedev
Да, дело в то, что ссылка на MainWindow не сохранена.
Очень простое, но не совсем правильное решение:
# --------------------- ниже пытаюсь открыть новое окно ----------------------------
		MainWindow = QtGui.QMainWindow()
		ui = Ui_MainWindowq()
		ui.setupUi(MainWindow)
		MainWindow.show()
		self.second_window = MainWindow
сохраняем ссылку на созданное окно, чтобы оно не удалялось сборщиком мусора и соответственно не закрывалось.

modos189
“Вносить в него изменения нет смысла, файл перезаписывается каждый раз.”
после изменений в QtDesigner я провожу сверку со своей программой и переношу только новое
Это же очень не удобно.

Правильным бы было реорганизовать ваш код, так как советуют в документации (ссылка в предыдущем посте)

Т.е. у вас есть два ui файла, например main_window.ui, second_window.ui
после pyuic они превращаются, допустим, в ui_main_window.py, ui_second_window.py

Весь код программы вы выносите в отдельный файл, например, application.py:
import sys
from PyQt4 import QtCore, QtGui
from ui_main_window import Ui_MainWindow
from ui_second_window import Ui_SecondWindow
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
         QtGui.QMainWindow.__init__(self)
         self.setupUi(self)
         .....
    # функции обработки событий и т.п.
    desc(self, QModelIndex):
        #.....
        second_window = SecondWindow(parent=self) # задаем родителем себя
        # или просто сохраняем в себе ссылку на дочернее окно
        #self.second_window = SecondWindow()
        second_window.show()
 
class SecondWindow(QtGui.QMainWindow, Ui_SecondWindow):
    def __init__(self, parent=None):
         QtGui.QMainWindow.__init__(self, parent)
         self.setupUi(self)
    # ... возможно функции для обработки нажатий и т.п.
# ... другие функции
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

После этого вы можете спокойно менять интерфейс в QtDesigner и перегенерировать файлы ui_main_window.py, ui_second_window.py. Весь код, будет в application (ну, в простейшем случае).

P.S. Здесь показан вариант со множественным наследованием, зачастую удобнее вариант с сохранением ui в self.ui (см. документацию)

upd: parent не передавался в QtGui.QMainWindow.__init__()
modos189
Спасибо

На счёт вывода интерфейса в отдельный файл - да, спасибо, так и сделаю, но немного позже, когда немного освоюсь пока что хочется видеть всю программу сразу, потому что большинство изменений делаю методом тыка
modos189
а как в новое окно передать какой-нибудь параметр? к примеру мне надо передать select_version
reclosedev
modos189
а как в новое окно передать какой-нибудь параметр? к примеру мне надо передать select_version
Можно через аргумент __init__:
class SecondWindow(QtGui.QMainWindow, Ui_SecondWindow):
    def __init__(self, select_version, parent=None):
         QtGui.QMainWindow.__init__(self, parent)
         self.select_version = select_version
         self.setupUi(self)
 
    def some_method(self):
        do_something_with(self.select_version)
modos189
а без выноса дизайна в файл как это сделать? у меня

class Ui_SecondWindow(object):
	def setupUi(self, MinecraftDownloadWindow):

аргумент __init__ не использую
reclosedev
modos189
а без выноса дизайна в файл как это сделать?
Можно в Ui_SecondWindow добавить:
class Ui_SecondWindow(object):
def __init__(self, select_version):
self.select_version = select_version
Но непонятно, что потом с этим будет. Давно бы уже перенесли.
modos189
сделал извращённо, но почти работает.

qt, в отличии от самого питона, мне не нравится что тут всё не очевидно

вот и не хочу пока в отдельный файл ложить дизайн, потому что даже если скопирую пример то не знаю как потом массивом создавать строки в списке и вообще большое количество разных __init__ меня пугает

у меня (надеюсь, теперь небольшая) проблемка осталась - окно появляется только после выполнения всех операций. вот код:

class Ui_MinecraftDownloadWindow(object):
	def __init__(self, select_version):
		self.select_version = select_version
	def setupUi(self, MinecraftDownloadWindow):
		MinecraftDownloadWindow.setObjectName("MinecraftDownloadWindow")
		MinecraftDownloadWindow.resize(312, 132)
		self.centralwidget = QtGui.QWidget(MinecraftDownloadWindow)
		self.centralwidget.setObjectName("centralwidget")
		self.progressBar_1 = QtGui.QProgressBar(self.centralwidget)
		self.progressBar_1.setGeometry(QtCore.QRect(10, 90, 291, 31))
		self.progressBar_1.setProperty("value", 0)
		self.progressBar_1.setObjectName("progressBar_1")
		MinecraftDownloadWindow.setCentralWidget(self.centralwidget)
		QtCore.QMetaObject.connectSlotsByName(MinecraftDownloadWindow)
		self.d(self.select_version)
	def loadProgress(self, bl, blsize, size):
		p = float(min(bl*blsize, size)) / size * 100
		self.progressBar_1.setProperty("value", p)
	def d(self, select_version):
		self.progressBar_1.setProperty("value", 80)
		menecraft_info_package = ConfigParser.ConfigParser()
		menecraft_info_package.read('menecraft_info_package.ini')
		url = menecraft_info_package.get(self.select_version, 'url')
		filename = menecraft_info_package.get(self.select_version, 'filename')
		urllib.urlretrieve(url, 'cache/minecraft/'+filename, self.loadProgress) # качаем майнкрафт

где может быть ошибка?
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