예제 #1
0
class RadioBooleanFilter(QWidget, Control):

    """ Boolean filter (Only/Exclude)
    """

    def __init__(self, tree, dataset, master, parent=None):
        QWidget.__init__(self, parent)
        Control.__init__(self, tree, dataset, master)

        self.setLayout(QVBoxLayout())
        self.buttonGroup = QButtonGroup(self)
        self.values = []
        for i, option in enumerate(tree.subelements_top("Option")):
            rb = QRadioButton(option.displayName, self)
            self.buttonGroup.addButton(rb)
            self.buttonGroup.setId(rb, i)
            self.layout().addWidget(rb)
            self.values.append(option.value)
        self.buttonGroup.button(0).setChecked(True)

    def value(self):
        return {"excluded": "%i" % self.buttonGroup.checkedId()}

    def get_filter(self):
        return self.tree.internalName, self.value()

    def query(self):
        return [("Filter", self.tree, self.value())]

    def setControlValue(self, name, value):
        for i, v in enumerate(self.values):
            if v == value:
                button = self.buttonGroup.button(i)
                button.setChecked(True)
                break
예제 #2
0
class RadioBooleanFilter(QWidget, Control):

    """ Boolean filter (Only/Exclude)
    """

    def __init__(self, tree, dataset, master, parent=None):
        QWidget.__init__(self, parent)
        Control.__init__(self, tree, dataset, master)

        self.setLayout(QVBoxLayout())
        self.buttonGroup = QButtonGroup(self)
        self.values = []
        for i, option in enumerate(tree.subelements_top("Option")):
            rb = QRadioButton(option.displayName, self)
            self.buttonGroup.addButton(rb)
            self.buttonGroup.setId(rb, i)
            self.layout().addWidget(rb)
            self.values.append(option.value)
        self.buttonGroup.button(0).setChecked(True)

    def value(self):
        return {"excluded": "%i" % self.buttonGroup.checkedId()}

    def get_filter(self):
        return self.tree.internalName, self.value()

    def query(self):
        return [("Filter", self.tree, self.value())]

    def setControlValue(self, name, value):
        for i, v in enumerate(self.values):
            if v == value:
                button = self.buttonGroup.button(i)
                button.setChecked(True)
                break
예제 #3
0
class TransformationModule(PreprocessorModule):
    DEFAULT_SETTINGS = {
        'is_enabled': True,
        'method': 0,
    }

    PorterStemmer, SnowballStemmer, Lemmatizer = 0, 1, 2
    transformation_values = {
        PorterStemmer: PS,
        SnowballStemmer: SS,
        Lemmatizer: LM,
    }

    transformation_method = 0

    def __init__(self, data):
        data = data or self.DEFAULT_SETTINGS
        PreprocessorModule.__init__(
                self, 'Stemming', True,
                data.get('is_enabled')
        )

        self.group = QButtonGroup(self, exclusive=True)
        for method in [
            self.PorterStemmer,
            self.SnowballStemmer,
            self.Lemmatizer
        ]:
            rb = QRadioButton(
                    self,
                    text=self.transformation_values[method].name
            )
            self.add_to_content_area(rb)
            self.group.addButton(rb, method)
        self.group.buttonClicked.connect(self.group_button_clicked)

        # Restore the previous state, after starting off the layout.
        self.restore_data(data)

    def group_button_clicked(self):
        self.transformation_method = self.group.checkedId()
        self.notify_on_change()

    def restore_data(self, data):
        self.transformation_method = data.get('method')
        b = self.group.button(self.transformation_method)
        b.setChecked(True)

    def export_data(self):
        return {
            'is_enabled': self.enabled,
            'method': self.transformation_method,
        }

    def get_pp_setting(self):
        return {
            'transformation': self.transformation_values.get(
                    self.transformation_method
            )
        }
예제 #4
0
class TokenizerModule(PreprocessorModule):
    DEFAULT_SETTINGS = {
        'is_enabled': True,
        'method': 0,
    }

    NLTKTokenizer, NLTKPunctTokenizer, TwitterTokenizer = 0, 1, 2
    tokenizer_values = {
        NLTKTokenizer: 'default',
        NLTKPunctTokenizer: 'no_punct',
        TwitterTokenizer: 'twitter'
    }
    tokenizer_names = {
        NLTKTokenizer: 'NLTK tokenizer',
        NLTKPunctTokenizer: 'NLTK tokenizer (no punctuation)',
        TwitterTokenizer: 'Twitter tokenizer',
    }

    tokenizer_method = 0

    def __init__(self, data):
        data = data or self.DEFAULT_SETTINGS
        PreprocessorModule.__init__(
                self, 'Tokenizer', False,
                data.get('is_enabled')
        )

        self.group = QButtonGroup(self, exclusive=True)
        for method in [
            self.NLTKTokenizer,
            self.NLTKPunctTokenizer,
            self.TwitterTokenizer,
        ]:
            rb = QRadioButton(self, text=self.tokenizer_names[method])
            self.add_to_content_area(rb)
            self.group.addButton(rb, method)
        self.group.buttonClicked.connect(self.group_button_clicked)

        # Restore the previous state, after starting off the layout.
        self.restore_data(data)

    def group_button_clicked(self):
        self.tokenizer_method = self.group.checkedId()
        self.notify_on_change()

    def restore_data(self, data):
        self.tokenizer_method = data.get('method')
        b = self.group.button(self.tokenizer_method)
        b.setChecked(True)

    def export_data(self):
        return {
            'is_enabled': self.enabled,
            'method': self.tokenizer_method,
        }

    def get_pp_setting(self):
        return {
            'tokenizer': self.tokenizer_values.get(self.tokenizer_method)
        }
예제 #5
0
class TokenizerModule(PreprocessorModule):
    DEFAULT_SETTINGS = {
        'is_enabled': True,
        'method': 0,
    }

    NLTKTokenizer, NLTKPunctTokenizer, TwitterTokenizer = 0, 1, 2
    tokenizer_values = {
        NLTKTokenizer: 'default',
        NLTKPunctTokenizer: 'no_punct',
        TwitterTokenizer: 'twitter'
    }
    tokenizer_names = {
        NLTKTokenizer: 'NLTK tokenizer',
        NLTKPunctTokenizer: 'NLTK tokenizer (no punctuation)',
        TwitterTokenizer: 'Twitter tokenizer',
    }

    tokenizer_method = 0

    def __init__(self, data):
        data = data or self.DEFAULT_SETTINGS
        PreprocessorModule.__init__(self, 'Tokenizer', False,
                                    data.get('is_enabled'))

        self.group = QButtonGroup(self, exclusive=True)
        for method in [
                self.NLTKTokenizer,
                self.NLTKPunctTokenizer,
                self.TwitterTokenizer,
        ]:
            rb = QRadioButton(self, text=self.tokenizer_names[method])
            self.add_to_content_area(rb)
            self.group.addButton(rb, method)
        self.group.buttonClicked.connect(self.group_button_clicked)

        # Restore the previous state, after starting off the layout.
        self.restore_data(data)

    def group_button_clicked(self):
        self.tokenizer_method = self.group.checkedId()
        self.notify_on_change()

    def restore_data(self, data):
        self.tokenizer_method = data.get('method')
        b = self.group.button(self.tokenizer_method)
        b.setChecked(True)

    def export_data(self):
        return {
            'is_enabled': self.enabled,
            'method': self.tokenizer_method,
        }

    def get_pp_setting(self):
        return {'tokenizer': self.tokenizer_values.get(self.tokenizer_method)}
예제 #6
0
class TransformationModule(PreprocessorModule):
    DEFAULT_SETTINGS = {
        'is_enabled': True,
        'method': 0,
    }

    PorterStemmer, SnowballStemmer, Lemmatizer = 0, 1, 2
    transformation_values = {
        PorterStemmer: PS,
        SnowballStemmer: SS,
        Lemmatizer: LM,
    }

    transformation_method = 0

    def __init__(self, data):
        data = data or self.DEFAULT_SETTINGS
        PreprocessorModule.__init__(self, 'Stemming', True,
                                    data.get('is_enabled'))

        self.group = QButtonGroup(self, exclusive=True)
        for method in [
                self.PorterStemmer, self.SnowballStemmer, self.Lemmatizer
        ]:
            rb = QRadioButton(self,
                              text=self.transformation_values[method].name)
            self.add_to_content_area(rb)
            self.group.addButton(rb, method)
        self.group.buttonClicked.connect(self.group_button_clicked)

        # Restore the previous state, after starting off the layout.
        self.restore_data(data)

    def group_button_clicked(self):
        self.transformation_method = self.group.checkedId()
        self.notify_on_change()

    def restore_data(self, data):
        self.transformation_method = data.get('method')
        b = self.group.button(self.transformation_method)
        b.setChecked(True)

    def export_data(self):
        return {
            'is_enabled': self.enabled,
            'method': self.transformation_method,
        }

    def get_pp_setting(self):
        return {
            'transformation':
            self.transformation_values.get(self.transformation_method)
        }
예제 #7
0
 def create_rows(self, layout):
     u"""Build the rows of the dialog box"""
     play_button_group = QButtonGroup(self)
     old_play_button_group = QButtonGroup(self)
     for num, entry in enumerate(self.entries_list, 3):
         tt_text = self.build_text_help_label(entry)
         ico_label = QLabel('', self)
         ico_label.setToolTip(tt_text)
         if entry.icon:
             ico_label.setPixmap(QPixmap.fromImage(entry.icon))
         layout.addWidget(ico_label, num, 0)
         tt_label = QLabel(entry.display_word, self)
         tt_label.setToolTip(tt_text)
         layout.addWidget(tt_label, num, 1)
         if self.hide_text:
             tt_label.hide()
         # Play button.
         t_play_button = QPushButton(self)
         play_button_group.addButton(t_play_button, num - 3)
         t_play_button.setToolTip(self.play_help)
         t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png')))
         layout.addWidget(t_play_button, num, self.play_column)
         if self.note[entry.audio_field_name]:
             t_play_old_button = QPushButton(self)
             old_play_button_group.addButton(t_play_old_button, num - 3)
             t_play_old_button.setIcon(
                 QIcon(os.path.join(icons_dir, 'play.png')))
             if not self.hide_text:
                 t_play_old_button.setToolTip(
                     self.note[entry.audio_field_name])
             else:
                 t_play_old_button.setToolTip(self.play_old_help_short)
             layout.addWidget(t_play_old_button, num, self.play_old_column)
         else:
             dummy_label = QLabel('', self)
             dummy_label.setToolTip(self.play_old_empty_line_help)
             layout.addWidget(dummy_label, num, self.play_old_column)
         # The group where we later look what to do:
         t_button_group = QButtonGroup(self)
         t_button_group.setExclusive(True)
         # Now the four buttons
         t_add_button = QPushButton(self)
         t_add_button.setCheckable(True)
         t_add_button.setFlat(True)
         t_add_button.setToolTip(self.add_help_text_short)
         t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png')))
         layout.addWidget(t_add_button, num, self.add_column)
         t_button_group.addButton(t_add_button, Action.Add)
         t_keep_button = QPushButton(self)
         t_keep_button.setCheckable(True)
         t_keep_button.setFlat(True)
         t_keep_button.setToolTip(self.keep_help_text_short)
         t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png')))
         layout.addWidget(t_keep_button, num, self.keep_column)
         t_button_group.addButton(t_keep_button, Action.Keep)
         t_delete_button = QPushButton(self)
         t_delete_button.setCheckable(True)
         t_delete_button.setFlat(True)
         t_delete_button.setToolTip(self.delete_help_text_short)
         t_delete_button.setIcon(
             QIcon(os.path.join(icons_dir, 'delete.png')))
         layout.addWidget(t_delete_button, num, self.delete_column)
         t_button_group.addButton(t_delete_button,  Action.Delete)
         t_blacklist_button = QPushButton(self)
         t_blacklist_button.setCheckable(True)
         t_blacklist_button.setFlat(True)
         t_blacklist_button.setToolTip(self.blacklist_help_text_short)
         t_blacklist_button.setIcon(
             QIcon(os.path.join(icons_dir, 'blacklist.png')))
         if entry.entry_hash:
             layout.addWidget(
                 t_blacklist_button, num, self.blacklist_column)
         else:
             t_blacklist_button.hide()
             dummy_label_bl = QLabel('', self)
             dummy_label_bl.setToolTip(self.blacklist_empty_line_help)
             layout.addWidget(dummy_label_bl, num, self.blacklist_column)
         t_button_group.button(entry.action).setChecked(True)
         # New: check a button based on how good the downloader is.
         t_button_group.addButton(t_blacklist_button, Action.Blacklist)
         self.buttons_groups.append(t_button_group)
     play_button_group.buttonClicked.connect(
         lambda button: play(
             self.entries_list[play_button_group.id(button)].file_path))
     # N.B.: anki.sound.play() plays files from anywhere, not just
     # from the colection.media folder. We should be good,
     # here. (This behaviour may be a security risk, idk.)
     old_play_button_group.buttonClicked.connect(
         lambda button: playFromText(
             self.note[
                 self.entries_list[
                     old_play_button_group.id(button)].audio_field_name]))
예제 #8
0
class LdapWidget(DirectoryWidget):
    def __init__(self, config, specific_config, mainwindow, parent=None):
        assert config is not None
        assert specific_config is not None
        DirectoryWidget.__init__(self, config, specific_config, mainwindow, parent)
        self.buildInterface(config)
        self.updateView(self.specific_config)

    def buildInterface(self, config):
        #<server uri>
        self.uri = QLineEdit()
        self.texts.add(self.uri)
        self.connect(self.uri, SIGNAL('textChanged(QString)'), self.setUri)
        self.connect(self.uri, SIGNAL('textChanged(QString)'), self.signalModified)
        self.connect(self.uri, SIGNAL('textEdited(QString)'), self.helpURI)
        self.connect(self.uri, SIGNAL('editingFinished()'), self.noHelpURI)
        self.connect(self.uri, SIGNAL('editingFinished()'), self.updateUri)
        self.form.addRow(tr('LDAP Server(s) uri'), self.uri)

        self.uri.setToolTip(help_uri_tooltip)
        self.connect(self.uri, SIGNAL('returnPressed()'), self.signalModified)

        self.uri_message_area = MessageArea()
        self.empty_uri_label = QLabel()
        self.form.addRow(self.empty_uri_label, self.uri_message_area)
        self.empty_uri_label.hide()
        self.uri_message_area.hide()
        self.uri_message_area.setMessage(help_uri_title, help_uri_message_area)

        self.numeric_uri_warning = MessageArea()
        empty  = QLabel()
        self.form.addRow(empty, self.numeric_uri_warning)
        empty.hide()
        self.numeric_uri_warning.hide()
        self.numeric_uri_warning.warning(numeric_warning_title, numeric_warning)
        self.numeric_uri_warning.setWidth(60)

        #</server uri>

        #<other fields>
        for args in self._genTextFieldsData():
            text_input = self.addTextInput(*args[1:])
            setattr(self, args[0], text_input)
            self.connect(text_input, SIGNAL('editingFinished(QString)'), self.valid)
        #</other fields>

        self.ssl_box = self.mkSslBox()
        self.connect(self.ssl_box, SIGNAL('toggled(bool)'), self.toggleSsl)
        self.form.addRow(self.ssl_box)

        self.form.addRow(separator())

        test_widget = QPushButton(tr("Test this configuration"))
        self.form.addRow("", test_widget)
        test_widget.connect(test_widget, SIGNAL('clicked()'), self.test_ldap)

    def _genTextFieldsData(self):
        return (
            ('dn_users', tr('LDAP DN for users'), self.setDnUsers),
            ('dn_groups', tr('LDAP DN for groups'), self.setDnGroups),
            ('user', tr('DN used to log in on the LDAP server'), self.setUser),
            ('password', tr('Password used to log in on the LDAP server'), self.setPassword, False)
        )

    def test_ldap(self):
        dc, base, uri, filter, password = self.specific_config.generateTest()
        if uri is None or uri == '':
            QMessageBox.critical(
                self,
                "Missing data",
                "Please fill URI field"
                )
            return
        if dc is None:
            dc == ''

        filter, ok = QInputDialog.getText(
            self,
            tr("LDAP Filter"),
            tr("Please enter a filter:"),
            QLineEdit.Normal,
            filter
            )

        if not ok:
            return

        async = self.mainwindow.client.async()
        async.call(
            'nuauth',
            'testLDAP',
            dc, base, uri, unicode(filter), password,
            callback = self.success_test,
            errback = self.error_test
            )

    def success_test(self, result):

        ans_no = tr("OK")
        ans_yes = tr("Show the server's answer")
        show_details = QMessageBox.question(
            self,
            tr('LDAP test results'),
            tr('LDAP test completed without error'),
            ans_no,
            ans_yes
            )

        if show_details == 0:
            return

        title = tr('LDAP test results')
        QMessageBox.information(
            self,
            title,
            '<span><h2>%s</h2><pre>%s</pre></span>' % (title, unicode(result))
            )

    def error_test(self, result):
        basic_text = tr('LDAP test completed with an error')
        formatted_text = u"""\
<span>
%s
<pre>
%s
</pre>
</span>
""" % (basic_text, unicode(result))
        QMessageBox.warning(
            self,
            tr('LDAP test results'),
            formatted_text
            )

    def helpURI(self, text):
        self.uri_message_area.show()

    def noHelpURI(self):
        self.uri_message_area.hide()

    def toggleSsl(self, value):
        if value:
            self.selectCustomOrNupki(NUPKI)
        else:
            self.specific_config.custom_or_nupki = SSL_DISABLED
        self.signalModified()

    def setUri(self, uris_text):
        self.specific_config.setUri(self.readString(uris_text))
        self.signalModified()

        self.numeric_uri_warning.setVisible(ip_in_ldapuri(self.specific_config.uri))

    def setUser(self, user):
        self.specific_config.user = self.readString(user)

    def setPassword(self, password):
        self.specific_config.password = self.readString(password)

    def setDnUsers(self, dn):
        self.specific_config.dn_users = self.readString(dn)

    def setDnGroups(self, dn):
        self.specific_config.dn_groups = self.readString(dn)

    def mkSslBox(self):
        group = QGroupBox(tr("Check server certificate"))
        group.setCheckable(True)
        box = QVBoxLayout(group)

        #id 0
        nupki = QRadioButton(tr("Upload certificate"))
        #id 1
        custom = QRadioButton(tr("Use an internal PKI"))

        hbox = QHBoxLayout()
        box.addLayout(hbox)
        self.nupki_or_custom = QButtonGroup()
        self.connect(self.nupki_or_custom, SIGNAL('buttonClicked(int)'), self.toggleCustomOrNupki)
        for index, radio in enumerate((custom, nupki)):
            hbox.addWidget(radio)
            self.nupki_or_custom.addButton(radio, index)

        self.file_selector_widget = QWidget()
        vbox = QVBoxLayout(self.file_selector_widget)
        selector_label = QLabel(tr("Manually uploaded LDAP certificate"))
        vbox.addWidget(selector_label)
        add_cert_trigger = AddButton(text=tr("Upload a certificate"))
        vbox.addWidget(add_cert_trigger)
        vbox.addWidget(separator())

        self.has_cert_message = QLabel(
            tr("There is no manually uploaded server certificate")
            )
        self.del_cert = RemButton(
            tr("Delete certificate file from server")
            )
        vbox.addWidget(self.has_cert_message)
        vbox.addWidget(self.del_cert)

        self.connect(add_cert_trigger, SIGNAL('clicked()'), self.upload_server_cert)

        self.connect(self.del_cert, SIGNAL('clicked()'), self.delete_server_cert)

        self.nupki_message = MessageArea()
        self.nupki_message.setMessage(tr("Warning"),
            tr(
                "There is no server certificate in the internal PKI.<br/>"
                "Please import or generate one using an internal PKI."
            )
            )

        for anti_button, widget in ((custom, self.nupki_message), (nupki, self.file_selector_widget)):
            box.addWidget(widget)
            self.connect(anti_button, SIGNAL('toggled(bool)'), widget.setVisible)

        self.selectCustomOrNupki(CUSTOM)

        return group

    def upload_server_cert(self):
        dialog = UploadDialog(
            selector_label=tr("LDAP certificate"),
            filter=tr("Certificate file (*.crt *.pem *)")
            )
        accepted = dialog.exec_()

        if accepted != QDialog.Accepted:
            return

        filename = dialog.filename

        if not filename:
            return
        with open(filename, 'rb') as fd:
            content = fd.read()

        content = encodeFileContent(content)

        self.mainwindow.addToInfoArea(tr('Uploading of a certificate file for the ldap server'))
        async = self.mainwindow.client.async()
        async.call("nuauth", "upload_ldap_server_cert", content,
            callback = self.success_upload,
            errback = self.error_upload
            )

    def success_upload(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] Success!'))
        self.specific_config.server_cert_set = True
        self.setServerCert()

        self.signalModified()

    def error_upload(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] Error!'), COLOR_ERROR)
        self.mainwindow.addToInfoArea(tr('[LDAP server cert upload] %s') % value, COLOR_ERROR)

    def setServerCert(self):
        if self.specific_config.server_cert_set:
            self.del_cert.show()
            self.has_cert_message.hide()
        else:
            self.del_cert.hide()
            self.has_cert_message.show()

    def delete_server_cert(self):
        confirm_box = QMessageBox(self)
        confirm_box.setText(
            tr(
                "Please confirm the deletion of the "
                "manually uploaded LDAP server certificate."
            )
            )
        confirm_box.setInformativeText(
            tr("Do you really want to delete the certificate file?")
            )
        confirm_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        confirm_box.setDefaultButton(QMessageBox.Cancel)
        confirm = confirm_box.exec_()

        if confirm != QMessageBox.Ok:
            return

        async = self.mainwindow.client.async()
        async.call("nuauth", "delete_ldap_server_cert",
            callback = self.success_delete,
            errback = self.error_delete
            )

    def success_delete(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] Success!'))
        self.specific_config.server_cert_set = False
        self.setServerCert()

        self.signalModified()

    def error_delete(self, value):
        self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] Error!'), COLOR_ERROR)
        self.mainwindow.addToInfoArea(tr('[LDAP server cert deletion] %s') % value, COLOR_ERROR)

    def toggleCustomOrNupki(self, id):
        if id == 0:
            self.specific_config.custom_or_nupki = NUPKI
        else:
            self.specific_config.custom_or_nupki = CUSTOM
        self.signalModified()

    def selectCustomOrNupki(self, custom_or_nupki):
        if custom_or_nupki == CUSTOM:
            self.file_selector_widget.setEnabled(True)
            self.nupki_message.hide()
            id = 1
        else:
            custom_or_nupki = NUPKI
            self.file_selector_widget.hide()
            id = 0
        self.nupki_or_custom.button(id).setChecked(True)

    def setSslData(self, config):
        ssl_enabled = (SSL_DISABLED != config.custom_or_nupki)
        self.ssl_box.setChecked(ssl_enabled)
        if ssl_enabled:
            self.selectCustomOrNupki(config.custom_or_nupki)

    def updateUri(self, config=None):
        if config is None:
            config = self.specific_config
        self.setText(self.uri, config.uri)

    def updateView(self, config=None):
        if config is None:
            config = self.specific_config
        self.updateUri(config=config)
        self.setSslData(config)
        #never copy this one:
        self.setDefaultText(self.dn_users, self.specific_config.dn_users)
        self.setDefaultText(self.dn_groups, self.specific_config.dn_groups)
        self.setDefaultText(self.user, config.user)
        self.setDefaultText(self.password, config.password)
        self.setServerCert()
