Форум сайта python.su
Делаю на Qt тестовую программу (в смысле, для прохождения тестов студентами). Отрисовываю первое окно, куда студент вбивает свое имя, группу, выбирает тему теста, жмет кнопку “ОК”. Далее надо отрисовать окно собственно с самим тестом.
Внимание, вопрос: как лучше отрисовать второе окно?
Мои варианты на вскидку:
1. Запустить обработку другого файла, в котором будет класс нового окна
2. Реорганизовать текущее окно путем удаление старых и добавления новых виджетов
3. В этом же файле организовать еще один класс с окном
4. Что-нибудь другое
Офлайн
А зачемтебе вообще многооконный интерфейс? Имхо, это не очень удобно. Лучше бы что-то типа визарда. Но классы отображающие окно логина, теста и результатов, определенно разные, один класс мусолить разными задачами не стоит. Один элемент интерфейса - один класс.
А остальное, это уже на вкуц и свет.
Отредактировано (Дек. 8, 2009 17:15:54)
Офлайн
> Лучше бы что-то типа визарда
И как это организовать?
Тупо разными классами мусолить одно и то же окно?
Офлайн
Тупо у окна (если это QMainWindow) сменять один centralWidget (логин, вопросы, результаты) на другой на каждом шаге визарда. Это как вариант.
Офлайн
Хорошо, почитаю про этот centralWidget (я так понимаю, что он может являться несколькими обычными виджетами?). Спасибо
UPD:
Оказывается, я как последний неудачник рисовал окно как QWidget, а не QMainWindow. Понятное дело, что теперь надо просто создать класс, который будет наследоваться от QMainWindow, и в него пихать centralWidget. Вопрос теперь в том, как это грамотно сделать. Чувствую, что придется реорганизовывать и рефакторить весь код, но хочу лишний раз посоветоваться: что с этим делать? Код прилагается
# -*- coding: utf-8 -*-
import handler
import sys
import base64
from PyQt4 import QtGui, QtCore
class Window (QtGui.QWidget):
def __init__ (self, parent = None):
QtGui.QWidget.__init__(self, parent)
self.resize(500, 150)
self.center()
self.data = handler.read_file('themes.yaml')
self.create_widgets()
self.connect_signals()
def center(self):
screen = QtGui.QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width() - size.width()) / 2,\
(screen.height() - size.height()) / 2)
def create_widgets (self):
self.name_label = QtGui.QLabel(u'ФИО:')
self.group_label = QtGui.QLabel(u'Группа:')
self.name_input = QtGui.QLineEdit()
self.group_input = QtGui.QLineEdit()
self.group_input.setMaxLength(2)
self.subject_box = QtGui.QComboBox()
self.theme_box = QtGui.QComboBox()
self.ok_but = QtGui.QPushButton(u'Сохранить лог')
self.add_subjects()
#self.theme_box.hide()
#self.ok_but.hide()
sizer = QtGui.QGridLayout()
sizer.addWidget(self.name_label, 0, 0)
sizer.addWidget(self.name_input, 0, 1)
sizer.addWidget(self.group_label, 0, 2)
sizer.addWidget(self.group_input, 0, 3)
sizer.addWidget(self.subject_box, 1, 0, 1, 2)
sizer.addWidget(self.theme_box, 1, 2, 1, 2)
sizer.addWidget(self.ok_but, 2, 0, 1, 4)
self.setLayout(sizer)
def add_subjects (self):
for subject in self.data:
self.subject_box.addItem('%s' % subject)
def add_themes (self, subject):
for theme in self.data[subject]:
self.theme_box.addItem('%s' % theme)
def connect_signals (self):
self.connect(self.subject_box, QtCore.SIGNAL('activated(QString)'), self.selected_subject)
self.connect(self.ok_but, QtCore.SIGNAL('clicked()'), self.on_click)
def on_click (self):
#selected_subject = '%s' % self.subject_box.currentText().toUtf8()
selected_theme = '%s' % self.theme_box.currentText().toUtf8()
student_name = '%s' % self.name_input.text().toUtf8()
student_group = '%s' % self.group_input.text().toUtf8()
handler.Loger.save_log(selected_theme, student_name, student_group)
def selected_subject (self):
self.theme_box.clear()
self.theme_box.addItem(u'Выберите тему')
curr_subject = '%s' % self.subject_box.currentText().toUtf8()
curr_subject = curr_subject.decode('utf-8')
self.add_themes(curr_subject)
#self.theme_box.show()
#self.ok_but.show()
app = QtGui.QApplication(sys.argv)
dt = Window()
dt.show()
app.exec_()
Отредактировано (Дек. 8, 2009 18:14:44)
Офлайн
FLeXдля таких целей лучше использовать QStackedWidget
Отрисовываю первое окно, куда студент вбивает свое имя, группу, выбирает тему теста, жмет кнопку “ОК”. Далее надо отрисовать окно собственно с самим тестом.
Офлайн
Можно использовать любой виджет в роли окна, не обязательно QMainWindow. Если тебе не нужно что либо из , то можно и QWidget делать главным окном. Просто выделяй каждую сущность в отдельный класс, в случае с UI это совсем просто ввиду наглядности, и делай ее самостоятельным виджетом. Если создаваемая форма достаточно статична и имеет много элементов (пример: окно настроек программы), то можно нарисовать ее в Designer.
Рефакторить пока особо нечего. Я так понял, у тебя сейчас реализовано окно логина (регистрации или что-то типа того). Я бы выделил все что относится конкретно к нему из главного окна в отдельный виджет (класс). Потом так же отдельными классами все остальные экраны программы, которые будут являться параметрами (properties или дочерями) главного окна. И у них будут кнопочки, которые шлют сигналы о том, что работа с текущим экраном закончена. А твой Window может реализовать связь между ними. Он показывает текущий экран (отображает текущий виджет и скрывает остальные), принимает от них нужный сигнал сигнал и делает видимым следующий дочерний виджет.
Получится простейшая реализация интерфейса в стиле “wizard”. Еще, кстати, можно посмотреть в сторону виджета QWizard, может он подойдет :)
Но если очень хочется, то можно сделать и многооконный интерфейс, тогда просто каждый экран не будет иметь родительского виджета и будет вылезать в отдельном окне.
Офлайн
для таких целей лучше использовать QStackedWidgetСпасибо, почитаю
Отредактировано (Дек. 8, 2009 21:52:24)
Офлайн
FLeXнапример так при первом клике первый пункт сразу удалится:
UPD:
Чтобы уж не заводить отдельную тему, глупый вопрос “на засыпку”: Делаю комбобокс. Есть ли встроенные решения в Qt, которые позволят добавить один пункт (верхний) пустой или с надписью “Выберите что-нибудь”. Т.е. он есть в списке до тех пор, пока пользователь не выберет что-нибудь конкретное из предложенных вариантов
self.combobox = QtGui.QComboBox(self)
self.combobox.addItems(["", "asdfsd", "asdfsdaf", "asdfsadf"])
self.connect(self.combobox, QtCore.SIGNAL("highlighted(QString)"), self.firstClick)
def firstClick(self, text):
if not text:
self.combobox.removeItem(0)
Отредактировано (Дек. 9, 2009 01:23:18)
Офлайн
Спасибо за решение. Собственно, до этого тоже уже дошел сам, но надеялся, что есть-таки какой-нибудь дополнительный параметр, который я в манах и туторах проглядел
Офлайн