Loki
Март 29, 2013 13:51:55
Patrik, точно по центру исходя из моего предыдущего примера будет так:
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
class ModalWind(QtGui.QWidget):
def __init__(self, parent=None):
super(ModalWind, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint)
self.setWindowModality(QtCore.Qt.WindowModal)
self.setWindowTitle("Модальное окно")
butt_hide = QtGui.QPushButton('Закрыть модальное окно')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_hide)
self.setLayout(vbox)
butt_hide.clicked.connect(self.close)
class MainWind(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWind, self).__init__(parent)
self.setWindowTitle("Главное окно")
self.resize(400, 200)
butt_show = QtGui.QPushButton('Показать модальное окно')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_show)
self.setLayout(vbox)
butt_show.clicked.connect(self.on_show)
def on_show(self):
win = ModalWind(self)
win.resize(200, 100)
# сначало отображаем окно за пределами видимости
win.move(win.width()*-2,0)
# обязательно отображаем, потому-что, только так frameSize()
# вернет коректное значение
win.show()
x = self.x()+(self.frameSize().width()-win.frameSize().width())//2
y = self.y()+(self.frameSize().height()-win.frameSize().height())//2
win.move(x, y)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
window = MainWind()
window.show()
sys.exit(app.exec_())
Patrik
Март 31, 2013 17:18:37
Loki А если нужно несколько модальных окно, то просто вводим новый классы class ModalWind1, 2 т.п?
Loki
Апрель 1, 2013 10:46:20
Все зависит от твоей задачи…
К примеру, если бы у тебя стояла задача запускать модальные окна из одного основного, и чтобы все модальные окна запускались обязательно по центру родителя, то разумно было бы ввести в основной класс новый метод, которому бы передавались ссылки на сами модальные окна, и уже в этом методе двигать их…
P.S. Просто совет… старайся своим классам давать емкие, но достаточно развернутые имена, исходя из их функционала… Modal1, Modal2 такие названия лучше использовать только в примерах, а не в своих программах…
Patrik
Апрель 1, 2013 11:11:53
У меня в программе всего будет три модальных окна:
1) о программе
2) окошко информация
3) окошко с ошибкой
Все будут вылетать по центру.
Имена классам я стараюсь давать названия, чтобы соответсвовали назначению.
Еще попутный вопрос появился, к примеру в окне с ошибкой, перед текстом хочу вставить картинку восклицательный знак.
Я правильно понимаю, что нужно поставить label и в качестве фона задать ему картинку?
Loki
Апрель 1, 2013 12:47:51
Мне кажется лучше воспользоваться QtGui.QMessageBox.warning(<родитель>,<Текст сообщения>), метод возвращает код нажатой кнопки, если укажешь родителя будет центроваться относительно его и будет его модалить(насколько я помню)…
Не понравится этот виджет посмотри QMessageBox.
Patrik
Апрель 1, 2013 13:50:40
Я думал взять виджет QWidget в нем вывести картинку label.setPixmap(pixmap) и label с описанием ошибки и кнопку закрыть. Единственное, что я не понимаю. К примеру класс назову
class Error(QtGui.QWidget), если модифицировать твой пример:
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
class Error(QtGui.QWidget):
def __init__(self, parent=None):
super(Error, self).__init__(parent)
...
class ModalWind(QtGui.QWidget):
def __init__(self, parent=None):
super(ModalWind, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint)
self.setWindowModality(QtCore.Qt.WindowModal)
self.setWindowTitle("Модальное окно")
butt_hide = QtGui.QPushButton('Закрыть модальное окно')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_hide)
self.setLayout(vbox)
butt_hide.clicked.connect(self.close)
class MainWind(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWind, self).__init__(parent)
self.setWindowTitle("Главное окно")
self.resize(400, 200)
butt_show = QtGui.QPushButton('Показать модальное окно')
butt_error = QtGui.QPushButton('Показать окно об ошибке')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_show)
vbox.addWidget(butt_error)
self.setLayout(vbox)
butt_show.clicked.connect(self.on_show)
butt_error.clicked.connect(self.on_show)
def on_show(self):
win = ModalWind(self)
win.resize(200, 100)
# сначало отображаем окно за пределами видимости
win.move(win.width()*-2,0)
# обязательно отображаем, потому-что, только так frameSize()
# вернет коректное значение
win.show()
x = self.x()+(self.frameSize().width()-win.frameSize().width())//2
y = self.y()+(self.frameSize().height()-win.frameSize().height())//2
win.move(x, y)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
window = MainWind()
window.show()
sys.exit(app.exec_())
Как класс Error передать методу on_show?
Loki
Апрель 1, 2013 14:43:14
Patrik, я практически ничего не понял, что ты хочешь сделать…
Обьясни по подробнее, что ты хочешь сделать, и как это должно работать.
Из того что ты написал я понял, что тебе лучше использовать МэсэджБоксы для вывода сообщения об ошибке…
По поводу передать класс методу…Твой класс находится в глобальной области видимости имен, ты его можешь вызвать непосредственно внутри метода другого класса…или я что-то не так понял.
Loki
Апрель 1, 2013 14:56:02
Если ты хотел на нажатие другой кнопки повесить окно Ошибки, то:
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
class Error(QtGui.QWidget):
def __init__(self, parent=None):
super(Error, self).__init__(parent)
...
class ModalWind(QtGui.QWidget):
def __init__(self, parent=None):
super(ModalWind, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint)
self.setWindowModality(QtCore.Qt.WindowModal)
self.setWindowTitle("Модальное окно")
butt_hide = QtGui.QPushButton('Закрыть модальное окно')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_hide)
self.setLayout(vbox)
butt_hide.clicked.connect(self.close)
class MainWind(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWind, self).__init__(parent)
self.setWindowTitle("Главное окно")
self.resize(400, 200)
butt_show = QtGui.QPushButton('Показать модальное окно')
butt_error = QtGui.QPushButton('Показать окно об ошибке')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_show)
vbox.addWidget(butt_error)
self.setLayout(vbox)
butt_show.clicked.connect(self.on_show)
butt_error.clicked.connect(self.on_show_error)
def on_show(self):
win = ModalWind(self)
win.resize(200, 100)
# сначало отображаем окно за пределами видимости
win.move(win.width()*-2,0)
# обязательно отображаем, потому-что, только так frameSize()
# вернет коректное значение
win.show()
x = self.x()+(self.frameSize().width()-win.frameSize().width())//2
y = self.y()+(self.frameSize().height()-win.frameSize().height())//2
win.move(x, y)
def on_show_error(self):
win_er = Error(self)
...
win_er.show()
x = self.x()+(self.frameSize().width()-win_er.frameSize().width())//2
y = self.y()+(self.frameSize().height()-win_er.frameSize().height())//2
win_er.move(x, y)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
window = MainWind()
window.show()
sys.exit(app.exec_())
Patrik
Апрель 1, 2013 18:45:36
А есть возможность объединить 2 метода on_show и on_show_error они же дублируют друг дргуга?
Loki
Апрель 2, 2013 07:36:54
Patrik, Есть и такой, но мне этот способ кажется не очень предпочтительным.
Я еще раз повторяю зачем изобретать велосипед, если в Qt уже есть QMessageBox?
Но если ты не ишешь легких путей, то:
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
# я немного дописал твой класс, чтобы проще было проверить работоспособность
class Error(QtGui.QWidget):
def __init__(self, parent=None):
super(Error, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint)
self.setWindowModality(QtCore.Qt.WindowModal)
self.setWindowTitle('Окно с ошибкой')
butt_hide = QtGui.QPushButton('Закрыть окно c ошибкой')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_hide)
self.setLayout(vbox)
butt_hide.clicked.connect(self.close)
class ModalWind(QtGui.QWidget):
def __init__(self, parent=None):
super(ModalWind, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint)
self.setWindowModality(QtCore.Qt.WindowModal)
self.setWindowTitle("Модальное окно")
butt_hide = QtGui.QPushButton('Закрыть модальное окно')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_hide)
self.setLayout(vbox)
butt_hide.clicked.connect(self.close)
class MainWind(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWind, self).__init__(parent)
self.setWindowTitle("Главное окно")
self.resize(400, 200)
butt_show = QtGui.QPushButton('Показать модальное окно')
butt_error = QtGui.QPushButton('Показать окно об ошибке')
vbox = QtGui.QVBoxLayout()
vbox.addWidget(butt_show)
vbox.addWidget(butt_error)
self.setLayout(vbox)
# здесь на сигнал вместо ссылки вешаешь лямбду с параметром
butt_show.clicked.connect(lambda: self.on_show(ModalWind))
butt_error.clicked.connect(lambda: self.on_show(Error))
def on_show(self, widget):
win = widget(self)
win.resize(200, 100)
# сначало отображаем окно за пределами видимости
win.move(win.width()*-2,0)
# обязательно отображаем, потому-что, только так frameSize()
# вернет коректное значение
win.show()
x = self.x()+(self.frameSize().width()-win.frameSize().width())//2
y = self.y()+(self.frameSize().height()-win.frameSize().height())//2
win.move(x, y)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
window = MainWind()
window.show()
sys.exit(app.exec_())