예제 #9
0
class QuestionDlg(QDialog):
    def __init__(self, parent=None):
        super(QuestionDlg,self).__init__(parent)
        # self.setStyleSheet("background-image:url('image/panelbg.jpg'); border: 2px; border-radius 2px;")
        # self.createDb()
        # return

        self.db = QSqlDatabase.addDatabase("QSQLITE");  
        self.db.setDatabaseName("studentNew.db")
        if not self.db.open():
            QMessageBox.warning(None, "错误",  "数据库连接失败: %s" % self.db.lastError().text())
            sys.exit(1)

        self.g_curClassName = ""
        self.deleteTmpdata()

        self.setWindowFlags(Qt.CustomizeWindowHint)
        # self.setStyleSheet("border: 2px; border-radius 2px;")
        # self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet("background-color: rgba(132, 171, 208, 200);")

        self.tabWidget=QTabWidget(self)
        self.tabWidget.currentChanged.connect(self.changeTab)
        # tabWidget.setTabShape(QTabWidget.Triangular)
        self.tabWidget.setStyleSheet("QTabWidget::pane{border-width:1px;border-color:rgb(48, 104, 151);\
            border-style: outset;background-color: rgb(132, 171, 208);\
            background: transparent;} \
            QTabWidget::tab-bar{border-width:0px;}\
            QTabBar::tab { height: 60px; width: 260px; color:rgb(0, 0, 255); font-size:20px; font-weight:bold;} \
            QTabBar::tab:hover{background:rgb(255,255, 255, 100);} \
            QTabBar::tab:selected{border-color:green;background-color:white;color:green;}")
        # tabWidget.setStyleSheet("QTabBar::tab:hover{background:rgb(255,255, 255, 100);}")
        self.btngroup = QButtonGroup()
        self.popMenu = QMenu(self)
        entry1 = self.popMenu.addAction("正确")
        self.connect(entry1,SIGNAL('triggered()'), lambda : self.answerRight())
        entry2 = self.popMenu.addAction("错误")
        self.connect(entry2,SIGNAL('triggered()'), lambda : self.answerWrong())
        entry3 = self.popMenu.addAction("替换")
        self.connect(entry3,SIGNAL('triggered()'), lambda : self.resetStudent())

        # Create the first tab page.
        self.w1=QWidget()
        self.w1.setAccessibleName("w1tab")
        self.genOneTab()
        
        # Create the second tab page.
        self.w2=QWidget()
        self.w2.setAccessibleName("w2tab")        
        self.genTwoTab()

        self.tabWidget.addTab(self.w1,"")
        self.tabWidget.addTab(self.w2,"班级学生信息管理")
        self.tabWidget.resize(940,700)

        btnclose = QPushButton(self)
        btnclose.setToolTip("关闭")
        btnclose.setText("╳")
        btnclose.setGeometry(915, 5, 20, 20)
        btnclose.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnclose.clicked.connect(self.close)
        btnMinimized = QPushButton(self)
        btnMinimized.setToolTip("最小化")
        btnMinimized.setText("▁")
        btnMinimized.setGeometry(890, 5, 20, 20)
        btnMinimized.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnMinimized.clicked.connect(lambda: self.showMinimized())
        self.btnSysMenu = QPushButton(self)
        # self.btnSysMenu.setText("▼")
        self.btnSysMenu.setGeometry(865, 5, 20, 20)
        self.btnSysMenu.setToolTip("系统设置")
        self.btnSysMenu.clicked.connect(lambda: self.showMinimized())
        menufont = QFont("宋体", 10)
        popMenu = QMenu(self)
        entry1 = popMenu.addAction("所有学生提问信息清零")
        entry1.setFont(menufont)
        self.connect(entry1,SIGNAL('triggered()'), self.initStudent)
        entry2 = popMenu.addAction("清除本堂课提问人员")
        entry2.setFont(menufont)
        self.connect(entry2,SIGNAL('triggered()'), self.deleteTmpdata)
        entry3 = popMenu.addAction("关于...")
        entry3.setFont(menufont)
        self.connect(entry3,SIGNAL('triggered()'), self.aboutMe)
        entry4 = popMenu.addAction("导出...")
        entry4.setFont(menufont)
        self.connect(entry4,SIGNAL('triggered()'), self.exportNotice)

        self.btnSysMenu.setMenu(popMenu)
        self.btnSysMenu.setStyleSheet("QPushButton::menu-indicator {image: url('image/sysmenu.png');subcontrol-position: right center;} ")
        # self.btnSysMenu.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255);")

        authorinfo = QLabel(self.tabWidget)
        # authorinfo.setToolTip("关闭")
        authorinfo.setText("程序设计:汕头市大华路第一小学 赵小娜,有任何问题请反馈至[email protected]。")
        authorinfo.setGeometry(20, 665, 470, 26)
        authorinfo.setFont(QFont('Courier New'))
        authorinfo.setStyleSheet("background-color:rgba(255, 255, 255,160); font-size:12px;border: 1px solid rgb(60,200,255,200);color:rgba(0,0,0,220);border-radius:12px;")

        self.setWindowTitle("课堂随机提问")
        self.setWindowIcon(QIcon("image/start.ico"))
        self.setGeometry(100, 20, 940, 700)

        # self.changeTab()

        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

        self.btn_start.setMyarg('start')
        
        # print(self.btn_start.getMyarg())

        self.connect(self.btn_start, SIGNAL("clicked()"), self.startChoice)
        # self.connect(self.w1title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        # self.connect(self.btn_start2, SIGNAL("clicked()"), self.startChoice)
        # self.connect(self.w2title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        self.btngroup.buttonClicked[int].connect(self.btns_click)
        # self.connect(self.btn_start,  SIGNAL("myslot(PyQt_PyObject)"), self.myslot)  
        # self.connect(self.btngroup, SIGNAL("buttonClicked(int)"), lambda:self.btns_click())

    def myslot(self, text):  
        # print(text, self.dict_choices)
        self.g_curbtn = text
        if self.g_curbtn not in self.dict_choices:
            self.btnSysMenu.setFocus()
            return

        # print(self.btngroup.button(int(self.g_curbtn)).parent())
        # print(type(self.btngroup.button(int(self.g_curbtn)).parentWidget()))
        pos = self.btngroup.button(int(self.g_curbtn)).parent().mapToGlobal(self.btngroup.button(int(self.g_curbtn)).pos())
        width = self.btngroup.button(int(self.g_curbtn)).rect().height()
        # print("-----", pos, width)
        pos.setY(pos.y()+width-5)

        indx = 0
        for istate in self.dict_choices[self.g_curbtn]:
            if istate == '1':
                self.popMenu.actions()[indx].setEnabled(True)
            elif istate == '0':
                self.popMenu.actions()[indx].setEnabled(False)
            indx += 1
        self.popMenu.exec_(pos)
        self.btnSysMenu.setFocus()
    # def on_context_menu(self, point):
    #     print(point)
    #     self.popMenu.exec_(self.button.mapToGlobal(point)) 

    def btns_click(self, btnid):
        # curclassname = self.tabWidget.tabText(0)
        query = QSqlQuery(self.db)
        # cur = conn.cursor()
        today = datetime.date.today()
        self.g_curbtn = str(btnid).zfill(2)
        if self.g_curbtn not in self.dict_choices:
            self.btngroup.button(int(self.g_curbtn)).setStyleSheet(stylesheetstr_new)
            query.exec_("select count(*) from tmprecord where stusn='" + str(self.g_curbtn) + "'")
            query.next()            
            if query.value(0) == 0:
                query.prepare("insert into tmprecord (classname, stusn, datequestion) values (:classname, :stusn, :datequestion)")
                query.bindValue(":classname", self.g_curClassName)
                query.bindValue(":stusn", self.g_curbtn)
                query.bindValue(":datequestion", today)
                query.exec_() 
                
            self.dict_choices[self.g_curbtn] = "111"
        else:
            self.btngroup.button(int(self.g_curbtn)).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(self.g_curbtn)).setIcon(QIcon())            
            query.exec_("delete from tmprecord where stusn='"+ str(self.g_curbtn) + "'")            
            self.dict_choices.pop(self.g_curbtn)

        self.btnSysMenu.setFocus()

    def exportNotice(self):
        query = QSqlQuery(self.db)
        query.exec_("select stusn, stuname, classname, rightquestions, wrongquestions from student" ) 
        lstInfo = [["学号","姓名", "班级", "回答正确次数", "回答错误次数"]]
        while(query.next()):
            lstInfo.append([query.value(0),query.value(1),query.value(2),query.value(3),query.value(4)])

        from xlwt import Workbook,easyxf
        book = Workbook(encoding='ascii')
            # 'pattern: pattern solid,  fore_colour white;'
        style = easyxf(
            'font: height 280, name 黑体;'
            'align: vertical center, horizontal center;'
            )
        style2 = easyxf('font: height 260, name 仿宋_GB2312, bold True; align: vertical center, horizontal left;')
        style3 = easyxf('font: height 260, name 仿宋_GB2312, bold True; align: vertical center, horizontal left, wrap True;')

        sheet1 = book.add_sheet('学生提问情况汇总',cell_overwrite_ok=True)
        # sheet1.write(0,7,flagtxt, easyxf('font: height 200, name 黑体;align: vertical center, horizontal right;'))
        sheet1.write_merge(0,0,0,4, '学生提问情况汇总表',style)
        sheet1.row(0).height_mismatch = 1
        sheet1.row(0).height = 5*256

        sheet1.col(0).width = 10*256
        sheet1.col(1).width = 25*256
        sheet1.col(2).width = 25*256
        sheet1.col(3).width = 20*256
        sheet1.col(4).width = 20*256
        
        tmprows = 1
        for item in lstInfo:
            stusn               = item[0]
            stuname             = item[1]
            classname           = item[2]
            rightquestions      = item[3]
            wrongquestions      = item[4]

            sheet1.write(tmprows,0,stusn, style2)
            sheet1.write(tmprows,1,stuname, style2)
            sheet1.write(tmprows,2,classname, style2)
            sheet1.write(tmprows,3,rightquestions, style2)
            sheet1.write(tmprows,4,wrongquestions, style2)
            tmprows += 1
        # print(tmprows)
        sheet1.header_str = "".encode()
        sheet1.footer_str = "".encode()

        # book.save('d:/simple.xls')
        # print(QDir.home().dirName() , QDir.homePath ())
        filename = QDir.homePath () + "\学生提问情况汇总表.xls" 
        try:
            book.save(filename)
        except  Exception as e:
            QMessageBox.warning(self, "写入错误", "错误号:"+str(e.errno)+"\n错误描述:"+e.strerror+"\n请关闭已经打开的%s文档!" % filename)
        QMessageBox.about (self, "导出成功", "请查看文档:%s" % filename)

    def aboutMe(self):
        strinfo = """本软件采用python3.4编写,界面采用qt4.8的python绑定。
                    \n版本所有:汕头市大华路第一小学赵小娜老师。
                    \n有任何问题请反馈至[email protected]。
                    """
        QMessageBox.information(None, "关于", strinfo)
        
    def initStudent(self):
        query = QSqlQuery(self.db)
        ret = query.exec_("update student set wrongquestions=0") 
        ret = query.exec_("update student set rightquestions=0")  
        QMessageBox.information(None, "提示", "已清除所有学生的累计提问情况。")


    def deleteTmpdata(self):
        query = QSqlQuery(self.db)
        ret = query.exec_("delete from tmprecord where 1=1" )   
        if self.g_curClassName != "":     
            QMessageBox.information(None, "提示", "已清除本次软件启动后的所有已提问过的学生。")
  
    def changeTab(self):
        # pass
        curtab = self.tabWidget.currentIndex()
        # print(curtab, "-")
        if curtab == 1:  ## when click the second tab page ,then pass.
            return
            
        # cur = conn.cursor()
        query = QSqlQuery(self.db)

        ## if current classname is null, then set current tabpage display the first class of classtable
        if self.g_curClassName == "":
            ret = query.exec_("select classname from classtable")
            query.next()
            self.g_curClassName = query.value(0)
            
        self.tabWidget.setTabText(0, self.g_curClassName)
        # print(1)
        strwhere = " and classname like '" + self.g_curClassName + "' ORDER BY stusn"

        self.g_curbtn = ""
        self.dict_choices = {}
        self.studentSnlst = []

        ## clearn the question data of temp record .
        ret= query.exec_("delete from tmprecord where 1=1")
        ret = query.exec_("select stusn, stuname from student where 1=1 " + strwhere)

        ## now update the global data "self.btngroup"
        for indx in range(0, 56):
            self.btngroup.button(indx+1).setText("")
            self.btngroup.button(indx+1).setMyarg(None)       
            self.btngroup.button(indx+1).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(indx+1).setIcon(QIcon())
            self.btngroup.button(indx+1).setEnabled(False)
            self.studentSnlst.append([indx+1,])

        inum = 0
        while (query.next()): 
            inum += 1            
            self.btngroup.button(inum).setText(query.value(1))
            self.btngroup.button(inum).setMyarg(query.value(0))       
            self.btngroup.button(inum).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(inum).setIcon(QIcon())
            self.btngroup.button(inum).setEnabled(True)

        # print(inum, len(self.btngroup.buttons()))        

        self.group_animation = groupAnimation(self.studentSnlst, self.btngroup)

    def mousePressEvent(self, event):
        # print('a')
        if event.button() == Qt.RightButton:
            QDialog.mousePressEvent(self,event)
            return
        # print(event.sender(), event.button())
        self.offset = event.pos()
        # print(self.offset)

    def mouseMoveEvent(self, event):
        # print('sss')
        if hasattr(self, 'offset'):
            x=event.globalX()
            y=event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x-x_w, y-y_w)
        else:
            pass

    #######======= studentModel ============###############
    def newStudent(self):
        # Calc the missing number:
        row = self.StudentModel.rowCount()

        if row > 0:
            oldNumList = []
            for i in range(0, row):
                oldNumList.append(int(self.StudentModel.index(i,2).data()))
            
            allNumberList = list(range(1, oldNumList[-1]+1))
            for i in range(0, allNumberList[-1]):
                if oldNumList[i] != allNumberList[i]:
                    missingNum = allNumberList[i]
                    break
            if len(oldNumList) == len(allNumberList):
                missingNum = allNumberList[i] +1
        else:
            missingNum = 1

        self.StudentModel.insertRow(row)
        self.StudentView.scrollToBottom()
        self.StudentModel.setData(self.StudentModel.index(row, 1), self.g_curClassName)
        self.StudentModel.setData(self.StudentModel.index(row, 2), str(missingNum).zfill(2))
        self.StudentModel.setData(self.StudentModel.index(row, 4), 0)
        self.StudentModel.setData(self.StudentModel.index(row, 5), 0)

    def removeStudent(self):
        index = self.StudentView.currentIndex()
        row = index.row()             
        if QMessageBox.question(self, "删除确认", "是否要删除当前选中记录?", "确定", "取消") == 0:
            self.StudentModel.removeRows(row, 1)
            self.StudentModel.submitAll()
            self.StudentModel.database().commit()

    def revertStudent(self):
        self.StudentModel.revertAll()
        self.StudentModel.database().rollback()

    def saveStudent(self):
        self.StudentModel.database().transaction()
        if self.StudentModel.submitAll():
            self.StudentModel.database().commit()
            # print("save success!  ->commit")
        else:
            self.StudentModel.revertAll()
            self.StudentModel.database().rollback()

    #######======= classModel ============###############
    def newClass(self):
        row = self.ClassnameModel.rowCount()
        self.ClassnameModel.insertRow(row)

    def removeClass(self):
        index = self.ClassnameView.currentIndex()
        row = index.row()   
        curClassname =  index.sibling(index.row(),0).data()
        strwhere = "classname like '" + curClassname + "'"
        self.StudentModel.setFilter(strwhere)
        self.StudentModel.select()
        # print(self.StudentModel.rowCount(), "----", )
        if QMessageBox.question(self, "删除确认", "删除班级意味着会删除本班所有人员信息。是否要删除当前选中记录?", "确定", "取消") == 0:
            self.ClassnameModel.removeRows(row, 1)
            self.ClassnameModel.submitAll()
            self.ClassnameModel.database().commit()

            self.StudentModel.removeRows(0, self.StudentModel.rowCount())
            self.StudentModel.submitAll()
            self.StudentModel.database().commit()

    def revertClass(self):
        self.ClassnameModel.revertAll()
        self.ClassnameModel.database().rollback()

    def saveClass(self):
        query = QSqlQuery(self.db)

        # record the old class name
        lstOldClassName = {}
        lstOldClassid = []
        query.exec_("select rowid, classname from classtable" )        
        while(query.next()):
            lstOldClassName[query.value(0)] = query.value(1)
            lstOldClassid.append(query.value(0))
        # print(lstOldClassName)

        # Update the class Table
        self.ClassnameModel.database().transaction()
        if self.ClassnameModel.submitAll():
            self.ClassnameModel.database().commit()
            # print("save success!  ->commit")
        else:
            QMessageBox.warning(None, "错误",  "请检查班级中名称,不能出现同名班级!")
            self.ClassnameModel.revertAll()
            self.ClassnameModel.database().rollback()

        # print(lstOldClassid)

        lstNewClassName = {}
        query.exec_("select rowid, classname from classtable where rowid in " + str(tuple(lstOldClassid)) )        
        while(query.next()):
            lstNewClassName[query.value(0)] = query.value(1)            

        # print(lstOldClassName, '=========')
        # print(lstNewClassName, '~~~~~~~~~')

        for i in lstOldClassName:
            oldclassname = lstOldClassName[i]
            newclassname = lstNewClassName[i]
            if oldclassname != newclassname:
                # print(oldclassname, newclassname, '++++++++')
                # print("update student set classname=" + newclassname + " where classname='" + oldclassname + "'")
                query.exec_("update student set classname='" + newclassname + "' where classname='" + oldclassname + "'")
                self.StudentModel.setFilter("classname = '" + newclassname + "'")
                self.StudentModel.select()

        lstClassName = []      
        query.exec_("select classname from classtable" ) 
        while(query.next()):
            lstClassName.append(query.value(0))
        self.StudentView.setItemDelegateForColumn(1,  ComboBoxDelegate(self, lstClassName, self.db))

    def dbclick(self, indx):
        if type(indx.sibling(indx.row(),0).data()) != QPyNullVariant:
            classname = indx.sibling(indx.row(),0).data()
            
            strwhere = "classname like '" + classname + "'"
            self.StudentModel.setFilter(strwhere)
            self.StudentModel.setSort(2, Qt.AscendingOrder)
            self.StudentModel.select()
            
            self.g_curClassName = classname
            self.tabWidget.setTabText(0, self.g_curClassName)

    def dbclick2(self, indx):
        if indx.column() == 2:
            self.StudentView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            self.StudentView.setEditTriggers(QAbstractItemView.DoubleClicked)
        

    def genTwoTab(self, tabtitle=""):
        # Create the tab title sytle.
        tabtitle = QLabel()
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setText("班级学生信息管理")
        tabtitle.setStyleSheet("border: 1px solid blue; color:rgba(0,0,255, 220);\
            background-color:rgba(201,201,201,60);\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        tabtitle.setMinimumHeight(50);
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)

       
        # Create the classnameView
        self.ClassnameView = QTableView()
        self.ClassnameModel = QSqlTableModel(self.ClassnameView)
        self.ClassnameModel.setTable("classtable")
        # self.ClassnameModel.setRelation(2, QSqlRelation("mentalmodel", "id", "name"));
        self.ClassnameModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.ClassnameModel.select()

        self.ClassnameModel.setHeaderData(0, Qt.Horizontal, "班级名称")

        # for indx, iheader in enumerate(["classid", "classname"]):
        #     self.ClassnameModel.setHeaderData(indx+1, Qt.Horizontal, iheader)
    
        self.ClassnameView.setModel(self.ClassnameModel)
        # self.ClassnameView.setColumnHidden(0, True)
        # self.ClassnameView.show()
        self.ClassnameView.verticalHeader().setFixedWidth(30)
        self.ClassnameView.verticalHeader().setStyleSheet("color: red;font-size:20px; ");
        self.ClassnameView.setStyleSheet("QTableView{background-color: rgb(250, 250, 200, 0);"  
                    "alternate-background-color: rgb(141, 163, 0);}"
                    "QTableView::item:hover {background-color: rgba(100,200,220,100);} ") 
        self.ClassnameView.setStyleSheet("font-size:16px; ");
        self.ClassnameView.setSelectionMode(QAbstractItemView.SingleSelection)
        # self.ClassnameView.dataChanged.connect(self.dataChanged)

        # self.ClassnameView.setSizePolicy(QSizePolicy.Expanding,     QSizePolicy.Expanding)

        # the second list
        self.StudentView = QTableView()
        self.StudentModel = QSqlTableModel(self.StudentView)
        self.StudentModel.setTable("student")
        # self.StudentModel.setRelation(2, QSqlRelation("mentalmodel", "id", "name"));
        self.StudentModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        # self.StudentModel.select()

        query = QSqlQuery(self.db)
        strwhere = " 1=1 "
        if self.g_curClassName == "":
            ret = query.exec_("select classname from classtable")
            query.next()
            firstClassName = query.value(0)
            strwhere += " and classname like '" + firstClassName + "'"
            
        self.StudentModel.setFilter(strwhere)
        self.StudentModel.select()

        for indx, iheader in enumerate(["班级名称", "学生编号", "学生姓名", "答对次数", "答错次数"]):
            self.StudentModel.setHeaderData(indx+1, Qt.Horizontal, iheader)
    
        self.StudentView.setModel(self.StudentModel)
        self.StudentView.setColumnHidden(0, True)

        # query = QSqlQuery(self.db)  
        lstClassName = []      
        query.exec_("select classname from classtable" ) 
        while(query.next()):
            lstClassName.append(query.value(0))

        self.StudentView.setItemDelegateForColumn(1,  ComboBoxDelegate(self, lstClassName, self.db))
        # self.StudentView.show()
        self.StudentView.verticalHeader().setFixedWidth(30)
        self.StudentView.verticalHeader().setStyleSheet("color: red;font-size:20px; background-color: rgb(250, 250, 200, 100)");
        self.StudentView.setStyleSheet("QTableView{background-color: rgb(250, 250, 200, 0);"  
                    "alternate-background-color: rgb(141, 163, 250);}"
                    "QTableView::item:hover {background-color: rgba(10,200,100,200);} "
                    ) 
        self.StudentView.setStyleSheet("font-size:16px;")
        self.StudentView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.StudentView.doubleClicked.connect(self.dbclick2)

        btn_lst1_layout = QGridLayout()
        newusrbtn       = QPushButton("新增")
        savebtn         = QPushButton("保存")
        revertbtn       = QPushButton("撤销")
        removebtn       = QPushButton("删除")
        btn_lst1_layout.addWidget(newusrbtn, 0, 0)
        btn_lst1_layout.addWidget(savebtn, 0, 1)
        btn_lst1_layout.addWidget(revertbtn, 1, 0)
        btn_lst1_layout.addWidget(removebtn, 1, 1)

        newusrbtn.clicked.connect(self.newClass)
        savebtn.clicked.connect(self.saveClass)
        revertbtn.clicked.connect(self.revertClass)
        removebtn.clicked.connect(self.removeClass)

        self.ClassnameView.doubleClicked.connect(self.dbclick)
        

        btnbox2 = QDialogButtonBox(Qt.Horizontal)
        newusrbtn2       = QPushButton("新增")
        savebtn2         = QPushButton("保存")
        revertbtn2       = QPushButton("撤销")
        removebtn2       = QPushButton("删除")
        btnbox2.addButton(newusrbtn2, QDialogButtonBox.ActionRole);
        btnbox2.addButton(savebtn2, QDialogButtonBox.ActionRole);
        btnbox2.addButton(revertbtn2, QDialogButtonBox.ActionRole);
        btnbox2.addButton(removebtn2, QDialogButtonBox.ActionRole);

        newusrbtn2.clicked.connect(self.newStudent)
        savebtn2.clicked.connect(self.saveStudent)
        revertbtn2.clicked.connect(self.revertStudent)
        removebtn2.clicked.connect(self.removeStudent)

        # left list layout
        lst_layout_1 = QVBoxLayout()
        lst_layout_1.addWidget(self.ClassnameView)
        lst_layout_1.addLayout(btn_lst1_layout)

        lst_layout_2 = QVBoxLayout()
        lst_layout_2.addWidget(self.StudentView)
        lst_layout_2.addWidget(btnbox2)
        
        lstlayout = QHBoxLayout()
        lstlayout.setMargin(5)
        # lstlayout.addLayout(findbox)
        lstlayout.addLayout(lst_layout_1, 2)
        lstlayout.setMargin(5)
        lstlayout.addLayout(lst_layout_2, 5)
            
        labelClass = QLabel("")
        labelClass.setStyleSheet("background-color:rgba(255, 255, 255,0); color:rgba(0,0,0,0);")
        labelClass.setFixedHeight(40)
        # labelClass.setFixedWidth(100)
        # labelClass.setFont(QFont('宋体', 10))

        bottomlayout = QHBoxLayout()        
        bottomlayout.addWidget(labelClass)        

        tab2layout = QVBoxLayout()
        tab2layout.addLayout(titleLayout)       
        tab2layout.addLayout(lstlayout)
        tab2layout.addLayout(bottomlayout)
        self.w2.setLayout(tab2layout)
        self.w2.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")
      
    def genOneTab(self):

        tabtitle = QLabel()
        # tabtitle.setFixedHeight(40)
        # tabtitle.setFixedWidth(160)        
        self.btn_start = MyButton("开始")
        self.choicenum_text = QComboBox()
        self.choicenum_text.setObjectName('w1combonums')
        # self.w1title.setStyleSheet("background-image:url('image/panelbg.jpg');")
        
        # Set the title style                
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setText("随堂提问演板")
        tabtitle.setStyleSheet("border: 1px solid blue; color:rgba(0,0,255, 220);\
            background-color:rgba(201,201,201,60);\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        tabtitle.setMinimumHeight(50);
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)
       
        btnlayout = QGridLayout()
        tmpnum = 0
        for inum in range(0,56):
            irow = tmpnum // g_cols
            icol = tmpnum % g_cols
            tmpnum += 1
            btnlayout.setRowMinimumHeight(irow, 80)
            tmpbtn = MyButton("")
            tmpbtn.setMyarg(None)
            # tmpbtn.setFixedHeight(20)
            tmpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding))
            tmpbtn.setStyleSheet("border: 1px solid rgb(55,55,255,100);background-color: rgba(255,255,255,20);font-size:16px;")
            self.connect(tmpbtn,  SIGNAL("myslot(PyQt_PyObject)"), self.myslot)
            tmpbtn.setAutoDefault(False)
            self.btngroup.addButton(tmpbtn, inum+1) # stusn is from 1 start

            btnlayout.addWidget(tmpbtn, irow, icol)


        self.btn_start.setIcon(QIcon("image/start.png"))
        self.btn_start.setStyleSheet("border: 1px solid yellow;")
        self.btn_start.setFixedHeight(40)
        self.btn_start.setFixedWidth(100)
        self.btn_start.setFont(QFont('宋体', 18))
        # self.choicenum_text.setFixedHeight(45)
        # self.choicenum_text.setFixedWidth(60)

        ## Set the combox number style
        self.choicenum_text.setFont(QFont('Courier New', 20))
        self.choicenum_text.setFixedHeight(45)
        self.choicenum_text.setStyleSheet("border: 2px solid blue; color:red;font-weight:light;font-size:26px;\
            border-radius: 6px; \
            min-width: 2em; ")
        self.choicenum_text.setEditable(True)
        self.choicenum_text.lineEdit().setReadOnly(True);
        self.choicenum_text.lineEdit().setAlignment(Qt.AlignCenter);

        model = self.choicenum_text.model()
        for row in list(range(1, 7)):
            item = QStandardItem(str(row))
            item.setTextAlignment(Qt.AlignCenter)
            item.setForeground(QColor('red'))
            item.setBackground(QColor(0,200,50, 130))
            model.appendRow(item)
        self.choicenum_text.setCurrentIndex(2)
        # self.choicenum_text.setStyleSheet ("QComboBox::drop-down {border-width: 100px;}")
        # self.choicenum_text.setStyleSheet ("QComboBox::down-arrow {image: url(image/downarrow.png);top: 10px;left: 1px;}")

        bottomlayout = QHBoxLayout()
        bottomlayout.setSizeConstraint(QLayout.SetFixedSize)
        bottomlayout.addStretch(10)
        bottomlayout.addWidget(self.btn_start)
        bottomlayout.setSpacing(5)
        bottomlayout.addWidget(self.choicenum_text)

        tab1layout = QVBoxLayout()
        tab1layout.addLayout(titleLayout)       
        tab1layout.addLayout(btnlayout)
        tab1layout.addLayout(bottomlayout)
                
        self.w1.setLayout(tab1layout)
        self.w1.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")
         
    def startChoice(self, usernum="", oldbtn=""): 
        # print(oldbtn, 1)

        if oldbtn == "":
            self.dict_choices = {}

        strwhere = " and classname like '" + self.g_curClassName + "'"

        allstudent = []
        lstrecord = []
        query = QSqlQuery(self.db)        
        query.exec_("select stusn from tmprecord where 1=1 " + strwhere) 
        while(query.next()):
            lstrecord.append(query.value(0))
        # print(lstrecord, 'record', "select stusn from student where stusn not in " + str(tuple(lstrecord)))

        query.exec_("select stusn from student where stusn not in " + str(tuple(lstrecord)) + strwhere)
        while(query.next()):
            allstudent.append(query.value(0))

        if usernum == "":
            nums = int(self.choicenum_text.currentText())
        else:
            nums = usernum
        if nums >= len(allstudent):
            query.exec_("delete from tmprecord where 1=1 " + strwhere) #delete tmp date no today            
            allstudent = []
            query.exec_("select stusn from student where 1=1 " + strwhere)
            while(query.next()):
                allstudent.append(query.value(0))
        
        if oldbtn == "":
            random.seed()
            lstchoices = random.sample(allstudent, nums)
            for ibtn in lstchoices:
                self.dict_choices[ibtn] = "111"

            self.group_animation.start()
            QTimer.singleShot(1200, self.stopmovie)
        else:
            random.seed()
            otherbtn = random.sample(allstudent, 1)[0]
            # self.btngroup.button(int(otherbtn)).setFocus()
            self.dict_choices.pop(oldbtn)
            self.dict_choices[otherbtn] = '111'
            self.stopmovie()
        self.btnSysMenu.setFocus()

    def stopmovie(self):
        self.group_animation.stop()
        for isn in self.studentSnlst:
            # print(isn)
            self.btngroup.button(int(isn[0])).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(isn[0])).setIcon(QIcon())
        
        classname = self.tabWidget.tabText(0)
        query = QSqlQuery(self.db)        
        today = datetime.date.today()
        for ibtn in self.dict_choices:
            self.btngroup.button(int(ibtn)).setStyleSheet(stylesheetstr_new)
            query.exec_("select count(*) from tmprecord where stusn='" + str(ibtn) + "'")
            query.next()
            if query.value(0) == 0:               
                query.prepare("insert into tmprecord (classname, stusn, datequestion) values (:classname, :stusn, :datequestion)")
                query.bindValue(":classname", classname)
                query.bindValue(":stusn", ibtn)
                query.bindValue(":datequestion", today)
                query.exec_()
    
    def answerRight(self):
        # print(self.g_curbtn)
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/smile.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))
        
        query = QSqlQuery(self.db)
        query.exec_("select rightquestions from student where stusn='" + value + "'")
        query.next()
        studentRightQuestions = query.value(0) + 1
        query.exec_("update student set rightquestions=" + str(studentRightQuestions) + " where stusn='" + value + "'")
                
        ###########
        if self.dict_choices[value] == "101":
            query.exec_("select wrongquestions from student where stusn='" + value + "'")
            query.next()
            studentWrongQuestions = query.value(0) - 1
            query.exec_("update student set wrongquestions=" + str(studentWrongQuestions) + " where stusn='" + value + "'")
            
        self.dict_choices[value] = "011"

    def answerWrong(self):
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/cry.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))
        # self.btngroup.button(int(value)).setStyleSheet("border-image: url(image/ex_stu.png);")
        
        query = QSqlQuery(self.db)
        query.exec_("select wrongquestions from student where stusn='" + value + "'")
        query.next()
        studentWrongQuestions = query.value(0) + 1
        query.exec_("update student set wrongquestions=" + str(studentWrongQuestions) + " where stusn='" + value + "'")
        
        if self.dict_choices[value] == "011":
            query.exec_("select rightquestions from student where stusn='" + value + "'")
            query.next()
            studentRightQuestions = query.value(0) - 1
            query.exec_("update student set rightquestions=" + str(studentRightQuestions) + " where stusn='" + value + "'")
            
        self.dict_choices[value] = "101"

    def resetStudent(self):
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        query = QSqlQuery(self.db)

        if self.dict_choices[value] == "011":        
            query.exec_("select rightquestions from student where stusn='" + value + "'")
            query.next()
            studentRightQuestions = query.value(0) - 1
            query.exec_("update student set rightquestions=" + str(studentRightQuestions) + " where stusn='" + value + "'")

        if self.dict_choices[value] == "101":
            query.exec_("select wrongquestions from student where stusn='" + value + "'")
            query.next()
            studentWrongQuestions = query.value(0) - 1
            query.exec_("update student set wrongquestions=" + str(studentWrongQuestions) + " where stusn='" + value + "'")
            
        self.startChoice(usernum=1, oldbtn=value)
        # print("---reset___")

        # curmenu.actions()[0].setEnabled(True)
        # curmenu.actions()[1].setEnabled(True)
        # self.choiceOneStudent(value)

    def createDb(self):
        conn = sqlite3.connect("studentNew.db") 
        cur = conn.cursor()
        sqlstr = 'create table student (id integer primary key, \
            classname varchar(20), \
            stusn varchar(20), \
            stuname varchar(20), \
            rightquestions integer, \
            wrongquestions integer, \
            FOREIGN KEY(classname) REFERENCES classtable(classname))'
        # print(sqlstr)

        sqlstr2 = 'create table tmprecord (id integer primary key, \
            classname varchar(20), \
            stusn varchar(20), \
            datequestion date)'

        sqlstr3 = 'create table classtable (classname varchar(20) PRIMARY KEY)'
        
        cur.execute(sqlstr3)
        conn.commit()
        cur.execute(sqlstr2)
        conn.commit()
        cur.execute(sqlstr)
        conn.commit()

        strdelete = "delete from student where 1=1"
        cur.execute(strdelete)
        conn.commit()
        strdelete = "delete from tmprecord where 1=1"
        cur.execute(strdelete)
        conn.commit()
        # print(sqlstr2)

        # cur.execute(sqlstr) 
        # conn.commit()
        # cur.execute(sqlstr2) 
        # conn.commit()

        # insert example data
        strsql = "insert into classtable values (?)"
        cur.execute(strsql, ("三(3)班",))
        conn.commit()
        cur.execute(strsql, ("三(4)班",))
        conn.commit()


        a03lst = ["曾忆谊","赵佳泉","翁文秀","林珑","郑铭洁","林泽思","吴崇霖","陈思嘉","欧阳月孜","郭展羽","詹伟哲","黄佳仪","杨秋霞","周奕子","林楚杰","欧伊涵","许腾誉","陈唯凯","陈树凯","林彦君","张钰佳","高锴","杨博凯","林妙菲","林楚鸿","陈展烯","姚静茵","吴欣桐","范思杰","肖佳","马思广","许一帆","姚奕帆","陈海珣","吴黛莹","吴育桐","肖凯帆","林欣阳","叶茂霖","姚楷臻","陈嘉豪","陈琦","杨子楷","陈炎宏","陈幸仪","杨景畅","罗暖婷","郑馨"]
        a04lst = ["罗恩琪","王可","曾祥威","谢濡婷","温嘉凯","许洁仪","肖欣淇","陈凯佳","林天倩","李乐海","吴文慧","黄文婷","万誉","陈进盛","张裕涵","陈振嘉","王巧玲","林珮琪","陈炜楷","杨健","赵泽锴","张凤临","蔡子丹","陈烨杰","廖妍希","林树超","夏培轩","陈锦森","李星","蔡依婷","姚容创","姚凯扬","沈嘉克","周凡","张玉川","邱金迅","陈菲敏","陈星翰","朱煜楷","郑泽洪","钱剑非","罗奕丰","陈杜炜","林知钦"]
        strsql = "insert into student values (?, ?, ?, ?,?,?)" 
        for i in list(range(0,len(a03lst))):
            cur.execute(strsql, (None, "三(3)班", str(i+1).zfill(2), a03lst[i], 0, 0))
            conn.commit()
        strsql = "insert into student values (?, ?, ?, ?,?,?)" 
        for i in list(range(0,len(a04lst))):
            cur.execute(strsql, (None, "三(4)班", str(i+1).zfill(2), a04lst[i], 0, 0))
            conn.commit()
        cur.close()
class DefaultSelectParameterWidget(SelectParameterWidget):

    """Widget class for Default Select Parameter."""

    def __init__(self, parameter, parent=None):
        """Constructor

        :param parameter: A DefaultSelectParameter object.
        :type parameter: DefaultSelectParameter
        """
        super(DefaultSelectParameterWidget, self).__init__(parameter, parent)

        self.default_layout = QHBoxLayout()
        self.radio_button_layout = QHBoxLayout()
        self.radio_button_widget = QWidget()

        self.default_label = QLabel(tr('Default'))

        # Create radio button group
        self.default_input_button_group = QButtonGroup()

        # Define string enabler for radio button
        self.radio_button_enabler = self.input.itemData(0, Qt.UserRole)

        for i in range(len(self._parameter.default_labels)):
            if '%s' in self._parameter.default_labels[i]:
                label = (
                    self._parameter.default_labels[i] %
                    self._parameter.default_values[i])
            else:
                label = self._parameter.default_labels[i]

            radio_button = QRadioButton(label)
            self.radio_button_layout.addWidget(radio_button)
            self.default_input_button_group.addButton(radio_button, i)
            if self._parameter.default_value == \
                    self._parameter.default_values[i]:
                radio_button.setChecked(True)

        # Create double spin box for custom value
        self.custom_value = QDoubleSpinBox()
        if self._parameter.default_values[-1]:
            self.custom_value.setValue(self._parameter.default_values[-1])
        has_min = False
        if self._parameter.minimum is not None:
            has_min = True
            self.custom_value.setMinimum(self._parameter.minimum)
        has_max = False
        if self._parameter.maximum is not None:
            has_max = True
            self.custom_value.setMaximum(self._parameter.maximum)
        if has_min and has_max:
            step = (self._parameter.maximum - self._parameter.minimum) / 100.0
            self.custom_value.setSingleStep(step)
        self.radio_button_layout.addWidget(self.custom_value)

        self.toggle_custom_value()

        # Reset the layout
        self.input_layout.setParent(None)
        self.help_layout.setParent(None)

        self.label.setParent(None)
        self.inner_input_layout.setParent(None)

        self.input_layout = QGridLayout()
        self.input_layout.setSpacing(0)

        self.input_layout.addWidget(self.label, 0, 0)
        self.input_layout.addLayout(self.inner_input_layout, 0, 1)
        self.input_layout.addWidget(self.default_label, 1, 0)
        self.input_layout.addLayout(self.radio_button_layout, 1, 1)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        # check every added combobox, it could have been toggled by
        # the existing keyword
        self.toggle_input()

        # Connect
        # noinspection PyUnresolvedReferences
        self.input.currentIndexChanged.connect(self.toggle_input)
        self.default_input_button_group.buttonClicked.connect(
            self.toggle_custom_value)

    def raise_invalid_type_exception(self):
        message = 'Expecting element type of %s' % (
            self._parameter.element_type.__name__)
        err = ValueError(message)
        return err

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultSelectParameter from the current state of widget.
        """
        current_index = self.input.currentIndex()
        selected_value = self.input.itemData(current_index, Qt.UserRole)
        if hasattr(selected_value, 'toPyObject'):
            selected_value = selected_value.toPyObject()

        try:
            self._parameter.value = selected_value
        except ValueError:
            err = self.raise_invalid_type_exception()
            raise err

        radio_button_checked_id = self.default_input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.default = None
        # The last radio button (custom) is checked, get the value from the
        # line edit
        elif (radio_button_checked_id ==
                len(self._parameter.default_values) - 1):
            self._parameter.default_values[radio_button_checked_id] \
                = self.custom_value.value()
            self._parameter.default = self.custom_value.value()
        else:
            self._parameter.default = self._parameter.default_values[
                radio_button_checked_id]

        return self._parameter

    def set_default(self, default):
        """Set default value by item's string.

        :param default: The default.
        :type default: str, int

        :returns: True if success, else False.
        :rtype: bool
        """
        # Find index of choice
        try:
            default_index = self._parameter.default_values.index(default)
            self.default_input_button_group.button(default_index).setChecked(
                True)
        except ValueError:
            last_index = len(self._parameter.default_values) - 1
            self.default_input_button_group.button(last_index).setChecked(
                True)
            self.custom_value.setValue(default)

        self.toggle_custom_value()

    def toggle_custom_value(self):
        radio_button_checked_id = self.default_input_button_group.checkedId()
        if (radio_button_checked_id ==
                len(self._parameter.default_values) - 1):
            self.custom_value.setDisabled(False)
        else:
            self.custom_value.setDisabled(True)

    def toggle_input(self):
        """Change behaviour of radio button based on input."""
        current_index = self.input.currentIndex()
        # If current input is not a radio button enabler, disable radio button.
        if self.input.itemData(current_index, Qt.UserRole) != (
                self.radio_button_enabler):
            self.disable_radio_button()
        # Otherwise, enable radio button.
        else:
            self.enable_radio_button()

    def set_selected_radio_button(self):
        """Set selected radio button to 'Do not report'."""
        dont_use_button = self.default_input_button_group.button(
            len(self._parameter.default_values) - 2)
        dont_use_button.setChecked(True)

    def disable_radio_button(self):
        """Disable radio button group and custom value input area."""
        checked = self.default_input_button_group.checkedButton()
        if checked:
            self.default_input_button_group.setExclusive(False)
            checked.setChecked(False)
            self.default_input_button_group.setExclusive(True)
        for button in self.default_input_button_group.buttons():
            button.setDisabled(True)
        self.custom_value.setDisabled(True)

    def enable_radio_button(self):
        """Enable radio button and custom value input area then set selected
        radio button to 'Do not report'.
        """
        for button in self.default_input_button_group.buttons():
            button.setEnabled(True)
        self.set_selected_radio_button()
        self.custom_value.setEnabled(True)
예제 #11
0
class DefaultValueParameterWidget(GenericParameterWidget):

    """Widget class for Default Value Parameter."""

    def __init__(self, parameter, parent=None):
        """Constructor.

        :param parameter: A DefaultValueParameter object.
        :type parameter: DefaultValueParameter

        """
        super(DefaultValueParameterWidget, self).__init__(parameter, parent)

        self.radio_button_layout = QHBoxLayout()

        # Create radio button group
        self.input_button_group = QButtonGroup()

        for i in range(len(self._parameter.labels)):
            if '%s' in self._parameter.labels[i]:
                label = (
                    self._parameter.labels[i] %
                    self._parameter.options[i])
            else:
                label = self._parameter.labels[i]

            radio_button = QRadioButton(label)
            self.radio_button_layout.addWidget(radio_button)
            self.input_button_group.addButton(radio_button, i)
            if self._parameter.value == \
                    self._parameter.options[i]:
                radio_button.setChecked(True)

        # Create double spin box for custom value
        self.custom_value = QDoubleSpinBox()
        self.custom_value.setSingleStep(0.1)
        if self._parameter.options[-1]:
            self.custom_value.setValue(self._parameter.options[-1])
        self.radio_button_layout.addWidget(self.custom_value)

        self.toggle_custom_value()

        self.inner_input_layout.addLayout(self.radio_button_layout)

        # Connect
        # noinspection PyUnresolvedReferences
        self.input_button_group.buttonClicked.connect(
            self.toggle_custom_value)

    def raise_invalid_type_exception(self):
        """Raise invalid type."""
        message = 'Expecting element type of %s' % (
            self._parameter.element_type.__name__)
        err = ValueError(message)
        return err

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultValueParameter from the current state of widget
        :rtype: DefaultValueParameter
        """
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.value = None
        # The last radio button (custom) is checked, get the value from the
        # line edit
        elif radio_button_checked_id == len(self._parameter.options) - 1:
            self._parameter.options[radio_button_checked_id] = \
                self.custom_value.value()
            self._parameter.value = self.custom_value.value()
        else:
            self._parameter.value = self._parameter.options[
                radio_button_checked_id]

        return self._parameter

    def set_value(self, value):
        """Set value by item's string.

        :param value: The value.
        :type value: str, int

        :returns: True if success, else False.
        :rtype: bool
        """
        # Find index of choice
        try:
            value_index = self._parameter.options.index(value)
            self.input_button_group.button(value_index).setChecked(True)
        except ValueError:
            last_index = len(self._parameter.options) - 1
            self.input_button_group.button(last_index).setChecked(
                True)
            self.custom_value.setValue(value)

        self.toggle_custom_value()

    def toggle_custom_value(self):
        """Enable or disable the custom value line edit."""
        radio_button_checked_id = self.input_button_group.checkedId()
        if (radio_button_checked_id ==
                len(self._parameter.options) - 1):
            self.custom_value.setDisabled(False)
        else:
            self.custom_value.setDisabled(True)
class DefaultValueParameterWidget(GenericParameterWidget):

    """Widget class for Default Value Parameter."""

    def __init__(self, parameter, parent=None):
        """Constructor.

        :param parameter: A DefaultValueParameter object.
        :type parameter: DefaultValueParameter

        """
        super(DefaultValueParameterWidget, self).__init__(parameter, parent)

        self.radio_button_layout = QHBoxLayout()

        # Create radio button group
        self.input_button_group = QButtonGroup()

        for i in range(len(self._parameter.labels)):
            if '%s' in self._parameter.labels[i]:
                label = (
                    self._parameter.labels[i] %
                    self._parameter.options[i])
            else:
                label = self._parameter.labels[i]

            radio_button = QRadioButton(label)
            self.radio_button_layout.addWidget(radio_button)
            self.input_button_group.addButton(radio_button, i)
            if self._parameter.value == \
                    self._parameter.options[i]:
                radio_button.setChecked(True)

        # Create double spin box for custom value
        self.custom_value = QDoubleSpinBox()
        self.custom_value.setSingleStep(0.1)
        if self._parameter.options[-1]:
            self.custom_value.setValue(self._parameter.options[-1])
        self.radio_button_layout.addWidget(self.custom_value)

        self.toggle_custom_value()

        self.inner_input_layout.addLayout(self.radio_button_layout)

        # Connect
        # noinspection PyUnresolvedReferences
        self.input_button_group.buttonClicked.connect(
            self.toggle_custom_value)

    def raise_invalid_type_exception(self):
        """Raise invalid type."""
        message = 'Expecting element type of %s' % (
            self._parameter.element_type.__name__)
        err = ValueError(message)
        return err

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultValueParameter from the current state of widget
        :rtype: DefaultValueParameter
        """
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.value = None
        # The last radio button (custom) is checked, get the value from the
        # line edit
        elif radio_button_checked_id == len(self._parameter.options) - 1:
            self._parameter.options[radio_button_checked_id] = \
                self.custom_value.value()
            self._parameter.value = self.custom_value.value()
        else:
            self._parameter.value = self._parameter.options[
                radio_button_checked_id]

        return self._parameter

    def set_value(self, value):
        """Set value by item's string.

        :param value: The value.
        :type value: str, int

        :returns: True if success, else False.
        :rtype: bool
        """
        # Find index of choice
        try:
            value_index = self._parameter.options.index(value)
            self.input_button_group.button(value_index).setChecked(True)
        except ValueError:
            last_index = len(self._parameter.options) - 1
            self.input_button_group.button(last_index).setChecked(
                True)
            self.custom_value.setValue(value)

        self.toggle_custom_value()

    def toggle_custom_value(self):
        """Enable or disable the custom value line edit."""
        radio_button_checked_id = self.input_button_group.checkedId()
        if (radio_button_checked_id ==
                len(self._parameter.options) - 1):
            self.custom_value.setDisabled(False)
        else:
            self.custom_value.setDisabled(True)
예제 #13
0
 def create_rows(self, layout, sarea):
     u"""Build the rows of the dialog box"""
     play_button_group = QButtonGroup(sarea)
     old_play_button_group = QButtonGroup(sarea)
     for num, entry in enumerate(self.entries_list, 2):
         tt_text = self.build_text_help_label(entry)
         ico_label = QLabel('', sarea)
         ico_label.setToolTip(tt_text)
         if entry.icon:
             ico_label.setPixmap(QPixmap.fromImage(entry.icon))
         layout.addWidget(ico_label, num, 0)
         tt_label = QLabel(entry.display_word, sarea)
         tt_label.setToolTip(tt_text)
         layout.addWidget(tt_label, num, 1)
         if self.hide_text:
             tt_label.hide()
         # Play button.
         t_play_button = QPushButton(sarea)
         play_button_group.addButton(t_play_button, num-2)
         t_play_button.setToolTip(self.play_help)
         t_play_button.setIcon(QIcon(os.path.join(icons_dir, 'play.png')))
         layout.addWidget(t_play_button, num, self.play_column)
         if self.note[entry.audio_field_name]:
             t_play_old_button = QPushButton(sarea)
             old_play_button_group.addButton(t_play_old_button, num-2)
             t_play_old_button.setIcon(
                 QIcon(os.path.join(icons_dir, 'play.png')))
             if not self.hide_text:
                 t_play_old_button.setToolTip(
                     self.note[entry.audio_field_name])
             else:
                 t_play_old_button.setToolTip(self.play_old_help_short)
             layout.addWidget(t_play_old_button, num, self.play_old_column)
         else:
             dummy_label = QLabel('', sarea)
             dummy_label.setToolTip(self.play_old_empty_line_help)
             layout.addWidget(dummy_label, num, self.play_old_column)
         # The group where we later look what to do:
         t_button_group = QButtonGroup(sarea)
         t_button_group.setExclusive(True)
         # Now the four buttons
         t_add_button = QPushButton(sarea)
         t_add_button.setCheckable(True)
         t_add_button.setFlat(True)
         t_add_button.setToolTip(self.add_help_text_short)
         t_add_button.setIcon(QIcon(os.path.join(icons_dir, 'add.png')))
         layout.addWidget(t_add_button, num, self.add_column)
         t_button_group.addButton(t_add_button, Action.Add)
         t_keep_button = QPushButton(sarea)
         t_keep_button.setCheckable(True)
         t_keep_button.setFlat(True)
         t_keep_button.setToolTip(self.keep_help_text_short)
         t_keep_button.setIcon(QIcon(os.path.join(icons_dir, 'keep.png')))
         layout.addWidget(t_keep_button, num, self.keep_column)
         t_button_group.addButton(t_keep_button, Action.Keep)
         t_delete_button = QPushButton(sarea)
         t_delete_button.setCheckable(True)
         t_delete_button.setFlat(True)
         t_delete_button.setToolTip(self.delete_help_text_short)
         t_delete_button.setIcon(
             QIcon(os.path.join(icons_dir, 'delete.png')))
         layout.addWidget(t_delete_button, num, self.delete_column)
         t_button_group.addButton(t_delete_button,  Action.Delete)
         t_blacklist_button = QPushButton(sarea)
         t_blacklist_button.setCheckable(True)
         t_blacklist_button.setFlat(True)
         t_blacklist_button.setToolTip(self.blacklist_help_text_short)
         t_blacklist_button.setIcon(
             QIcon(os.path.join(icons_dir, 'blacklist.png')))
         if entry.entry_hash:
             layout.addWidget(
                 t_blacklist_button, num, self.blacklist_column)
         else:
             t_blacklist_button.hide()
             dummy_label_bl = QLabel('', sarea)
             dummy_label_bl.setToolTip(self.blacklist_empty_line_help)
             layout.addWidget(dummy_label_bl, num, self.blacklist_column)
         t_button_group.button(entry.action).setChecked(True)
         # New: check a button based on how good the downloader is.
         t_button_group.addButton(t_blacklist_button, Action.Blacklist)
         self.buttons_groups.append(t_button_group)
     play_button_group.buttonClicked.connect(
         lambda button: play(
             self.entries_list[play_button_group.id(button)].file_path))
     # N.B.: anki.sound.play() plays files from anywhere, not just
     # from the colection.media folder. We should be good,
     # here. (This behaviour may be a security risk, idk.)
     old_play_button_group.buttonClicked.connect(
         lambda button: playFromText(
             self.note[
                 self.entries_list[
                     old_play_button_group.id(button)].audio_field_name]))
예제 #14
0
class GroupSelectParameterWidget(GenericParameterWidget):
    """Widget class for Group Select Parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor.

        :param parameter: A GroupSelectParameter object.
        :type parameter: GroupSelectParameter
        """
        QWidget.__init__(self, parent)
        self._parameter = parameter

        # Store spin box
        self.spin_boxes = {}

        # Create elements
        # Label (name)
        self.label = QLabel(self._parameter.name)

        # Layouts
        self.main_layout = QVBoxLayout()
        self.input_layout = QVBoxLayout()

        # _inner_input_layout must be filled with widget in the child class
        self.inner_input_layout = QVBoxLayout()

        self.radio_button_layout = QGridLayout()

        # Create radio button group
        self.input_button_group = QButtonGroup()

        # List widget
        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_widget.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_widget.setDefaultDropAction(Qt.MoveAction)
        self.list_widget.setEnabled(False)
        self.list_widget.setSizePolicy(QSizePolicy.Maximum,
                                       QSizePolicy.Expanding)

        for i, key in enumerate(self._parameter.options):
            value = self._parameter.options[key]
            radio_button = QRadioButton(value.get('label'))
            self.radio_button_layout.addWidget(radio_button, i, 0)
            if value.get('type') == SINGLE_DYNAMIC:
                double_spin_box = QDoubleSpinBox()
                self.radio_button_layout.addWidget(double_spin_box, i, 1)
                double_spin_box.setValue(value.get('value', 0))
                double_spin_box.setMinimum(
                    value.get('constraint', {}).get('min', 0))
                double_spin_box.setMaximum(
                    value.get('constraint', {}).get('max', 1))
                double_spin_box.setSingleStep(
                    value.get('constraint', {}).get('step', 0.01))
                step = double_spin_box.singleStep()
                if step > 1:
                    precision = 0
                else:
                    precision = len(str(step).split('.')[1])
                    if precision > 3:
                        precision = 3
                double_spin_box.setDecimals(precision)
                self.spin_boxes[key] = double_spin_box

                # Enable spin box depends on the selected option
                if self._parameter.selected == key:
                    double_spin_box.setEnabled(True)
                else:
                    double_spin_box.setEnabled(False)

            elif value.get('type') == STATIC:
                static_value = value.get('value', 0)
                if static_value is not None:
                    self.radio_button_layout.addWidget(
                        QLabel(str(static_value)), i, 1)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                selected_fields = value.get('value', [])
                if self._parameter.selected == key:
                    self.list_widget.setEnabled(True)
                else:
                    self.list_widget.setEnabled(False)

            self.input_button_group.addButton(radio_button, i)
            if self._parameter.selected == key:
                radio_button.setChecked(True)

        # Help text
        self.help_label = QLabel(self._parameter.help_text)
        self.help_label.setSizePolicy(QSizePolicy.Maximum,
                                      QSizePolicy.Expanding)
        self.help_label.setWordWrap(True)
        self.help_label.setAlignment(Qt.AlignTop)

        self.inner_input_layout.addLayout(self.radio_button_layout)
        self.inner_input_layout.addWidget(self.list_widget)

        # Put elements into layouts
        self.input_layout.addWidget(self.label)
        self.input_layout.addLayout(self.inner_input_layout)

        self.help_layout = QVBoxLayout()
        self.help_layout.addWidget(self.help_label)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        self.setLayout(self.main_layout)

        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)

        # Update list widget
        self.update_list_widget()

        # Connect signal
        self.input_button_group.buttonClicked.connect(
            self.radio_buttons_clicked)

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultValueParameter from the current state of widget
        :rtype: DefaultValueParameter
        """
        # Set value for each key
        for key, value in self._parameter.options.items():
            if value.get('type') == STATIC:
                continue
            elif value.get('type') == SINGLE_DYNAMIC:
                new_value = self.spin_boxes.get(key).value()
                self._parameter.set_value_for_key(key, new_value)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                # Need to iterate through all items
                items = []
                for index in xrange(self.list_widget.count()):
                    items.append(self.list_widget.item(index))
                new_value = [i.text() for i in items]
                self._parameter.set_value_for_key(key, new_value)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.selected = None
        else:
            self._parameter.selected = self._parameter.options.keys(
            )[radio_button_checked_id]

        return self._parameter

    def update_list_widget(self):
        """Update list widget when radio button is clicked."""
        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id > -1:
            selected_dict = self._parameter.options.values(
            )[radio_button_checked_id]
            if selected_dict.get('type') == MULTIPLE_DYNAMIC:
                for field in selected_dict.get('value'):
                    # Update list widget
                    field_item = QListWidgetItem(self.list_widget)
                    field_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable
                                        | Qt.ItemIsDragEnabled)
                    field_item.setData(Qt.UserRole, field)
                    field_item.setText(field)
                    self.list_widget.addItem(field_item)

    def radio_buttons_clicked(self):
        """Handler when selected radio button changed."""
        # Disable all spin boxes
        for spin_box in self.spin_boxes.values():
            spin_box.setEnabled(False)
        # Disable list widget
        self.list_widget.setEnabled(False)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()

        if radio_button_checked_id > -1:
            selected_value = self._parameter.options.values(
            )[radio_button_checked_id]
            if selected_value.get('type') == MULTIPLE_DYNAMIC:
                # Enable list widget
                self.list_widget.setEnabled(True)
            elif selected_value.get('type') == SINGLE_DYNAMIC:
                selected_key = self._parameter.options.keys(
                )[radio_button_checked_id]
                self.spin_boxes[selected_key].setEnabled(True)

    def select_radio_button(self, key):
        """Helper to select a radio button with key.

        :param key: The key of the radio button.
        :type key: str
        """
        key_index = self._parameter.options.keys().index(key)
        radio_button = self.input_button_group.button(key_index)
        radio_button.click()
예제 #15
0
class QuestionDlg(QDialog):
    def __init__(self,parent=None):
        super(QuestionDlg,self).__init__(parent)
        # self.setStyleSheet("background-image:url('image/panelbg.jpg'); border: 2px; border-radius 2px;")
        self.setWindowFlags(Qt.CustomizeWindowHint)
        # self.setStyleSheet("border: 2px; border-radius 2px;")
        # self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet("background-color: rgba(132, 171, 208, 200);")

        tabWidget=QTabWidget(self)
        tabWidget.currentChanged.connect(self.changeTab)
        # tabWidget.setTabShape(QTabWidget.Triangular)
        tabWidget.setStyleSheet("QTabWidget::pane{border-width:1px;border-color:rgb(48, 104, 151);\
            border-style: outset;background-color: rgb(132, 171, 208);\
            background: transparent;} \
            QTabWidget::tab-bar{border-width:0px;}\
            QTabBar::tab { height: 60px; width: 260px; color:rgb(0, 0, 255); font-size:20px; font-weight:bold;} \
            QTabBar::tab:hover{background:rgb(255,255, 255, 100);} \
            QTabBar::tab:selected{border-color:green;background-color:white;color:green;}")
        # tabWidget.setStyleSheet("QTabBar::tab:hover{background:rgb(255,255, 255, 100);}")
        self.btngroup = QButtonGroup()
        self.popMenu = QMenu(self)
        entry1 = self.popMenu.addAction("正确")
        self.connect(entry1,SIGNAL('triggered()'), lambda : self.answerRight())
        entry2 = self.popMenu.addAction("错误")
        self.connect(entry2,SIGNAL('triggered()'), lambda : self.answerWrong())
        entry3 = self.popMenu.addAction("替换")
        self.connect(entry3,SIGNAL('triggered()'), lambda : self.resetStudent())

        w1=QWidget()
        w1.setAccessibleName("w1tab")
        self.w1title = QLabel()
        self.btn_start = MyButton("开始")
        self.choicenum_text = QComboBox()
        self.choicenum_text.setObjectName('w1combonums')
        # self.w1title.setStyleSheet("background-image:url('image/panelbg.jpg');")
        

        titleLayout, btnlayout, bottomlayout = self.genOneTab(tabtitle = self.w1title, tabbtn=self.btn_start, tabnums=self.choicenum_text)

        tab1layout = QVBoxLayout()
        tab1layout.addLayout(titleLayout)       
        tab1layout.addLayout(btnlayout)
        tab1layout.addLayout(bottomlayout)
                
        w1.setLayout(tab1layout)
        w1.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")

        w2=QWidget()
        w2.setAccessibleName("w2tab")
        self.w2title = QLabel()
        self.btn_start2 = QPushButton("开始")
        self.choicenum_text2 = QComboBox()
        self.choicenum_text2.setObjectName('w2combonums')
        titleLayout2, btnlayout2, bottomlayout2 = self.genOneTab(tabtitle = self.w2title, tabbtn=self.btn_start2, tabnums=self.choicenum_text2, strwhere = "where studentsn like '04%' ")
        tab2layout = QVBoxLayout()
        tab2layout.addLayout(titleLayout2)       
        tab2layout.addLayout(btnlayout2)
        tab2layout.addLayout(bottomlayout2)
        w2.setLayout(tab2layout)
        w2.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")

        tabWidget.addTab(w1,"三(3)班")
        tabWidget.addTab(w2,"三(4)班")
        tabWidget.resize(740,700)
        # print(tabWidget.parentWidget())
        btnclose = QPushButton(self)
        btnclose.setToolTip("关闭")
        btnclose.setText("╳")
        btnclose.setGeometry(715, 5, 20, 20)
        btnclose.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnclose.clicked.connect(self.close)
        btnMinimized = QPushButton(self)
        btnMinimized.setToolTip("最小化")
        btnMinimized.setText("▁")
        btnMinimized.setGeometry(690, 5, 20, 20)
        btnMinimized.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnMinimized.clicked.connect(lambda: self.showMinimized())
        self.btnSysMenu = QPushButton(self)
        # self.btnSysMenu.setText("▼")
        self.btnSysMenu.setGeometry(665, 5, 20, 20)
        self.btnSysMenu.setToolTip("系统设置")
        self.btnSysMenu.clicked.connect(lambda: self.showMinimized())
        menufont = QFont("宋体", 10)
        popMenu = QMenu(self)
        entry1 = popMenu.addAction("初始化")
        entry1.setFont(menufont)
        self.connect(entry1,SIGNAL('triggered()'), self.initStudent)
        entry2 = popMenu.addAction("清除提问人员")
        entry2.setFont(menufont)
        self.connect(entry2,SIGNAL('triggered()'), self.deleteTmpdata)
        self.btnSysMenu.setMenu(popMenu)
        self.btnSysMenu.setStyleSheet("QPushButton::menu-indicator {image: url('image/sysmenu.png');subcontrol-position: right center;} ")
        # self.btnSysMenu.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255);")

        authorinfo = QLabel(tabWidget)
        # authorinfo.setToolTip("关闭")
        authorinfo.setText("汕头市大华一小:赵小娜")
        authorinfo.setGeometry(20, 665, 235, 26)
        authorinfo.setStyleSheet("background-color:rgba(255, 255, 255,160); font-size:20px;border: 1px solid rgb(60,200,255,200);color:rgba(0,0,0,220);border-radius:12px;")

        self.setWindowTitle("课堂随机提问")
        self.setWindowIcon(QIcon("image/start.ico"))
        self.setGeometry(100, 20, 740, 700)

        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

        self.btn_start.setMyarg('start')
        # print(self.btn_start.getMyarg())

        self.connect(self.btn_start, SIGNAL("clicked()"), self.startChoice)
        # self.connect(self.w1title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        self.connect(self.btn_start2, SIGNAL("clicked()"), self.startChoice)
        # self.connect(self.w2title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        self.btngroup.buttonClicked[int].connect(self.btns_click)
        # self.connect(self.btn_start,  SIGNAL("myslot(PyQt_PyObject)"), self.myslot)  
        # self.connect(self.btngroup, SIGNAL("buttonClicked(int)"), lambda:self.btns_click())

    def myslot(self, text):  
        # print(text)
        self.g_curbtn = text
        if self.g_curbtn not in self.dict_choices:
            self.btnSysMenu.setFocus()
            return

        # print(self.btngroup.button(int(self.g_curbtn)).parent())
        # print(type(self.btngroup.button(int(self.g_curbtn)).parentWidget()))
        pos = self.btngroup.button(int(self.g_curbtn)).parent().mapToGlobal(self.btngroup.button(int(self.g_curbtn)).pos())
        width = self.btngroup.button(int(self.g_curbtn)).rect().height()
        # print("-----", pos, width)
        pos.setY(pos.y()+width-5)

        indx = 0
        for istate in self.dict_choices[self.g_curbtn]:
            if istate == '1':
                self.popMenu.actions()[indx].setEnabled(True)
            elif istate == '0':
                self.popMenu.actions()[indx].setEnabled(False)
            indx += 1
        self.popMenu.exec_(pos)
        self.btnSysMenu.setFocus()
    # def on_context_menu(self, point):
    #     print(point)
    #     self.popMenu.exec_(self.button.mapToGlobal(point)) 

    def btns_click(self, btnid):
        # print(self.btngroup.button(btnid).rect())
        # print(self.mapToGlobal(self.btngroup.button(btnid).pos()))
        cur = conn.cursor()
        today = datetime.date.today()
        self.g_curbtn = str(btnid).zfill(4)
        if self.g_curbtn not in self.dict_choices:
            self.btngroup.button(int(self.g_curbtn)).setStyleSheet(stylesheetstr_new)
            cur.execute("select count(*) from tmprecord where studentsn='" + str(self.g_curbtn) + "'")
            if cur.fetchall()[0][0] == 0:
                strsql = "insert into tmprecord values (?, ?, ?)"
                cur.execute(strsql, (None, self.g_curbtn, today))
                conn.commit()
            self.dict_choices[self.g_curbtn] = "111"
        else:
            self.btngroup.button(int(self.g_curbtn)).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(self.g_curbtn)).setIcon(QIcon())
            # cur.execute("select count(*) from tmprecord where studentsn='" + str(self.g_curbtn) + "'")
            # print(cur.fetchall())
            cur.execute("delete from tmprecord where studentsn='"+ str(self.g_curbtn) + "'")
            conn.commit()
            self.dict_choices.pop(self.g_curbtn)
        self.btnSysMenu.setFocus()
        cur.close()

    def initStudent(self):
        cur = conn.cursor()
        cur.execute("update student set wrongquestions=0")
        conn.commit()
        cur.execute("update student set rightquestions=0")
        conn.commit()

        # cur.execute("select * from student")
        # print(cur.fetchall())
        cur.close()

    def deleteTmpdata(self):
        cur = conn.cursor()
        cur.execute("delete from tmprecord where 1=1" )
        conn.commit()
        cur.close()

    def changeTab(self, curtab):
        if curtab == 0:
            strwhere = " and studentsn like '03%' "
        elif curtab == 1:
            strwhere = " and studentsn like '04%' "

        self.g_curbtn = ""
        self.dict_choices = {}

        cur = conn.cursor()
        cur.execute("delete from tmprecord where 1=1")
        conn.commit()
        cur.execute("select studentsn from student where 1=1 " + strwhere)
        self.studentSnlst = cur.fetchall()

        for isn in self.studentSnlst:
            self.btngroup.button(int(isn[0])).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(isn[0])).setIcon(QIcon())

        # print(self.studentSnlst)
        self.group_animation = groupAnimation(self.studentSnlst, self.btngroup)
        # print(self.group_animation)

        cur.close()

    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            QDialog.mousePressEvent(self,event)
            return
        # print(event.sender(), event.button())
        self.offset = event.pos()
        # print(self.offset)

    def mouseMoveEvent(self, event):
        if hasattr(self, 'offset'):
            x=event.globalX()
            y=event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x-x_w, y-y_w)
        else:
            pass

    def genOneTab(self, tabtitle="", tabbtn="", tabnums="", strwhere = "where studentsn like '03%' "):
        # tabtitle.setFixedHeight(40)
        # tabtitle.setFixedWidth(160)
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setText("随堂提问演板")
        tabtitle.setStyleSheet("border: 1px solid blue; color:rgba(0,0,255, 220);\
            background-color:rgba(201,201,201,60);\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        tabtitle.setMinimumHeight(50);
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)
       
        btnlayout = QGridLayout()
        
        cur = conn.cursor()
        strsql = "select studentsn, studentname from student " + strwhere
        cur.execute(strsql)
     
        tmpnum = 0
        for item in cur.fetchall():
            irow = tmpnum // 7
            icol = tmpnum % 7
            tmpnum += 1
            btnlayout.setRowMinimumHeight(irow, 80)

            tmpbtn = MyButton(item[1])
            tmpbtn.setMyarg(item[0])
            # tmpbtn.setFixedHeight(20)
            tmpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding))
            # tmpbtn.setStyleSheet("border: 1px solid rgb(255,255,255,0);background-color: rgba(255,255,255,20);font-size:16px;")
            # tmpbtn.setFlat(True)
            self.connect(tmpbtn,  SIGNAL("myslot(PyQt_PyObject)"), self.myslot)
            # self.connect(tmpbtn, SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)

            tmpbtn.setAutoDefault(False)
            self.btngroup.addButton(tmpbtn, int(item[0]))

            btnlayout.addWidget(tmpbtn, irow, icol)

        tabbtn.setIcon(QIcon("image/start.png"))
        tabbtn.setStyleSheet("border: 1px solid yellow;")
        tabbtn.setFixedHeight(40)
        tabbtn.setFixedWidth(100)
        tabbtn.setFont(QFont('宋体', 20))
        # tabnums.setFixedHeight(45)
        # tabnums.setFixedWidth(60)
        tabnums.setFont(QFont('Courier New', 20))
        tabnums.setFixedHeight(45)
        tabnums.setStyleSheet("border: 2px solid blue; color:red;font-weight:light;font-size:26px;\
            border-radius: 6px; \
            min-width: 2em; ")
        tabnums.setEditable(True)
        tabnums.lineEdit().setReadOnly(True);
        tabnums.lineEdit().setAlignment(Qt.AlignCenter);

        model = tabnums.model()
        for row in list(range(1, 7)):
            item = QStandardItem(str(row))
            item.setTextAlignment(Qt.AlignCenter)
            item.setForeground(QColor('red'))
            item.setBackground(QColor(0,200,50, 130))
            model.appendRow(item)
        tabnums.setCurrentIndex(2)
        # tabnums.setStyleSheet ("QComboBox::drop-down {border-width: 100px;}")
        # tabnums.setStyleSheet ("QComboBox::down-arrow {image: url(image/downarrow.png);top: 10px;left: 1px;}")

        bottomlayout = QHBoxLayout()
        bottomlayout.setSizeConstraint(QLayout.SetFixedSize)
        bottomlayout.addStretch(10)
        bottomlayout.addWidget(tabbtn)
        bottomlayout.setSpacing(5)
        bottomlayout.addWidget(tabnums)
     
        cur.close()
        return(titleLayout, btnlayout, bottomlayout)
    
    def startChoice(self, usernum="", oldbtn=""): 
        if oldbtn != "":
            flag = str(int(oldbtn[:2]))
        else:
            self.dict_choices = {}
            whichtabpage = self.sender().parentWidget().accessibleName()
            flag = (whichtabpage == "w1tab") and "3" or "4"
            
        if flag== "3":
            strwhere = " and studentsn like '03%' "
            tabCombonums = self.findChild(QComboBox, 'w1combonums')
        else:
            strwhere = " and studentsn like '04%' "
            tabCombonums = self.findChild(QComboBox, 'w2combonums')

        # print(usernum, oldbtn)

        allstudent = []
        lstrecord = ['0000', '1111']
        cur = conn.cursor()   
        cur.execute("select studentsn from tmprecord where 1=1 " + strwhere)  
        for item in cur.fetchall():
            lstrecord.append(item[0])
        # print(lstrecord, 'record', "select studentsn from student where studentsn like '03%' and studentsn not in " + str(tuple(lstrecord)))
        cur.execute("select studentsn from student where studentsn not in " + str(tuple(lstrecord)) + strwhere)
        for item in cur.fetchall():
            allstudent.append(item[0])

        if usernum == "":
            nums = int(tabCombonums.currentText())
        else:
            nums = usernum
        if nums >= len(allstudent):
            cur.execute("delete from tmprecord where 1=1 " + strwhere) #delete tmp date no today
            conn.commit()
            allstudent = []
            cur.execute("select studentsn from student where 1=1 " + strwhere)
            for item in cur.fetchall():
                allstudent.append(item[0])
        # print(tabCombonums.currentText())
        cur.close()

        if oldbtn == "":
            random.seed()
            lstchoices = random.sample(allstudent, nums)
            for ibtn in lstchoices:
                self.dict_choices[ibtn] = "111"

            self.group_animation.start()
            QTimer.singleShot(1200, self.stopmovie)
        else:
            random.seed()
            otherbtn = random.sample(allstudent, 1)[0]
            # self.btngroup.button(int(otherbtn)).setFocus()
            self.dict_choices.pop(oldbtn)
            self.dict_choices[otherbtn] = '111'
            self.stopmovie()
        self.btnSysMenu.setFocus()

    def stopmovie(self):
        self.group_animation.stop()
        for isn in self.studentSnlst:
            self.btngroup.button(int(isn[0])).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(isn[0])).setIcon(QIcon())
    
        cur = conn.cursor()
        today = datetime.date.today()
        for ibtn in self.dict_choices:
            self.btngroup.button(int(ibtn)).setStyleSheet(stylesheetstr_new)
            cur.execute("select count(*) from tmprecord where studentsn='" + str(ibtn) + "'")
            if cur.fetchall()[0][0] == 0:
                strsql = "insert into tmprecord values (?, ?, ?)"
                cur.execute(strsql, (None, ibtn, today))
                conn.commit()

        # cur.execute("select * from tmprecord")
        # print(cur.fetchall())
        cur.close()

    def answerRight(self):
        # print(self.g_curbtn)
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/smile.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))

        cur = conn.cursor()
        cur.execute("select rightquestions from student where studentsn='" + value + "'")
        studentRightQuestions = cur.fetchall()[0][0] + 1
        cur.execute("update student set rightquestions=" + str(studentRightQuestions) + " where studentsn='" + value + "'")
        conn.commit()
        
        ###########
        if self.dict_choices[value] == "101":
            cur.execute("select wrongquestions from student where studentsn='" + value + "'")
            studentWrongQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set wrongquestions=" + str(studentWrongQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        cur.close()

        self.dict_choices[value] = "011"

    def answerWrong(self):
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/cry.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))
        # self.btngroup.button(int(value)).setStyleSheet("border-image: url(image/ex_stu.png);")

        cur = conn.cursor()
        cur.execute("select wrongquestions from student where studentsn='" + value + "'")
        studentWrongQuestions = cur.fetchall()[0][0] + 1
        cur.execute("update student set wrongquestions=" + str(studentWrongQuestions) + " where studentsn='" + value + "'")
        conn.commit()

        if self.dict_choices[value] == "011":
            cur.execute("select rightquestions from student where studentsn='" + value + "'")
            studentRightQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set rightquestions=" + str(studentRightQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        cur.close()
        self.dict_choices[value] = "101"

    def resetStudent(self):
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        # self.btngroup.button(int(value)).parentWidget().setStyleSheet("border: 1px solid rgb(255,255,255,0);background-color: rgba(255,255,255,20);font-size:16px;")
        # self.btngroup.button(int(value)).setStyleSheet("border: 1px solid rgb(255,255,255,0);background-color: rgba(255,255,255,20);font-size:16px;")
        # self.btngroup.button(int(value)).setAutoDefault(False)

        cur = conn.cursor()

        if self.dict_choices[value] == "011":        
            cur.execute("select rightquestions from student where studentsn='" + value + "'")
            studentRightQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set rightquestions=" + str(studentRightQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        if self.dict_choices[value] == "101":
            cur.execute("select wrongquestions from student where studentsn='" + value + "'")
            studentWrongQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set wrongquestions=" + str(studentWrongQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        cur.close()

        self.startChoice(usernum=1, oldbtn=value)
        # print("---reset___")

        # curmenu.actions()[0].setEnabled(True)
        # curmenu.actions()[1].setEnabled(True)
        # self.choiceOneStudent(value)

    def createDb(self):
        cur = conn.cursor()
        sqlstr = 'create table student (id integer primary key, \
            studentsn varchar(20), \
            studentname varchar(20), \
            rightquestions integer, \
            wrongquestions integer)'
        # print(sqlstr)

        sqlstr2 = 'create table tmprecord (id integer primary key, \
            studentsn varchar(20), \
            datequestion date)'

        strdelete = "delete from student where 1=1"
        cur.execute(strdelete)
        conn.commit()
        strdelete = "delete from tmprecord where 1=1"
        cur.execute(strdelete)
        conn.commit()
        # print(sqlstr2)

        # cur.execute(sqlstr) 
        # conn.commit()
        # cur.execute(sqlstr2) 
        # conn.commit()

        # insert example data
        a03lst = ["曾忆谊","赵佳泉","翁文秀","林珑","郑铭洁","林泽思","吴崇霖","陈思嘉","欧阳月孜","郭展羽","詹伟哲","黄佳仪","杨秋霞","周奕子","林楚杰","欧伊涵","许腾誉","陈唯凯","陈树凯","林彦君","张钰佳","高锴","杨博凯","林妙菲","林楚鸿","陈展烯","姚静茵","吴欣桐","范思杰","肖佳","马思广","许一帆","姚奕帆","陈海珣","吴黛莹","吴育桐","肖凯帆","林欣阳","叶茂霖","姚楷臻","陈嘉豪","陈琦","杨子楷","陈炎宏","陈幸仪","杨景畅","罗暖婷","郑馨"]
        a04lst = ["罗恩琪","王可","曾祥威","谢濡婷","温嘉凯","许洁仪","肖欣淇","陈凯佳","林天倩","李乐海","吴文慧","黄文婷","万誉","陈进盛","张裕涵","陈振嘉","王巧玲","林珮琪","陈炜楷","杨健","赵泽锴","张凤临","蔡子丹","陈烨杰","廖妍希","林树超","夏培轩","陈锦森","李星","蔡依婷","姚容创","姚凯扬","沈嘉克","周凡","张玉川","邱金迅","陈菲敏","陈星翰","朱煜楷","郑泽洪","钱剑非","罗奕丰","陈杜炜","林知钦"]
        strsql = "insert into student values (?, ?, ?,?,?)" 
        for i in list(range(0,len(a03lst))):
            cur.execute(strsql, (None, "03"+str(i+1).zfill(2), a03lst[i], 0, 0))
            conn.commit()
        strsql = "insert into student values (?, ?, ?,?,?)" 
        for i in list(range(0,len(a04lst))):
            cur.execute(strsql, (None, "04"+str(i+1).zfill(2), a04lst[i], 0, 0))
            conn.commit()
        cur.close()
예제 #16
0
class DefaultSelectParameterWidget(SelectParameterWidget):
    """Widget class for Default Select Parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor

        :param parameter: A DefaultSelectParameter object.
        :type parameter: DefaultSelectParameter
        """
        super(DefaultSelectParameterWidget, self).__init__(parameter, parent)

        self.default_layout = QHBoxLayout()
        self.radio_button_layout = QHBoxLayout()
        self.radio_button_widget = QWidget()

        self.default_label = QLabel(tr('Default'))

        # Create radio button group
        self.default_input_button_group = QButtonGroup()

        # Define string enabler for radio button
        self.radio_button_enabler = self.input.itemData(0, Qt.UserRole)

        for i in range(len(self._parameter.default_labels)):
            if '%s' in self._parameter.default_labels[i]:
                label = (self._parameter.default_labels[i] %
                         self._parameter.default_values[i])
            else:
                label = self._parameter.default_labels[i]

            radio_button = QRadioButton(label)
            self.radio_button_layout.addWidget(radio_button)
            self.default_input_button_group.addButton(radio_button, i)
            if self._parameter.default_value == \
                    self._parameter.default_values[i]:
                radio_button.setChecked(True)

        # Create double spin box for custom value
        self.custom_value = QDoubleSpinBox()
        if self._parameter.default_values[-1]:
            self.custom_value.setValue(self._parameter.default_values[-1])
        has_min = False
        if self._parameter.minimum is not None:
            has_min = True
            self.custom_value.setMinimum(self._parameter.minimum)
        has_max = False
        if self._parameter.maximum is not None:
            has_max = True
            self.custom_value.setMaximum(self._parameter.maximum)
        if has_min and has_max:
            step = (self._parameter.maximum - self._parameter.minimum) / 100.0
            self.custom_value.setSingleStep(step)
        self.radio_button_layout.addWidget(self.custom_value)

        self.toggle_custom_value()

        # Reset the layout
        self.input_layout.setParent(None)
        self.help_layout.setParent(None)

        self.label.setParent(None)
        self.inner_input_layout.setParent(None)

        self.input_layout = QGridLayout()
        self.input_layout.setSpacing(0)

        self.input_layout.addWidget(self.label, 0, 0)
        self.input_layout.addLayout(self.inner_input_layout, 0, 1)
        self.input_layout.addWidget(self.default_label, 1, 0)
        self.input_layout.addLayout(self.radio_button_layout, 1, 1)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        # check every added combobox, it could have been toggled by
        # the existing keyword
        self.toggle_input()

        # Connect
        # noinspection PyUnresolvedReferences
        self.input.currentIndexChanged.connect(self.toggle_input)
        self.default_input_button_group.buttonClicked.connect(
            self.toggle_custom_value)

    def raise_invalid_type_exception(self):
        message = 'Expecting element type of %s' % (
            self._parameter.element_type.__name__)
        err = ValueError(message)
        return err

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultSelectParameter from the current state of widget.
        """
        current_index = self.input.currentIndex()
        selected_value = self.input.itemData(current_index, Qt.UserRole)
        if hasattr(selected_value, 'toPyObject'):
            selected_value = selected_value.toPyObject()

        try:
            self._parameter.value = selected_value
        except ValueError:
            err = self.raise_invalid_type_exception()
            raise err

        radio_button_checked_id = self.default_input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.default = None
        # The last radio button (custom) is checked, get the value from the
        # line edit
        elif (radio_button_checked_id == len(self._parameter.default_values) -
              1):
            self._parameter.default_values[radio_button_checked_id] \
                = self.custom_value.value()
            self._parameter.default = self.custom_value.value()
        else:
            self._parameter.default = self._parameter.default_values[
                radio_button_checked_id]

        return self._parameter

    def set_default(self, default):
        """Set default value by item's string.

        :param default: The default.
        :type default: str, int

        :returns: True if success, else False.
        :rtype: bool
        """
        # Find index of choice
        try:
            default_index = self._parameter.default_values.index(default)
            self.default_input_button_group.button(default_index).setChecked(
                True)
        except ValueError:
            last_index = len(self._parameter.default_values) - 1
            self.default_input_button_group.button(last_index).setChecked(True)
            self.custom_value.setValue(default)

        self.toggle_custom_value()

    def toggle_custom_value(self):
        radio_button_checked_id = self.default_input_button_group.checkedId()
        if (radio_button_checked_id == len(self._parameter.default_values) -
                1):
            self.custom_value.setDisabled(False)
        else:
            self.custom_value.setDisabled(True)

    def toggle_input(self):
        """Change behaviour of radio button based on input."""
        current_index = self.input.currentIndex()
        # If current input is not a radio button enabler, disable radio button.
        if self.input.itemData(current_index,
                               Qt.UserRole) != (self.radio_button_enabler):
            self.disable_radio_button()
        # Otherwise, enable radio button.
        else:
            self.enable_radio_button()

    def set_selected_radio_button(self):
        """Set selected radio button to 'Do not report'."""
        dont_use_button = self.default_input_button_group.button(
            len(self._parameter.default_values) - 2)
        dont_use_button.setChecked(True)

    def disable_radio_button(self):
        """Disable radio button group and custom value input area."""
        checked = self.default_input_button_group.checkedButton()
        if checked:
            self.default_input_button_group.setExclusive(False)
            checked.setChecked(False)
            self.default_input_button_group.setExclusive(True)
        for button in self.default_input_button_group.buttons():
            button.setDisabled(True)
        self.custom_value.setDisabled(True)

    def enable_radio_button(self):
        """Enable radio button and custom value input area then set selected
        radio button to 'Do not report'.
        """
        for button in self.default_input_button_group.buttons():
            button.setEnabled(True)
        self.set_selected_radio_button()
        self.custom_value.setEnabled(True)
class GroupSelectParameterWidget(GenericParameterWidget):

    """Widget class for Group Select Parameter."""

    def __init__(self, parameter, parent=None):
        """Constructor.

        :param parameter: A GroupSelectParameter object.
        :type parameter: GroupSelectParameter
        """
        QWidget.__init__(self, parent)
        self._parameter = parameter

        # Store spin box
        self.spin_boxes = {}

        # Create elements
        # Label (name)
        self.label = QLabel(self._parameter.name)

        # Layouts
        self.main_layout = QVBoxLayout()
        self.input_layout = QVBoxLayout()

        # _inner_input_layout must be filled with widget in the child class
        self.inner_input_layout = QVBoxLayout()

        self.radio_button_layout = QGridLayout()

        # Create radio button group
        self.input_button_group = QButtonGroup()

        # List widget
        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_widget.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_widget.setDefaultDropAction(Qt.MoveAction)
        self.list_widget.setEnabled(False)
        self.list_widget.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Expanding)

        for i, key in enumerate(self._parameter.options):
            value = self._parameter.options[key]
            radio_button = QRadioButton(value.get('label'))
            self.radio_button_layout.addWidget(radio_button, i, 0)
            if value.get('type') == SINGLE_DYNAMIC:
                double_spin_box = QDoubleSpinBox()
                self.radio_button_layout.addWidget(double_spin_box, i, 1)
                double_spin_box.setValue(value.get('value', 0))
                double_spin_box.setMinimum(
                    value.get('constraint', {}).get('min', 0))
                double_spin_box.setMaximum(value.get(
                    'constraint', {}).get('max', 1))
                double_spin_box.setSingleStep(
                    value.get('constraint', {}).get('step', 0.01))
                step = double_spin_box.singleStep()
                if step > 1:
                    precision = 0
                else:
                    precision = len(str(step).split('.')[1])
                    if precision > 3:
                        precision = 3
                double_spin_box.setDecimals(precision)
                self.spin_boxes[key] = double_spin_box

                # Enable spin box depends on the selected option
                if self._parameter.selected == key:
                    double_spin_box.setEnabled(True)
                else:
                    double_spin_box.setEnabled(False)

            elif value.get('type') == STATIC:
                static_value = value.get('value', 0)
                if static_value is not None:
                    self.radio_button_layout.addWidget(
                        QLabel(str(static_value)), i, 1)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                selected_fields = value.get('value', [])
                if self._parameter.selected == key:
                    self.list_widget.setEnabled(True)
                else:
                    self.list_widget.setEnabled(False)

            self.input_button_group.addButton(radio_button, i)
            if self._parameter.selected == key:
                radio_button.setChecked(True)

        # Help text
        self.help_label = QLabel(self._parameter.help_text)
        self.help_label.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Expanding)
        self.help_label.setWordWrap(True)
        self.help_label.setAlignment(Qt.AlignTop)

        self.inner_input_layout.addLayout(self.radio_button_layout)
        self.inner_input_layout.addWidget(self.list_widget)

        # Put elements into layouts
        self.input_layout.addWidget(self.label)
        self.input_layout.addLayout(self.inner_input_layout)

        self.help_layout = QVBoxLayout()
        self.help_layout.addWidget(self.help_label)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        self.setLayout(self.main_layout)

        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)

        # Update list widget
        self.update_list_widget()

        # Connect signal
        self.input_button_group.buttonClicked.connect(
            self.radio_buttons_clicked)

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultValueParameter from the current state of widget
        :rtype: DefaultValueParameter
        """
        # Set value for each key
        for key, value in self._parameter.options.items():
            if value.get('type') == STATIC:
                continue
            elif value.get('type') == SINGLE_DYNAMIC:
                new_value = self.spin_boxes.get(key).value()
                self._parameter.set_value_for_key(key, new_value)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                # Need to iterate through all items
                items = []
                for index in xrange(self.list_widget.count()):
                    items.append(self.list_widget.item(index))
                new_value = [i.text() for i in items]
                self._parameter.set_value_for_key(key, new_value)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.selected = None
        else:
            self._parameter.selected = self._parameter.options.keys()[
                radio_button_checked_id]

        return self._parameter

    def update_list_widget(self):
        """Update list widget when radio button is clicked."""
        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id > -1:
            selected_dict = self._parameter.options.values()[
                radio_button_checked_id]
            if selected_dict.get('type') == MULTIPLE_DYNAMIC:
                for field in selected_dict.get('value'):
                    # Update list widget
                    field_item = QListWidgetItem(self.list_widget)
                    field_item.setFlags(
                        Qt.ItemIsEnabled |
                        Qt.ItemIsSelectable |
                        Qt.ItemIsDragEnabled)
                    field_item.setData(Qt.UserRole, field)
                    field_item.setText(field)
                    self.list_widget.addItem(field_item)

    def radio_buttons_clicked(self):
        """Handler when selected radio button changed."""
        # Disable all spin boxes
        for spin_box in self.spin_boxes.values():
            spin_box.setEnabled(False)
        # Disable list widget
        self.list_widget.setEnabled(False)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()

        if radio_button_checked_id > -1:
            selected_value = self._parameter.options.values()[
                radio_button_checked_id]
            if selected_value.get('type') == MULTIPLE_DYNAMIC:
                # Enable list widget
                self.list_widget.setEnabled(True)
            elif selected_value.get('type') == SINGLE_DYNAMIC:
                selected_key = self._parameter.options.keys()[
                    radio_button_checked_id]
                self.spin_boxes[selected_key].setEnabled(True)

    def select_radio_button(self, key):
        """Helper to select a radio button with key.

        :param key: The key of the radio button.
        :type key: str
        """
        key_index = self._parameter.options.keys().index(key)
        radio_button = self.input_button_group.button(key_index)
        radio_button.click()
예제 #18
0
class QuestionDlg(QDialog):
    def __init__(self,parent=None):
        super(QuestionDlg,self).__init__(parent)
        # self.setStyleSheet("background-image:url('image/panelbg.jpg'); border: 2px; border-radius 2px;")
        self.setWindowFlags(Qt.CustomizeWindowHint)
        # self.setStyleSheet("border: 2px; border-radius 2px;")
        # self.setWindowFlags(Qt.FramelessWindowHint)
        
        tabWidget=QTabWidget(self)
        tabWidget.currentChanged.connect(self.changeTab)
        # tabWidget.setTabShape(QTabWidget.Triangular)
        tabWidget.setStyleSheet("QTabWidget::pane{border:0px;}\
            QTabBar::tab { height: 60px; width: 260px; color:rgb(0, 0, 255); font-size:20px; font-weight:bold;} \
            QTabBar::tab:hover{background:rgb(255,255, 255, 100);} \
            QTabBar::tab:selected{border-color:green;background-color:white;color:green;}")
        # tabWidget.setStyleSheet("QTabBar::tab:hover{background:rgb(255,255, 255, 100);}")
        self.btngroup = QButtonGroup()

        w1=QWidget()
        w1.setAccessibleName("w1tab")
        self.w1title = QComboBox()
        self.btn_start = QPushButton("开始")
        self.choicenum_text = QComboBox()
        self.choicenum_text.setObjectName('w1combonums')
        # self.w1title.setStyleSheet("background-image:url('image/panelbg.jpg');")

        titleLayout, btnlayout, bottomlayout = self.genOneTab(tabtitle = self.w1title, tabbtn=self.btn_start, tabnums=self.choicenum_text)

        tab1layout = QVBoxLayout()
        tab1layout.addLayout(titleLayout)       
        tab1layout.addLayout(btnlayout)
        tab1layout.addLayout(bottomlayout)
                
        w1.setLayout(tab1layout)
        # w1.setStyleSheet("background-image: url(image/bg.gif);")
        w1.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")
        # w1.setStyleSheet("border-image: url(image/bg2.gif);")
        # firstUi.setupUi(w1)
        w2=QWidget()
        w2.setAccessibleName("w2tab")
        self.w2title = QComboBox()
        self.btn_start2 = QPushButton("开始")
        self.choicenum_text2 = QComboBox()
        self.choicenum_text2.setObjectName('w2combonums')
        titleLayout2, btnlayout2, bottomlayout2 = self.genOneTab(tabtitle = self.w2title, tabbtn=self.btn_start2, tabnums=self.choicenum_text2, strwhere = "where studentsn like '04%' ")
        tab2layout = QVBoxLayout()
        tab2layout.addLayout(titleLayout2)       
        tab2layout.addLayout(btnlayout2)
        tab2layout.addLayout(bottomlayout2)
        w2.setLayout(tab2layout)
        # w2.setStyleSheet("background-image: url(image/bg.gif);")
        w2.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")

        tabWidget.addTab(w1,"三(3)班")
        tabWidget.addTab(w2,"三(4)班")
        tabWidget.resize(760,700)
        # print(tabWidget.parentWidget())
        btnclose = QPushButton(self)
        btnclose.setText("╳")
        btnclose.setGeometry(735, 5, 20, 20)
        btnclose.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnclose.clicked.connect(self.close)
        btnMinimized = QPushButton(self)
        btnMinimized.setText("▁")
        btnMinimized.setGeometry(710, 5, 20, 20)
        btnMinimized.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnMinimized.clicked.connect(lambda: self.showMinimized())
        btnSysMenu = QPushButton(self)
        btnSysMenu.setText("▼")
        btnSysMenu.setGeometry(685, 5, 20, 20)
        btnSysMenu.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnSysMenu.clicked.connect(lambda: self.showMinimized())
        popMenu = QMenu(self)
        entry1 = popMenu.addAction("初始化")
        self.connect(entry1,SIGNAL('triggered()'), self.initStudent)
        entry2 = popMenu.addAction("清除提问人员")
        self.connect(entry2,SIGNAL('triggered()'), self.deleteTmpdata)
        btnSysMenu.setMenu(popMenu)
        btnSysMenu.setStyleSheet("QPushButton::menu-indicator {image: url('image/sysmenu.png');subcontrol-position: right center;}")

        self.lstchoices = []
        self.threadcounter = 0
        # self.createDb()
        cur = conn.cursor()
        # today = datetime.date.today() 
        # cur.execute("delete from tmprecord where datequestion= '" +str(today) + "'") #delete tmp date no today
        cur.execute("delete from tmprecord where 1=1" )
        # cur.execute("delete from tmprecord where datequestion!= '" +str(today) + "'") #delete tmp date no today
        conn.commit()

        cur.execute("select studentsn from student ")
        self.studentSnlst = cur.fetchall()
        cur.close()

        # self.btncolor = self.btngroup.buttons()[0].palette().color(1).getRgb()
        # for i in list(range(0, self.studentNums)):
        # for isn in self.studentSnlst:
        #     self.btngroup.button(int(isn[0])).setStyleSheet("border-image: url(image/ex_stu.png);")
            # print(isn)
        # for i in list(range(0, self.studentNums)):
            # self.btngroup.buttons()[i].setStyleSheet("background-color: rgb(120,220,220);")
            # self.btngroup.buttons()[i].setStyleSheet("border-image: url(image/ex_stu.png);")
            # self.btngroup.buttons()[i].setStyleSheet("background-image: url(image/ex_stu.png);background-size:20px 20px;")

        # print("background-color: rgb(120,220,220);", "background-color: rgb" + str(self.btncolor) + ";")
        self.setWindowTitle("课堂随机提问")
        self.setWindowIcon(QIcon("image/start.ico"))
        self.setGeometry(100, 20, 760, 700)

        self.connect(self.btn_start, SIGNAL("clicked()"), self.startChoice)
        self.connect(self.w1title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        self.connect(self.btn_start2, SIGNAL("clicked()"), self.startChoice)
        self.connect(self.w2title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)

    def initStudent(self):
        cur = conn.cursor()
        cur.execute("update student set wrongquestions=0")
        conn.commit()
        cur.execute("update student set rightquestions=0")
        conn.commit()

        # cur.execute("select * from student")
        # print(cur.fetchall())
        cur.close()

    def deleteTmpdata(self):
        cur = conn.cursor()
        cur.execute("delete from tmprecord where 1=1" )
        conn.commit()
        cur.close()

    def changeTab(self, curtab):
        if curtab == 0:
            strwhere = " and studentsn like '03%' "
        elif curtab == 1:
            strwhere = " and studentsn like '04%' "

        self.lstchoices = []
        self.threadcounter = 0
        cur = conn.cursor()   
        cur.execute("select studentsn from student where 1=1 " + strwhere)
        self.studentSnlst = cur.fetchall()
        for isn in self.studentSnlst:
            self.btngroup.button(int(isn[0])).setStyleSheet("border-image: url(image/ex_stu.png); color:dark;")
            self.btngroup.button(int(isn[0])).setIcon(QIcon())
            # self.btngroup.buttons()[i].setStyleSheet("background-color: rgb(120,220,220);")  
            # self.btngroup.buttons()[i].setStyleSheet("border-image: url(image/ex_stu.png);")
            curmenu = self.btngroup.button(int(isn[0])).menu()
            curmenu.actions()[0].setEnabled(True)
            curmenu.actions()[1].setEnabled(True)
            
        cur.close()

    def mousePressEvent(self, event):
        self.offset = event.pos()
        # print(self.offset)
    def mouseMoveEvent(self, event):
        x=event.globalX()
        y=event.globalY()
        x_w = self.offset.x()
        y_w = self.offset.y()
        self.move(x-x_w, y-y_w)

    def genOneTab(self, tabtitle="", tabbtn="", tabnums="", strwhere = "where studentsn like '03%' "):
        # tabtitle.setFixedHeight(40)
        # tabtitle.setFixedWidth(160)
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setStyleSheet("border: 3px solid blue;\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        model = tabtitle.model()
        for row in ["随堂演板", "随堂提问"]:
            item = QStandardItem(str(row))
            item.setForeground(QColor('blue'))
            item.setBackground(QColor(0,200,50, 130))
            font = item.font()
            font.setPointSize(20)
            item.setFont(font)
            model.appendRow(item)
        tabtitle.setCurrentIndex(0)
        titleLayout = QHBoxLayout()
        tabtitle.setMinimumHeight(50);
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)
       
        btnlayout = QGridLayout()
        
        cur = conn.cursor()
        strsql = "select studentsn, studentname from student " + strwhere
        cur.execute(strsql)
     
        tmpnum = 0
        for item in cur.fetchall():
            irow = tmpnum // 7
            icol = tmpnum % 7
            tmpnum += 1
            btnlayout.setRowMinimumHeight(irow, 80)
            tmpbtn = QPushButton(item[1])
            tmpbtn.setFont(QFont('宋体', 16))
            tmpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding))

            popMenu = QMenu(self)
            entry1 = popMenu.addAction("正确")
            self.connect(entry1,SIGNAL('triggered()'), lambda item=item[0]: self.answerRight(item))
            entry2 = popMenu.addAction("错误")
            self.connect(entry2,SIGNAL('triggered()'), lambda item=item[0]: self.answerWrong(item))
            entry3 = popMenu.addAction("替换")
            self.connect(entry3,SIGNAL('triggered()'), lambda item=item[0]: self.resetStudent(item))
            tmpbtn.setMenu(popMenu)
            tmpbtn.setAutoDefault(False)
            self.btngroup.addButton(tmpbtn, int(item[0]))
            btnlayout.addWidget(tmpbtn, irow, icol)

        tabbtn.setIcon(QIcon("image/start.png"))
        tabbtn.setStyleSheet("border: 5px solid yellow;")
        tabbtn.setFixedHeight(45)
        tabbtn.setFixedWidth(100)
        tabbtn.setFont(QFont('宋体', 20))
        # tabnums.setFixedHeight(40)
        # tabnums.setFixedWidth(60)
        tabnums.setFont(QFont('Courier New', 20))
        tabnums.setStyleSheet("border: 5px solid blue; color:red;font-weight:bold;font-size:26px;\
            border-radius: 6px; \
            padding: 1px 1px 1px 1px;\
            min-width: 2em; ")
        # tabnums.VerticalContentAlignment="Center"
        # tabnums.addItems(["1", "2", "3", "4", "5", "6"])
        model = tabnums.model()
        for row in list(range(1, 7)):
            item = QStandardItem(str(row))
            # item.setStyleSheet("background-color:rgb(0,0,255)")
            item.setForeground(QColor('red'))
            item.setBackground(QColor(0,200,50, 130))
            # font = item.font()
            # font.setPointSize(16)
            # item.setFont(font)
            model.appendRow(item)
        tabnums.setCurrentIndex(2)

        bottomlayout = QHBoxLayout()
        bottomlayout.setSizeConstraint(QLayout.SetFixedSize)
        bottomlayout.addStretch(10)
        bottomlayout.addWidget(tabbtn)
        bottomlayout.setSpacing(5)
        bottomlayout.addWidget(tabnums)
     
        cur.close()
        return(titleLayout, btnlayout, bottomlayout)

    def changeTitle(self, curindex):
        # whichtabpage = self.sender().parentWidget().parentWidget().parentWidget()
        # print(whichtabpage.tabText(0), whichtabpage1)
        for isn in self.studentSnlst:
            self.btngroup.button(int(isn[0])).setStyleSheet("border-image: url(image/ex_stu.png);")
            self.btngroup.button(int(isn[0])).setIcon(QIcon())
            # self.btngroup.buttons()[i].setStyleSheet("background-color: rgb(120,220,220);")  
            # self.btngroup.buttons()[i].setStyleSheet("border-image: url(image/ex_stu.png);")
            curmenu = self.btngroup.button(int(isn[0])).menu()
            curmenu.actions()[0].setEnabled(True)
            curmenu.actions()[1].setEnabled(True)

        whichtabpage = self.sender().parentWidget().accessibleName()
        if whichtabpage == "w1tab":
            if curindex == 1:
                self.choicenum_text.setCurrentIndex(0)
                self.choicenum_text.setEnabled(False)
            else:
                self.choicenum_text.setEnabled(True)
                self.choicenum_text.setCurrentIndex(2)
        else:
            if curindex == 1:
                self.choicenum_text2.setCurrentIndex(0)
                self.choicenum_text2.setEnabled(False)
            else:
                self.choicenum_text2.setEnabled(True)
                self.choicenum_text2.setCurrentIndex(2)

    def startChoice(self): 
        self.lstchoices = []
        self.threadcounter = 0
        whichtabpage = self.sender().parentWidget().accessibleName()
        if whichtabpage == "w1tab":
            strwhere = " and studentsn like '03%' "
            tabCombonums = self.findChild(QComboBox, 'w1combonums')
        else:
            strwhere = " and studentsn like '04%' "
            tabCombonums = self.findChild(QComboBox, 'w2combonums')

        # for i in list(range(0, self.studentNums)):
        cur = conn.cursor()   
        # cur.execute("select studentsn from student where 1=1 " + strwhere)
        # self.studentSnlst = cur.fetchall()

        # for isn in self.studentSnlst:
        #     self.btngroup.button(int(isn[0])).setStyleSheet("border-image: url(image/ex_stu.png);")
        #     self.btngroup.button(int(isn[0])).setIcon(QIcon())
        #     # self.btngroup.buttons()[i].setStyleSheet("background-color: rgb(120,220,220);")  
        #     # self.btngroup.buttons()[i].setStyleSheet("border-image: url(image/ex_stu.png);")
        #     curmenu = self.btngroup.button(int(isn[0])).menu()
        #     curmenu.actions()[0].setEnabled(True)
        #     curmenu.actions()[1].setEnabled(True)

        allstudent = []
        lstrecord = ['0000', '1111']
        if tabCombonums.isEnabled():
            cur.execute("select studentsn from tmprecord where 1=1 " + strwhere)  
            for item in cur.fetchall():
                lstrecord.append(item[0])
        # print(lstrecord, 'record', "select studentsn from student where studentsn like '03%' and studentsn not in " + str(tuple(lstrecord)))
        cur.execute("select studentsn from student where studentsn not in " + str(tuple(lstrecord)) + strwhere)
        for item in cur.fetchall():
            allstudent.append(item[0])

        nums = int(tabCombonums.currentText())
        if nums >= len(allstudent):
            cur.execute("delete from tmprecord where datequestion like '%%' ") #delete tmp date no today
            conn.commit()
            allstudent = []
            cur.execute("select studentsn from student where 1=1 " + strwhere)
            for item in cur.fetchall():
                allstudent.append(item[0])
        # print(tabCombonums.currentText())
        cur.close()
        for i in range(10):
            thread = MyThread(self)
            thread.trigger.connect(self.choicestudent)
            thread.setup(allstudent, nums)            # just setting up a parameter
            thread.start()

    def choicestudent(self, allstudent, num): 
        for isn in self.studentSnlst:
            self.btngroup.button(int(isn[0])).setStyleSheet("border-image: url(image/ex_stu.png);")
            # self.btngroup.buttons()[i].setStyleSheet("background-color: rgb(120,220,220);")
        random.seed()
        self.lstchoices = random.sample(allstudent, num)
        for ibtn in self.lstchoices:
            self.btngroup.button(int(ibtn)).setStyleSheet("border: 6px solid rgb(255,0,0); color:black; font-size:26px;")
            # self.btngroup.button(int(ibtn)).setStyleSheet("border-image: url(image/ex_stu_ok.png); color:dark;")
            # self.btngroup.button(int(ibtn)).setStyleSheet("background-color: red; color:white;")
            # self.btngroup.buttons()[ibtn].setStyleSheet("background-color: red; color:white;")

        self.threadcounter += 1
        if self.threadcounter == 10:
            for isn in self.studentSnlst:
                self.btngroup.button(int(isn[0])).setStyleSheet("border-image: url(image/ex_stu.png);")
            for ibtn in self.lstchoices:
                self.btngroup.button(int(ibtn)).setStyleSheet("border: 6px solid rgb(255,0,0); color:black; font-size:26px;")

            cur = conn.cursor()
            if self.choicenum_text.isEnabled():
                for ibtn in self.lstchoices:
                    today = datetime.date.today()
                    strsql = "insert into tmprecord values (?, ?, ?)" 
                    cur.execute(strsql, (None, ibtn, today))
                    conn.commit()

            # cur.execute("select * from tmprecord")
            # tmpaa = []
            # for item in cur.fetchall():
            #     tmpaa.append(item[1])
            #     # print(item[1], sep="|", end="--")
            # tmpaa.sort()
            # print(tmpaa)
            
            cur.close()
                # print(self.btngroup.buttons()[ibtn].text())
            self.threadcounter = 0

    def choiceOneStudent(self, curbtn, num=1):
        # print(self.findChildren(QComboBox))
        if curbtn[:2] == "03":
            strwhere = " and studentsn like '03%' "
            tabCombonums = self.findChild(QComboBox, 'w1combonums')
        elif  curbtn[:2] == "04":
            strwhere = " and studentsn like '04%' "
            tabCombonums = self.findChild(QComboBox, 'w2combonums')

        allstudent = []
        cur = conn.cursor()   
        lstrecord = ['0000', '1111']
        if tabCombonums.isEnabled():
            cur.execute("select studentsn from tmprecord where 1=1 " + strwhere)  
            for item in cur.fetchall():
                lstrecord.append(item[0])
        cur.execute("select studentsn from student where studentsn not in " + str(tuple(lstrecord)) + strwhere)
        for item in cur.fetchall():
            allstudent.append(item[0])

        # cur.execute("select * from tmprecord")
        # print(cur.fetchall(), '111111111111111111')
        random.seed()
        otherbtn = random.sample(allstudent, num)[0]
        # self.btngroup.button(int(otherbtn)).setStyleSheet("background-color: red; color:white;")
        # self.btngroup.button(int(otherbtn)).setStyleSheet("border-image: url(image/ex_stu_ok.png);")
        self.btngroup.button(int(otherbtn)).setStyleSheet("border: 6px solid rgb(255,0,0); color:black; font-size:26px;")
        self.btngroup.button(int(otherbtn)).setFocus()

        # print(self.lstchoices, 'choice one another00000000000000001')
        self.lstchoices.remove(curbtn)
        self.lstchoices.append(otherbtn)
        # print(self.lstchoices, 'choice one another000000000000000002')

        # cur.execute("delete from tmprecord where studentsn='" + curbtn + "'") # can not delete ,because this student is ill.
        # conn.commit()
        if tabCombonums.isEnabled():
            today = datetime.date.today()
            cur.execute("insert into tmprecord values (?, ?, ?)", (None, otherbtn, today))
            conn.commit()
        # cur.execute("select * from tmprecord")
        # print(cur.fetchall(), '2222222222222')

        cur.close()

    def answerRight(self, value):
        if value not in self.lstchoices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/smile.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))

        cur = conn.cursor()
        cur.execute("select rightquestions from student where studentsn='" + value + "'")
        studentRightQuestions = cur.fetchall()[0][0] + 1
        cur.execute("update student set rightquestions=" + str(studentRightQuestions) + " where studentsn='" + value + "'")
        conn.commit()
        
        curmenu = self.btngroup.button(int(value)).menu()
        if not curmenu.actions()[1].isEnabled (): # must delete wrongquestionnums
            cur.execute("select wrongquestions from student where studentsn='" + value + "'")
            studentWrongQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set wrongquestions=" + str(studentWrongQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        curmenu.actions()[0].setEnabled(False)
        curmenu.actions()[1].setEnabled(True)
        # curmenu.actions()[2].setEnabled(False)
        
        # cur.execute("select * from student where studentsn='" + value + "'")
        # print(cur.fetchall(), 'right-------')

        cur.close()

    def answerWrong(self, value):
        if value not in self.lstchoices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/cry.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))
        # self.btngroup.button(int(value)).setStyleSheet("border-image: url(image/ex_stu.png);")

        cur = conn.cursor()
        cur.execute("select wrongquestions from student where studentsn='" + value + "'")
        studentWrongQuestions = cur.fetchall()[0][0] + 1
        cur.execute("update student set wrongquestions=" + str(studentWrongQuestions) + " where studentsn='" + value + "'")
        conn.commit()

        curmenu = self.btngroup.button(int(value)).menu()
        if not curmenu.actions()[0].isEnabled (): # must delete wrongquestionnums
            cur.execute("select rightquestions from student where studentsn='" + value + "'")
            studentRightQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set rightquestions=" + str(studentRightQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        curmenu.actions()[0].setEnabled(True)
        curmenu.actions()[1].setEnabled(False)

        # cur.execute("select * from student where studentsn='" + value + "'")
        # print(cur.fetchall(), 'wrong--')

        cur.close()

    def resetStudent(self, value):
        if value not in self.lstchoices:
            return

        # self.btngroup.button(int(value)).setStyleSheet("background-color: rgb(120,220,220);")
        self.btngroup.button(int(value)).setIcon(QIcon())
        self.btngroup.button(int(value)).setStyleSheet("border-image: url(image/ex_stu.png);")
        self.btngroup.button(int(value)).setAutoDefault(False)

        cur = conn.cursor()

        curmenu = self.btngroup.button(int(value)).menu()
        if not curmenu.actions()[0].isEnabled():
            cur.execute("select rightquestions from student where studentsn='" + value + "'")
            studentRightQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set rightquestions=" + str(studentRightQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        if not curmenu.actions()[1].isEnabled():
            cur.execute("select wrongquestions from student where studentsn='" + value + "'")
            studentWrongQuestions = cur.fetchall()[0][0] - 1
            cur.execute("update student set wrongquestions=" + str(studentWrongQuestions) + " where studentsn='" + value + "'")
            conn.commit()
        cur.close()

        curmenu.actions()[0].setEnabled(True)
        curmenu.actions()[1].setEnabled(True)
        self.choiceOneStudent(value)

    def createDb(self):
        cur = conn.cursor()
        sqlstr = 'create table student (id integer primary key, \
            studentsn varchar(20), \
            studentname varchar(20), \
            rightquestions integer, \
            wrongquestions integer)'
        # print(sqlstr)

        sqlstr2 = 'create table tmprecord (id integer primary key, \
            studentsn varchar(20), \
            datequestion date)'

        strdelete = "delete from student where 1=1"
        cur.execute(strdelete)
        conn.commit()
        strdelete = "delete from tmprecord where 1=1"
        cur.execute(strdelete)
        conn.commit()
        # print(sqlstr2)

        # cur.execute(sqlstr) 
        # conn.commit()
        # cur.execute(sqlstr2) 
        # conn.commit()

        # insert example data
        a03lst = ["曾忆谊","赵佳泉","翁文秀","林珑","郑铭洁","林泽思","吴崇霖","陈思嘉","欧阳月孜","郭展羽","詹伟哲","黄佳仪","杨秋霞","周奕子","林楚杰","欧伊涵","许腾誉","陈唯凯","陈树凯","林彦君","张钰佳","高锴","杨博凯","林妙菲","林楚鸿","陈展烯","姚静茵","吴欣桐","范思杰","肖佳","马思广","许一帆","姚奕帆","陈海珣","吴黛莹","吴育桐","肖凯帆","林欣阳","叶茂霖","姚楷臻","陈嘉豪","陈琦","杨子楷","陈炎宏","陈幸仪","杨景畅","罗暖婷","郑馨"]
        a04lst = ["罗恩琪","王可","曾祥威","谢濡婷","温嘉凯","许洁仪","肖欣淇","陈凯佳","林天倩","李乐海","吴文慧","黄文婷","万誉","陈进盛","张裕涵","陈振嘉","王巧玲","林珮琪","陈炜楷","杨健","赵泽锴","张凤临","蔡子丹","陈烨杰","廖妍希","林树超","夏培轩","陈锦森","李星","蔡依婷","姚容创","姚凯扬","沈嘉克","周凡","张玉川","邱金迅","陈菲敏","陈星翰","朱煜楷","郑泽洪","钱剑非","罗奕丰","陈杜炜","林知钦"]
        strsql = "insert into student values (?, ?, ?,?,?)" 
        for i in list(range(0,len(a03lst))):
            cur.execute(strsql, (None, "03"+str(i+1).zfill(2), a03lst[i], 0, 0))
            conn.commit()
        strsql = "insert into student values (?, ?, ?,?,?)" 
        for i in list(range(0,len(a04lst))):
            cur.execute(strsql, (None, "04"+str(i+1).zfill(2), a04lst[i], 0, 0))
            conn.commit()
        cur.close()
예제 #19
0
파일: authent.py 프로젝트: maximerobin/Ufwi
class AuthenticationFrontend(ScrollArea):
    COMPONENT = 'auth_cert'
    LABEL = tr('Authentication server')
    REQUIREMENTS = ('auth_cert',)
    ICON = ':/icons/auth_protocol.png'

    def __init__(self, client, parent):
        self.__loading = True
        ScrollArea.__init__(self)
        self.mainwindow = parent
        self.client = client
        self.modified = False

        self.qauthcertobject = QAuthCertObject.getInstance()

        frame = QFrame(self)

        layout = QVBoxLayout(frame)

        layout.addWidget(QLabel('<H1>%s</H1>' % tr('Authentication server') ))

        head_box = QGroupBox(tr("How the authentication server handles certificates"))
        head = QFormLayout(head_box)
        self.strictCheckBox = QCheckBox()
        head.addRow(QLabel(tr("Strict mode (check the client's certificate against the installed CA)")), self.strictCheckBox)
        self.connect(self.strictCheckBox, SIGNAL('toggled(bool)'),
                     self.setStrict)

        self.cl_auth_box = QGroupBox(tr("Client authentication with a certificate is"))
        cl_auth = QVBoxLayout(self.cl_auth_box)
        self.auth_by_cert = QButtonGroup()
        self.auth_by_cert.setExclusive(True)

        self.mainwindow.writeAccessNeeded(self.strictCheckBox)

        labels = [tr('forbidden'), tr('allowed'), tr('mandatory')]
        for index, label_button in enumerate(labels):
            button = QRadioButton(label_button)
            self.auth_by_cert.addButton(button, index)
            cl_auth.addWidget(button)
            self.mainwindow.writeAccessNeeded(button)
        self.auth_by_cert.button(0).setChecked(Qt.Checked)
        self.connect(self.auth_by_cert, SIGNAL('buttonClicked(int)'),
                     self.auth_by_cert_modified)


        # Captive portal
        # --------------
        self.portal_groupbox = QGroupBox(tr("Captive portal"))
        self.portal_groupbox.setLayout(QVBoxLayout())

        # Enabled checkbox:
        self.portal_checkbox = QCheckBox(tr("Enable captive portal"))
        self.connect(self.portal_checkbox, SIGNAL('toggled(bool)'),
                     self.setPortalEnabled)

        # List of networks redirected to the captive portal:
        self.portal_nets_groupbox = QGroupBox(
            tr("Networks handled by the captive portal"))
        self.portal_nets_groupbox.setLayout(QVBoxLayout())
        self.portal_nets_edit = NetworkListEdit()
        self.connect(self.portal_nets_edit, SIGNAL('textChanged()'), self.setPortalNets)
        self.portal_nets_groupbox.layout().addWidget(self.portal_nets_edit)

        # Pack the widgets:
        for widget in (self.portal_checkbox, self.portal_nets_groupbox):
            self.portal_groupbox.layout().addWidget(widget)
        self.mainwindow.writeAccessNeeded(self.portal_checkbox)
        self.mainwindow.writeAccessNeeded(self.portal_nets_edit)

        if not EDENWALL:
            self.portal_groupbox.setVisible(False)


        # authentication server
        self.pki_widget = PkiEmbedWidget(self.client, self, 'auth_cert', PkiEmbedWidget.SHOW_ALL|PkiEmbedWidget.CRL_OPTIONAL, self.setModified)
        self.mainwindow.writeAccessNeeded(self.pki_widget)

        layout.addWidget(head_box)
        layout.addWidget(self.cl_auth_box)
        layout.addWidget(self.portal_groupbox)
        layout.addWidget(self.pki_widget)
        layout.addStretch()
        self.setWidget(frame)
        self.setWidgetResizable(True)

        self.resetConf()
        self.__loading = False

    def setModified(self, isModified=True, message=""):
        if self.__loading:
            return
        if isModified:
            self.modified = True
            self.mainwindow.setModified(self, True)
            if message:
                self.mainwindow.addToInfoArea(message)
        else:
            self.modified = False

    def setModifiedCallback(self, *unused):
        self.setModified()

    def isModified(self):
        return self.modified

    def saveConf(self, message):
        self.qauthcertobject.auth_cert.auth_by_cert = self.auth_by_cert.checkedId()

        conf = self.pki_widget.getConfig()
        self.qauthcertobject.auth_cert.setSSLDict(conf)

        serialized = self.qauthcertobject.auth_cert.serialize(downgrade=True)
        self.client.call('auth_cert', 'setAuthCertConfig', serialized, message)

    def resetConf(self):
        auth_cert_loaded = self._reset_helper(
            'auth_cert',
            'getAuthCertConfig',
            self.qauthcertobject,
            tr("Authentication interface enabled"),
            tr("Authentication disabled: backend not loaded")
        )
        self.setModified(False)

        remote = self.qauthcertobject.auth_cert.getReceivedSerialVersion()
        if remote < 3:
            self.mainwindow.addWarningMessage(tr('Captive portal configuration disabled: this frontend and your appliance software versions are not compatible.'))
        enable_portal = (
            auth_cert_loaded
            and EDENWALL
            and remote >= 3
            )
        self.portal_groupbox.setVisible(enable_portal)

        if not auth_cert_loaded:
            return


        self.strictCheckBox.setChecked(self.qauthcertobject.auth_cert.strict)
        if not self.qauthcertobject.auth_cert.auth_by_cert:
            self.qauthcertobject.auth_cert.auth_by_cert = 0
        self.auth_by_cert.button(
            self.qauthcertobject.auth_cert.auth_by_cert).setChecked(True)

        # Captive portal:
        self.portal_checkbox.setChecked(
            self.qauthcertobject.auth_cert.portal_enabled)
        self.portal_nets_edit.setIpAddrs(
            self.qauthcertobject.auth_cert.portal_nets)

        # Certificate (PKI):
        pki_conf = self.qauthcertobject.auth_cert.getSSLDict()
        self.pki_widget.setConfig(pki_conf)

    def error(self, message):
        self.mainwindow.addToInfoArea(message, category=COLOR_ERROR)

    def auth_by_cert_modified(self, idbox):
        button_name = self.auth_by_cert.button(idbox).text()
        info = tr("Certificates - Authentication with client certificate : '%s'") % button_name
        self.setModified(message=info)

    def setPortalEnabled(self, value):
        if value != self.qauthcertobject.auth_cert.portal_enabled:
            self.qauthcertobject.auth_cert.setPortalEnabled(value)
            self.setModified()

    def setPortalNets(self):
        if self.portal_nets_edit.isValid():
            self.qauthcertobject.auth_cert.setPortalNets(
                self.portal_nets_edit.value())
            self.setModified()

    def setStrict(self, value):
        if value != self.qauthcertobject.auth_cert.strict:
            self.qauthcertobject.auth_cert.setStrict(value)
            self.setModified()
        self.cl_auth_box.setEnabled(value)

    def isValid(self):
        cert_validity = self.pki_widget.validate()
        if cert_validity is not None:
            self.error_message = '<br/>' + cert_validity + '<br/>'
            self.mainwindow.addToInfoArea(cert_validity, category=COLOR_ERROR)
            return False
        return True

    def onApplyFinished(self):
        self.pki_widget.feed()