class Window(QMainWindow):
    '''Main Window'''
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setWindowTitle('RP Contacts')
        self.resize(1200, 500)
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.layout = QHBoxLayout()
        self.centralWidget.setLayout(self.layout)
        self.contactsModel = ContactsModel()
        self.setupUI()

    def setupUI(self):
        '''Setup the main window GUI.'''
        # Create table view widget
        self.table = QTableView()
        self.table.setModel(self.contactsModel.model)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.resizeColumnsToContents()
        # Create buttons
        self.addButton = QPushButton('Add...')
        self.addButton.clicked.connect(self.openAddDialog)
        self.deleteButton = QPushButton('Delete')
        self.deleteButton.clicked.connect(self.deleteContact)
        self.clearAllButton = QPushButton('Clear All')
        self.clearAllButton.clicked.connect(self.clearContacts)
        # Layout the GUI
        layout = QVBoxLayout()
        layout.addWidget(self.addButton)
        layout.addWidget(self.deleteButton)
        layout.addStretch()
        layout.addWidget(self.clearAllButton)
        self.layout.addWidget(self.table)
        self.layout.addLayout(layout)

    def openAddDialog(self):
        ''' Open Add Contact dialog '''
        dialog = AddDialog(self)
        if dialog.exec() == QDialog.Accepted:
            self.contactsModel.addContact(dialog.data)
            self.table.resizeColumnsToContents()

    def deleteContact(self):
        ''' Delete selected contact from database'''
        row = self.table.currentIndex().row()
        if row < 0:
            return
        messageBox = QMessageBox.warning(
            self, 'Warning!', 'Do you want to remove the selected contact?',
            QMessageBox.Ok | QMessageBox.Cancel)
        if messageBox == QMessageBox.Ok:
            self.contactsModel.deleteContact(row)

    def clearContacts(self):
        messageBox = QMessageBox.warning(self, 'Warning!',
                                         'Do you wat to remove all contacts?',
                                         QMessageBox.Ok | QMessageBox.Cancel)
        if messageBox == QMessageBox.Ok:
            self.contactsModel.clearContacts()
Exemple #2
0
 def excel_like_enter_filter(source: QtWidgets.QTableView,
                             event: QtCore.QEvent):
     if event.type() == event.KeyPress:
         if event.key() in [QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter]:
             if int(source.editTriggers()) > int(
                     QtWidgets.QAbstractItemView.NoEditTriggers):
                 next_row = source.currentIndex().row() + 1
                 if next_row + 1 > source.model().rowCount():
                     next_row -= 1
                 if source.state() == source.EditingState:
                     next_index = source.model().index(
                         next_row,
                         source.currentIndex().column())
                     source.setCurrentIndex(next_index)
                 else:
                     source.edit(source.currentIndex())
Exemple #3
0
class TextTable(QComboBox):

    view = None
    model = None

    index_str_map =[
        [
        '<p style="font-size: 20px;"></p>',
        '<inc>[](hl_lines="")',
        '<att>()',
        '<img src="" alt="" style="width:100px; height:200px;">'
        ]
    ]

    table = [["<p>", "<inc>", "<att>", "<img>"]]

    insert = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent=parent)


        self.model = TableModel(self.table, parent=self)
        self.view = QTableView()

        self.view.setMinimumSize(300, 30)
        self.view.setMaximumSize(300, 30)


        self.view.setShowGrid(False)

        self.view.verticalHeader().setVisible(False)
        self.view.horizontalHeader().setVisible(False)

        self.view.horizontalHeader().setSectionResizeMode(1)
        self.view.verticalHeader().setSectionResizeMode(1)
        #self.view.setMaximumWidth(200)
        self.view.setStyleSheet("font-size: 15px;")

        self.setStyleSheet('''* {font-size: 23px; border: 0px; padding: 0px; background-color: rgba(255,255,255,0);} 
                                *::down-arrow {image: url(noimg); border-width: 0px;}
                                *::drop-down {border: none; width: 0px;}
                                }''')

        self.setModel(self.model)
        self.setView(self.view)

        self.activated.connect(self.set_col)

    def set_col(self, index):

        index2 = self.view.currentIndex()

        if not index2.isValid():
            return

        self.insert.emit(self.index_str_map[index][index2.column()])
Exemple #4
0
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(650, 300)

        self.model = QStandardItemModel(6, 6, self)            # 1
        # self.model = QStandardItemModel(self)
        # self.model.setColumnCount(6)
        # self.model.setRowCount(6)

        for row in range(6):                                   # 2
            for column in range(6):
                item = QStandardItem('({}, {})'.format(row, column))
                self.model.setItem(row, column, item)

        self.item_list = [QStandardItem(
            '(6, {})'.format(column)) for column in range(6)]
        self.model.appendRow(self.item_list)                   # 3

        self.item_list = [QStandardItem(
            '(7, {})'.format(column)) for column in range(6)]
        self.model.insertRow(7, self.item_list)                # 4

        self.table = QTableView(self)                          # 5
        self.table.setModel(self.model)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.clicked.connect(self.show_info)

        self.info_label = QLabel(self)                         # 6
        self.info_label.setAlignment(Qt.AlignCenter)

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.table)
        self.v_layout.addWidget(self.info_label)
        self.setLayout(self.v_layout)

    def show_info(self):                                       # 7
        row = self.table.currentIndex().row()
        column = self.table.currentIndex().column()
        print('({}, {})'.format(row, column))

        data = self.table.currentIndex().data()
        self.info_label.setText(data)
class ViewTable:
    """
    Интерфейс таблицы со спецификацией
    """
    def __init__(self, main: QMainWindow, df: pd.DataFrame):
        self._main = main
        self._df = df

        self._grid_layout = QGridLayout()
        central_widget = QWidget(self._main)
        self._main.setCentralWidget(central_widget)
        central_widget.setLayout(self._grid_layout)

        self._table = QTableView()

    def create_table(self):
        """
        Создание таблицы со спецификацией на интерфейсе
        """
        model = TableModel(self._df)
        self._table.setModel(model)
        header = self._table.horizontalHeader()
        header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
        self._table.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self._table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # pylint: disable=no-member
        self._table.setHorizontalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        self._table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self._table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self._table.setSelectionMode(QAbstractItemView.SingleSelection)
        self._grid_layout.addWidget(self._table, 2, 0)

    def create_buttons(self):
        """
        Создание кнопок на интерфейсе
        """
        single_check_button = QPushButton("Поиск ближайшего требования")
        full_check_button = QPushButton("Полная проверка требований")
        single_check_button.setEnabled(False)
        self._table.selectionModel().selectionChanged.connect(
            lambda: single_check_button.setEnabled(True))
        full_check_button.clicked.connect(
            lambda: single_check_button.setEnabled(True))
        self._grid_layout.addWidget(single_check_button, 0, 0)
        self._grid_layout.addWidget(full_check_button, 1, 0)
        single_check_button.clicked.connect(
            self._main.single_check_chosen_slot)
        full_check_button.clicked.connect(self._main.full_check_chosen_slot)

    def get_current(self) -> str:
        """
        :return: ID выбранного требования
        """
        return self._table.model().index(self._table.currentIndex().row(),
                                         0).data()
Exemple #6
0
class SetsScreen(QDialog):
    def __init__(self):
        super(SetsScreen, self).__init__()
        self.setWindowTitle("Sets")

        cursor = connection.cursor()
        cursor.execute("SELECT * FROM sets limit 50;")
        data = cursor.fetchall()
        self.table_model = SimpleTableModel(data)
        self.table_view = QTableView()
        self.table_view.setModel(self.table_model)
        self.table_view.setSelectionMode(QAbstractItemView.SelectRows
                                         | QAbstractItemView.SingleSelection)

        self.show_item_button = QPushButton("Detail")
        self.show_item_button.clicked.connect(self.show_item)
        self.show_item_button.setEnabled(False)
        self.table_view.clicked.connect(self.enable_show_item_button)

        vbox = QVBoxLayout()
        self.back_button = QPushButton("Back")
        self.back_button.clicked.connect(self.NavWin)
        vbox.addWidget(self.table_view)
        vbox.addWidget(self.show_item_button)
        vbox.addWidget(self.back_button)
        self.setLayout(vbox)

    def NavWin(self):
        self.hide()
        self.set = NavigationWindow()
        self.set.show()

    def show_item(self):
        current_index = self.table_view.currentIndex().row()
        selected_item = self.table_model.row(current_index)
        SetDetailDialog(selected_item).exec()

    def enable_show_item_button(self):
        if self.table_view.currentIndex() == -1:
            self.show_item_button.setEnabled(False)
        else:
            self.show_item_button.setEnabled(True)
Exemple #7
0
def getRow(table_view: QTableView):
    """получение строки из таблицы"""
    try:
        m_index = table_view.currentIndex()
        m_index = m_index.sibling(m_index.row(), m_index.column())
        items = m_index.data(Qt.UserRole)
        return items
    except AttributeError as error:
        logger.error(f"error: {str(error)}")
        return None
    except TypeError as error:
        logger.error(f"error: {str(error)}")
        return None
Exemple #8
0
class MyUi(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi()
        self.show()

    def setupUi(self):
        self.wdgt = QTableView()

        self.model = QStandardItemModel(4, 3)
        for r in range(4):
            for c in range(3):
                it = QStandardItem('a {},c {}'.format(r, c))
                if c == 0:
                    it.setEditable(False)
                self.model.setItem(r, c, it)
        self.wdgt.setModel(self.model)

        self.model.itemChanged.connect(self.pr)
        self.wdgt.setStyleSheet('QWidget{background-color:rgb(255,255,255)}')
        self.wdgt.setMinimumSize(1500, 800)

        # self.wdgt.setColumnHidden(0,True)
        scroll = QScrollArea(self)
        scroll.setWidget(self.wdgt)
        self.setCentralWidget(scroll)

    def pr(self):
        print('jjkkk')

        print(self.wdgt.currentIndex().row(),
              self.wdgt.currentIndex().column(),
              self.wdgt.currentIndex().data())
        r = self.wdgt.currentIndex().row()
        c = self.wdgt.currentIndex().column()
        item = self.model.index(r, 0)
        print(item.data())
Exemple #9
0
class UiUserListFrame(QFrame):
    # 用户列表右键菜单事件信号
    sign_userlist_to_menu = pyqtSignal(str, int)

    def __init__(self, parent):
        super(UiUserListFrame, self).__init__(parent)
        self.setupUi()

    def setupUi(self):
        # 用户列表框架
        self.setGeometry(QRect(710, 130, 301, 231))
        self.setFrameShape(QFrame.Box)
        self.setFrameShadow(QFrame.Sunken)
        self.setLineWidth(2)
        self.setObjectName("uiUserListFrame")

        # 用户列表
        self.tableView = QTableView(self)
        self.tableView.setGeometry(QRect(10, 10, 281, 212))
        self.tableView.setObjectName("tableView")
        # self.tableView.setContextMenuPolicy(3)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tableView.customContextMenuRequested[QPoint].connect(
            self.generateMenu)

    def generateMenu(self, pos):
        menu = QMenu()
        item1 = menu.addAction(u"查看信息")
        item2 = menu.addAction(u"发送消息")
        item3 = menu.addAction(u"发起对战")
        action = menu.exec_(self.tableView.mapToGlobal(pos))
        row_num = self.tableView.currentIndex().row()
        print(row_num)
        # text = self.tableView.indexAt(QPoint(row_num, 0)).data()
        if action == item1:
            self.sign_userlist_to_menu.emit('show', row_num)
            # print('查看信息', )
        elif action == item2:
            self.sign_userlist_to_menu.emit('message', row_num)
            # print('发送消息', self.tableView.indexAt(QPoint(row_num, 0)).data())
        elif action == item3:
            # print('发起对战', self.tableView.indexAt(QPoint(row_num, 0)).data())
            self.sign_userlist_to_menu.emit('fight', row_num)
        else:
            return
Exemple #10
0
class Regions(QWidget):
    def __init__(self, model: RegionsModel, parent=None):
        super(Regions, self).__init__(parent)

        self.model = model

        vbox = QVBoxLayout(self)
        self.setLayout(vbox)

        hbox = QHBoxLayout()
        hbox.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        vbox.addLayout(hbox)

        self.add = QPushButton()
        self.add.setIcon(QIcon(icon('plus.png')))
        self.add.setToolTip('Add region')
        self.add.clicked.connect(self.addRegion)
        hbox.addWidget(self.add)

        self.remove = QPushButton()
        self.remove.setIcon(QIcon(icon('minus.png')))
        self.remove.setToolTip('Remove selected region')
        self.remove.setEnabled(False)
        self.remove.clicked.connect(self.removeRegion)
        hbox.addWidget(self.remove)

        self.view = QTableView()
        self.view.setModel(model)
        self.view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        vbox.addWidget(self.view)

        self.view.setItemDelegateForColumn(
            RegionsModel.attr.index(Headers.NAME), Name(self.view))
        self.view.setItemDelegateForColumn(
            RegionsModel.attr.index(Headers.REFINEMENT), Integer(self.view))

    def addRegion(self):
        self.model.insertRow(self.model.rowCount())
        self.view.selectRow(self.model.rowCount() - 1)
        self.remove.setEnabled(True)

    def removeRegion(self):
        row = self.view.currentIndex().row()
        self.model.removeRow(row)
        if self.model.rowCount() == 0:
            self.remove.setEnabled(False)
Exemple #11
0
class Demo(QWidget):

    def __init__(self, parent: typing.Optional[QWidget] = None) -> None:
        super().__init__(parent)

        db = QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName('student.db')
        db.open()
        # 创建view
        self.view = QTableView()
        # 将模型与数据库绑定
        self.model = QSqlTableModel(None, db)
        # 设置模型对应数据库中的student表
        self.model.setTable('student')
        # 获取数据
        self.model.select()
        # 修改表格头
        self.model.setHeaderData(0, Qt.Horizontal, '姓名')
        self.model.setHeaderData(1, Qt.Horizontal, '手机号')
        self.model.setHeaderData(2, Qt.Horizontal, '地址')
        self.view.setModel(self.model)

        vbox = QVBoxLayout()
        vbox.addWidget(self.view)

        self.btn_add = QPushButton("添加")
        self.btn_add.clicked.connect(self.slot_add)
        self.btn_del = QPushButton("删除")
        self.btn_del.clicked.connect(self.slot_del)

        vbox.addWidget(self.btn_add)
        vbox.addWidget(self.btn_del)

        self.setLayout(vbox)

    def slot_add(self):
        print(11)
        self.model.insertRows(self.model.rowCount(), 1)

    def slot_del(self):
        print(22)
        self.model.removeRow(self.view.currentIndex().row())
class Demo_TabelView(QWidget):
    def __init__(self):
        super(Demo_TabelView, self).__init__()
        self.initUI()
        self.initLayout()

    def initUI(self):
        # 表格视图控件
        self.view = QTableView()
        # 使用QStandardItemModel(row,col)
        self.model = QStandardItemModel(4, 3)
        self.model.setHorizontalHeaderLabels(["列1", "列2", "列3"])

        self.model.setItem(0, 0, QStandardItem("1"))
        self.model.setItem(1, 0, QStandardItem("2"))
        self.model.setItem(2, 0, QStandardItem("3"))

        self.view.setModel(self.model)

        # 设置表格头部占满窗体
        self.view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 设置是否可编辑
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)

        # 设置选中方式
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)

        # 获取点击处于哪一行
        self.view.clicked.connect(self.test)

    def initLayout(self):
        contentLayout = QVBoxLayout()
        contentLayout.addWidget(self.view)

        self.setLayout(contentLayout)

    def test(self):
        print(self.view.currentIndex().row())
class Table(QWidget):
    def __init__(self):
        super(Table, self).__init__()
        self.setWindowTitle('TableView示例')
        self.resize(600, 600)
        self.model = QStandardItemModel(4, 4)
        '''
        QStandardItemModel:'Q标准化模型'类提供了一个用于存储定制数据的通用模型。 
        'Q标准化模型'可以作为标准Qt数据类型的存储库。
        它是模型/视图类之一,也是Qt模型/视图框架的一部分。 
        'Q标准化模型'提供了一种经典的基于项目的方法来处理模型。
        'Q标准化模型'提供了Q标准化模型中的项目。 
        'Q标准化模型'实现了QAbstractItemModel接口,这意味着该模型可以用于提供支持该接口
        的任何视图中的数据(如QListView、QTableView和QTreeView,以及自定义的类型)。

        当您需要一个列表或树时,通常会创建一个空的'q标准化模型',
        并使用appendRow()将项目添加到模型中,并使用item()来访问项目。
        如果您的模型代表一个表,那么您通常将表的维度传递给'q标准化模型'构造函数,
        并使用setItem()将条目放置到表中。您还可以使用setRowCount()和setColumnCount()来改变模型的维度。
        要插入项,请使用insertRow()或insertColumn(),并删除项目,使用removeRow()或removeColumn()。
        '''
        tableTittleList = ['行数', '针数', '次数', '收针']
        self.model.setHorizontalHeaderLabels(tableTittleList)
        dataList = [
            '5', '7', 'dd', '90', '34', '', '1', '33', '45', '31', '34', '12',
            '89', '12', '1', '513'
        ]

        for [n, (i, j)] in enumerate([(i, j) for i in range(4)
                                      for j in range(4)]):
            item = QStandardItem(dataList[n])
            self.model.setItem(i, j, item)

        self.tabletView = QTableView()
        self.tabletView.setModel(self.model)
        # 设置tableView的最后一列会跟随窗口水平伸缩
        self.tabletView.horizontalHeader().setStretchLastSection(True)
        # 设置tableView的所有列都会跟谁窗口伸缩
        self.tabletView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)

        self.stateLabel = QLabel('Size:(0x0),Mouse:(0,0)')
        self.setStateLabel()

        self.tabletView.clicked.connect(self.setStateLabel)

        # 添加一些按钮:删除行,插入行,清空行,
        delBtn = QPushButton('删除')
        insertRowBtn = QPushButton('插入')
        clrBtn = QPushButton('清除')

        # 添加2个lineEdit和一个btn 用来查询用户指定的位置的数据
        rowLine = QLineEdit()
        colLine = QLineEdit()
        findBtn = QPushButton('查询')
        # 创建一个整数验证器,用来限制输入的数据为0~300的整数
        intValidator = QIntValidator()
        intValidator.setRange(0, 300)
        # 添加信号槽
        rowLine.setValidator(intValidator)
        colLine.setValidator(intValidator)
        rowLine.setPlaceholderText('输入查询的行数')
        colLine.setPlaceholderText('输入要查询的列数')
        findBtn.clicked.connect(
            lambda: self.findData(int(rowLine.text()), int(colLine.text())))

        # 为按钮添加信号槽
        delBtn.clicked.connect(self.removeRow)
        insertRowBtn.clicked.connect(self.insertRow)
        clrBtn.clicked.connect(self.clearSelectedItem)

        btnGridLayout = QGridLayout()
        btnGridLayout.addWidget(delBtn, 0, 0)
        btnGridLayout.addWidget(insertRowBtn, 0, 1)
        btnGridLayout.addWidget(clrBtn, 0, 2)
        btnGridLayout.addWidget(rowLine, 1, 0)
        btnGridLayout.addWidget(colLine, 1, 1)
        btnGridLayout.addWidget(findBtn, 1, 2)

        # 创建查询框和查询按钮
        searchLine = QLineEdit()
        columnNumLine = QLineEdit()
        searchBtn = QPushButton('搜索')
        columnNumLine.setValidator(intValidator)
        # 为搜索按钮添加槽
        searchBtn.clicked.connect(
            lambda: self.searchData(searchLine.text(), columnNumLine.text()))

        btnGridLayout.addWidget(searchLine, 2, 0)
        btnGridLayout.addWidget(columnNumLine, 2, 1)
        btnGridLayout.addWidget(searchBtn, 2, 2)

        layout = QVBoxLayout()
        layout.addWidget(self.tabletView)
        layout.addLayout(btnGridLayout)
        layout.addWidget(self.stateLabel)
        self.setLayout(layout)

    def setStateLabel(self, p_arg):
        print(p_arg)
        '''获取当前tableView的大小和鼠标点击的位置,以及选择和框选区大小'''
        selectedIndexes = self.tabletView.selectedIndexes()

        stateList = [
            self.model.rowCount(),
            self.model.columnCount(),
            self.tabletView.currentIndex().row(),
            self.tabletView.currentIndex().column()
        ]
        self.stateLabel.setText(
            'Size:(%dx%d),Mouse:(%d,%d)' %
            (stateList[0], stateList[1], stateList[2] + 1, stateList[3] + 1))
        print(stateList)

    def insertRow(self):
        if self.model.rowCount() < 300:
            if self.model.rowCount() == 0:
                self.model.setItem(0, QStandardItem(''))
            else:
                self.model.insertRow(self.tabletView.currentIndex().row())
            print('rowCount = ', self.model.rowCount())
        else:
            QMessageBox.warning(self, '停止', '最大支持300行数据!')

        self.setStateLabel()

    def removeRow(self):
        indexes = self.tabletView.selectedIndexes()
        rowIndexList = []
        for index in indexes:
            rowIndexList.append(index.row())
        rowIndexSet = set(rowIndexList)
        print(len(indexes), len(rowIndexList), len(rowIndexSet))
        self.model.removeRows(self.tabletView.currentIndex().row(),
                              len(rowIndexSet))
        self.setStateLabel()

    def findData(self, n_row, n_col):
        print('开始查询第{0}行,第{1}列的数据...'.format(n_row, n_col))
        index = self.model.index(n_row - 1, n_col - 1)
        # 检查输入的数据是否超出表格范围,并检查表格内容是否为空
        if (n_row - 1) > self.model.rowCount():
            QMessageBox.critical(self, '错误', '输入的行数超过表格最大行数')
        elif (n_col - 1) > self.model.columnCount():
            QMessageBox.critical(self, '错误', '输入的列数超过表格最大列数')
        else:
            data = self.model.data(index)
            if data:
                QMessageBox.information(
                    self, '查询',
                    '({0},{1})位置处的数值是{2}'.format(n_row, n_col, data))
            else:
                QMessageBox.information(
                    self, '查询',
                    '({0},{1})位置处的数值是{2}'.format(n_row, n_col, '空的'))

    def searchData(self, data, column_num):
        # 用来在指定的column_num列找那个查找有没有data的item
        # 如果找到,返回其行数, 如果找不到,告知找不到
        column_num = int(column_num)

        dataItem = QStandardItem(data)
        indexList = self.model.findItems(data, column=column_num - 1)
        list = []
        for i in range(len(indexList)):
            list.append(indexList[i].row())
        if len(list) == 0:
            QMessageBox.information(
                self, '找不到', '在第{0}列中找不到\n任何值是{1}元素'.format(column_num, data))
        else:
            for i in range(len(list)):
                list[i] = list[i] + 1
            dlgText = """在第{0}列中找到了值是'{1}'的元素共<font color = red>{2}</font>个,分别在第{3}列""".format(
                column_num, data, len(list), list)
            QMessageBox.information(self, '找到了', dlgText)

    def clearSelectedItem(self):
        indexes = self.tabletView.selectedIndexes()
        for index in indexes:
            self.model.setItem(index.row(), index.column(), QStandardItem(''))
Exemple #14
0
class NarzPoz(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.pozycja = 'Brak'
        self.proxy = QSortFilterProxyModel(self)
        self.proxy_poz = QSortFilterProxyModel(self)
        self.edit_wysz = QLineEdit(self)
        self.combo_typ = QComboBox(self)
        self.lbl_wysz = QLabel("Wyszukaj")
        self.lbl_typ = QLabel("Wybierz typ narzędzia:")
        self.combo_poz = QComboBox(self)
        self.lbl_poz = QLabel("Wybierz pozycję:")
        self.listaPozycji = []
        self.table = QTableView(self)
        self.table_narz = QTableView(self)
        sciezka = czy_istnieje()
        db = QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName(sciezka)
        if db.open():
            print('Otworzono bazę danych')
        self.model = QSqlTableModel(self, db)
        self.model_poz = QSqlTableModel(self, db)

        self.parent = parent
        self.formularz = QGroupBox("Przypisz narzędzia")
        self.initUI()

    def initUI(self):
        self.naglowki_kolumn()

        # todo dodać okno z wyborem oprawki po wyborze narzędzia
        typy_narzedzi = [
            'Brak',
            'Frez palcowy',
            'Frez płytkowy (głowica)',
            'Gwintownik',
            'Nóż tokarski',
            # 'Oprawka',
            'Piła',
            'Pozostałe',
            'Rozwiertak',
            'Wiertło',
            'Wiertło składane',
            'Wygniatak'
        ]

        self.widok()
        # Zatwierdzenie
        ok_button = QPushButton("Dodaj do pozycji")
        cancel_button = QPushButton("Cofnij")
        wydrukuj_btn = QPushButton("Wyeksportuj")
        usun_btn = QPushButton("Usuń pozycję")
        dodaj_btn = QPushButton("Dodaj pozycję")
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(ok_button)
        hbox.addWidget(cancel_button)

        # Layouty
        layout_v = QVBoxLayout()
        l_1 = QHBoxLayout()
        l_2 = QHBoxLayout()
        l_3 = QHBoxLayout()
        layout_h = QHBoxLayout()

        # Funkcje
        self.combo_typ.addItems(typy_narzedzi)
        self.combo_poz.addItems(self.listaPozycji)
        self.proxy_poz.setSourceModel(self.model_poz)
        self.table.setModel(self.proxy_poz)
        self.proxy.setSourceModel(self.model)
        self.table_narz.setModel(self.proxy)

        # Przyporzadkowanie
        l_1.addWidget(self.lbl_typ)
        l_1.addWidget(self.combo_typ)
        l_2.addWidget(self.lbl_wysz)
        l_2.addWidget(self.edit_wysz)
        l_3.addWidget(wydrukuj_btn)
        l_3.addWidget(usun_btn)
        l_3.addWidget(dodaj_btn)
        layout_h.addWidget(self.lbl_poz)
        layout_h.addWidget(self.combo_poz)
        layout_v.addLayout(layout_h, 1)
        layout_v.addLayout(l_1)
        layout_v.addLayout(l_2)
        layout_v.addLayout(l_3)
        layout_v.addWidget(self.table)
        layout_v.addWidget(self.table_narz)
        self.formularz.setLayout(layout_v)
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.formularz)
        main_layout.addLayout(hbox)
        self.setLayout(main_layout)

        # connecty
        # ok_button.clicked.connect(self.dodaj)
        cancel_button.clicked.connect(self.anulowanie)
        dodaj_btn.clicked.connect(self.dodaj_poz)
        ok_button.clicked.connect(self.klikniecie)
        usun_btn.clicked.connect(self.usun_pozycje)
        wydrukuj_btn.clicked.connect(self.wydrukuj)
        self.edit_wysz.textChanged.connect(self.wyszukiwanie)
        self.combo_typ.activated[str].connect(self.onActiveNarz)
        self.combo_poz.activated[str].connect(self.onActivePoz)
        # Menu kontekstowe własne
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.prawoklik)

    def wydrukuj(self):
        poz_lista = [
            'Wykaz narzędzi ' + self.pozycja,
            "SELECT * FROM '" + self.pozycja + "'",
            'Baza nie zawiera żadnych pozycji. Plik nie zostanie zapisany.',
        ]
        from gui import Window
        if self.pozycja != 'Brak':
            Window.export(self, poz_lista)
            self.parent.statusBar().showMessage("Wyeksportowano do pliku",
                                                10000)
        else:
            QMessageBox.critical(self, 'Wybierz pozycję',
                                 'Nie wybrano żadnej pozycji!', QMessageBox.Ok,
                                 QMessageBox.Ok)

    def naglowki_kolumn(self):
        # Nagłówki kolumn
        self.listaPozycji.append('Brak')
        for i in naglowki():
            if "/" in i[0]:
                self.listaPozycji.append(i[0])

    def usun_pozycje(self):
        text, ok = QInputDialog.getItem(self,
                                        'Usuń pozycje',
                                        'Wybierz pozycję do usunięcia',
                                        self.listaPozycji[1:],
                                        editable=False)
        if ok:
            if text != 'Brak':
                print(text)
                query = 'DROP TABLE "main"."' + text + '";'
                polaczenie(query)
                self.listaPozycji.clear()
                self.naglowki_kolumn()
                indeks = self.combo_poz.findText(text)
                self.combo_poz.removeItem(indeks)
                self.parent.statusBar().showMessage("Usunięto pozycję", 10000)
            else:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Warning)
                msg.setWindowIcon(QIcon('icons/cow.png'))
                msg.setText("Wybierz poprawną pozycję")
                msg.setWindowTitle("Niewłaściwa pozycja")
                msg.exec_()
                self.usun_pozycje()

    def prawoklik(self):
        menu = QMenu(self)
        akcja = QAction('Usuń narzędzie', self)
        akcja.triggered.connect(self.usun_wiersz)
        menu.addAction(akcja)
        menu.exec_(QCursor.pos())

    def usun_wiersz(self):
        selected = self.table.currentIndex()
        self.model_poz.removeRow(selected.row())
        self.model_poz.submitAll()
        self.model_poz.select()
        self.parent.statusBar().showMessage("Usunięto narzędzie", 10000)

    def dodaj_poz(self):
        text, ok = QInputDialog.getText(self, 'Wprowadź pozycje', 'Pozycja:')
        if ok and text:
            query = 'CREATE TABLE IF NOT EXISTS "' + text + '" ("id_poz" INTEGER PRIMARY ' \
                                              'KEY AUTOINCREMENT, ' \
                                              '"symbol_narz"	TEXT, ' \
                                              '"vc" INTEGER,	"obroty" ' \
                                              'INTEGER, "fz" REAL, "posuw" ' \
                                              'INTEGER); '
            print(query)
            polaczenie(query)
            self.listaPozycji.clear()
            self.combo_poz.addItem(text)
            self.naglowki_kolumn()
            self.parent.statusBar().showMessage("Dodano pozycję " + text,
                                                10000)
        else:
            print("Nie wpisano pozycji")

    def onActivePoz(self, tekst):
        self.pozycja = tekst
        naglowki = {
            'id_poz': 'ID',
            'symbol_narz': 'Symbol narzędzia',
            'vc': 'Prędkość skrawania Vc [m/min]',
            'obroty': 'Obroty n [obr/min]',
            'fz': 'Posuw na ząb fz [mm/ostrze]',
            'posuw': 'Posuw liniowy f [mm/min]'
        }
        self.model_poz.setTable(tekst)
        self.model_poz.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model_poz.select()

        # Ustawianie nagłówków
        ilosc_kolumn = self.model_poz.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model_poz.headerData(i, Qt.Horizontal)
            self.model_poz.setHeaderData(i, Qt.Horizontal,
                                         naglowki[nazwa_kolumn])

    def onActiveNarz(self, tekst):
        slownik = {
            'Frez palcowy': 'frezy_palcowe',
            'Frez płytkowy (głowica)': 'frezy_plytkowe',
            'Gwintownik': 'gwintowniki',
            'Nóż tokarski': 'noze_tokarskie',
            'Oprawka': 'oprawki',
            'Piła': 'pily',
            'Pozostałe': 'pozostale',
            'Rozwiertak': 'rozwiertaki',
            'Wiertło': 'wiertla',
            'Wiertło składane': 'wiertla_skladane',
            'Wygniatak': 'wygniataki',
            'Brak': ''
        }
        naglowki = {
            'idfrezy_palcowe': 'ID',
            'symbol_freza': 'Symbol',
            'producent_fr': 'Producent',
            'srednica_fr': 'Średnica',
            'dl_fr': 'Długość całkowita',
            'dl_rob_fr': 'Długość robocza',
            'idfrezy_plytkowe': 'ID',
            'symbol_frez_pl': 'Symbol',
            'producent_fp': 'Producent',
            'srednica_fr_pl': 'Średnica',
            'ilosc_plytek': 'Ilość płytek',
            'symbol_pl': 'Symbol płytek',
            'ilosc_krawedzi_pl': 'Ilość krawędzi płytki',
            'idgwintowniki': 'ID',
            'symbol_g': 'Symbol',
            'producent_gw': 'Producent',
            'rozmiar_gwintu': 'Rozmiar gwintu i skok',
            'typ_gwintownika': 'Typ gwintownika',
            'idnoze_tokarskie': 'ID',
            'symbol_n': 'Symbol',
            'producent_n': 'Producent',
            'plytki_n': 'Symbol płytek',
            'ilosc_krawedzi_pl_n': 'Ilość krawędzi',
            'idpily': 'ID',
            'symbol_p': 'Symbol',
            'producent_pil': 'Producent',
            'srednica_p': 'Średnica',
            'grubosc_p': 'Grubość',
            'rodzaj_pl_p': 'Symbol płytek',
            'ilosc_pl_p': 'Ilość płytek',
            'ilosc_kraw_p': 'Ilość krawędzi płytki',
            'idpozostale': 'ID',
            'symbol_poz': 'Symbol',
            'producent_poz': 'Producent',
            'srednica_poz': 'Średnica',
            'ilosc_pl_poz': 'Ilość płytek',
            'plytki_poz': 'Symbol płytek',
            'idrozwiertaki': 'ID',
            'symbol_r': 'Symbol',
            'producent_roz': 'Producent',
            'rozmiar_r': 'Rozmiar',
            'idwiertla': 'ID',
            'symbol_w': 'Symbol',
            'producent_w': 'Producent',
            'srednica_w': 'Średnica',
            'dlugosc_w': 'Długość [mm]',
            'idwiertla_skladane': 'ID',
            'symbol_w_skl': 'Symbol',
            'producent_ws': 'Producent',
            'srednica_w_skl': 'Średnica',
            'plytki_w_skl': 'Symbol płytek',
            'idwygniataki': 'ID',
            'symbol_wyg': 'Symbol',
            'producent_wyg': 'Producent',
            'rozmiar_gw': 'Rozmiar gwintu'
        }
        self.model.setTable(slownik[tekst])
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.select()

        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn])

    @pyqtSlot(str)
    def wyszukiwanie(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)

    # opcja z wyszukiwaniem
    def widok(self):
        # Ustawianie własciwości widoku
        self.table_narz.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_narz.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_narz.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_narz.verticalHeader().setVisible(False)
        self.table_narz.setSortingEnabled(True)
        self.table_narz.setModel(self.model)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.setAlternatingRowColors(True)
        self.table.setModel(self.model_poz)
        # self.table.hideColumn(0)
        self.table_narz.doubleClicked.connect(self.klikniecie)

    @pyqtSlot()
    def klikniecie(self):
        x = self.table_narz.currentIndex().row()
        y = self.table_narz.currentIndex().column()
        nazwa = self.table_narz.currentIndex().sibling(x, 1).data()
        print(nazwa)

        # Dodanie narzędzia do pozycji
        if nazwa:
            print(nazwa)
            query = "INSERT INTO '" + self.model_poz.tableName(
            ) + "'(symbol_narz) VALUES ('" + nazwa + "') "
            polaczenie(query)
            # Odświeża tabelę
            self.model_poz.select()
            self.parent.statusBar().showMessage(
                "Dodano narzędzie " + nazwa + " do pozycji " +
                self.model_poz.tableName(), 10000)
        else:
            print(self.model_poz.tableName())
            print("Brak wybranego narzędzia")

    def anulowanie(self):
        self.parent.statusBar().clearMessage()
        from opcje_qt import Wewnatrz
        menu_gl = Wewnatrz(self.parent)
        self.parent.setCentralWidget(menu_gl)
class ReferenceDataDlg(QDialog):
    def __init__(self, parent=None):
        super(ReferenceDataDlg, self).__init__(parent)

        self.model = QSqlTableModel(self)
        self.model.setTable("reference")
        self.model.setSort(ID, Qt.AscendingOrder)
        self.model.setHeaderData(ID, Qt.Horizontal, "ID")
        self.model.setHeaderData(CATEGORY, Qt.Horizontal, "小车编号")
        self.model.setHeaderData(SHORTDESC, Qt.Horizontal, "检查记录")
        self.model.setHeaderData(LONGDESC, Qt.Horizontal, "巡检日期")
        self.model.select()

        self.view = QTableView()
        self.view.setModel(self.model)
        self.view.setSelectionMode(QTableView.SingleSelection)
        self.view.setSelectionBehavior(QTableView.SelectRows)
        self.view.setColumnHidden(ID, True)
        self.view.resizeColumnsToContents()

        buttonBox = QDialogButtonBox()
        addButton = buttonBox.addButton("&添加", QDialogButtonBox.ActionRole)
        deleteButton = buttonBox.addButton("&删除", QDialogButtonBox.ActionRole)
        sortButton = buttonBox.addButton("&排序", QDialogButtonBox.ActionRole)
        if not MAC:
            addButton.setFocusPolicy(Qt.NoFocus)
            deleteButton.setFocusPolicy(Qt.NoFocus)
            sortButton.setFocusPolicy(Qt.NoFocus)

        menu = QMenu(self)
        sortByCategoryAction = menu.addAction("按小车编号排序")
        sortByDescriptionAction = menu.addAction("按检查记录排序")
        sortByIDAction = menu.addAction("按编号顺序排序")
        sortButton.setMenu(menu)
        closeButton = buttonBox.addButton(QDialogButtonBox.Close)

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.addWidget(buttonBox)
        self.setLayout(layout)

        addButton.clicked.connect(self.addRecord)
        deleteButton.clicked.connect(self.deleteRecord)
        sortByCategoryAction.triggered.connect(lambda: self.sort(CATEGORY))
        sortByDescriptionAction.triggered.connect(lambda: self.sort(SHORTDESC))
        sortByIDAction.triggered.connect(lambda: self.sort(ID))
        closeButton.clicked.connect(self.accept)
        self.setWindowTitle("巡检历史数据")
        self.setWindowIcon(
            QtGui.QIcon('icon/update_128px_1156069_easyicon.net.ico'))

    def addRecord(self):
        row = self.model.rowCount()
        self.model.insertRow(row)
        index = self.model.index(row, CATEGORY)
        self.view.setCurrentIndex(index)
        self.view.edit(index)

    def deleteRecord(self):
        index = self.view.currentIndex()
        if not index.isValid():
            return
        record = self.model.record(index.row())
        category = record.value(CATEGORY)
        desc = record.value(SHORTDESC)
        if (QMessageBox.question(self, "Reference Data",
                                 ("确定删除 {1} 的数据?".format(desc, category)),
                                 QMessageBox.Yes
                                 | QMessageBox.No) == QMessageBox.No):
            return
        self.model.removeRow(index.row())
        self.model.submitAll()
        self.model.select()

    def sort(self, column):
        self.model.setSort(column, Qt.AscendingOrder)
        self.model.select()
class BackTestViewer(QDialog):
    def __init__(self):
        super(BackTestViewer, self).__init__()
        self.resize(800, 500)
        self.setWindowTitle('QUANT XH 金融终端')
        self.setWindowIcon(QIcon('static/icon.png'))
        self.queryModel = None
        self.tableView = None
        self.currentPage = 1
        self.totalPage = 0
        self.displayRecord = 0
        self.totalRecord = 0
        self.pageRecord = 10
        self.initUI()

    def initUI(self):
        f = FETCH()
        self.init_data = f.fetch_backtest_history()
        self.totalRecord = len(self.init_data)
        self.totalPage = self.totalRecord // 10 + 1
        self.vbox = QVBoxLayout()
        self.h1box = QHBoxLayout()
        self.h2box = QHBoxLayout()

        self.searchEdit = QLineEdit()
        self.searchEdit.setFixedHeight(32)
        self.searchEdit.setFont(QFont("仿宋", 15))

        self.searchButton = QPushButton("查询")
        self.searchButton.setFixedHeight(32)
        self.searchButton.setFont(QFont("仿宋", 15))

        self.condisionComboBox = QComboBox()
        searchCondision = ["按回测编号查找", "按回测类型查找"]
        self.condisionComboBox.setFixedHeight(32)
        self.condisionComboBox.setFont(QFont("仿宋", 15))
        self.condisionComboBox.addItems(searchCondision)

        self.h1box.addWidget(self.searchEdit)
        self.h1box.addWidget(self.condisionComboBox)
        self.h1box.addWidget(self.searchButton)

        self.currentPageLabel = QLabel(self)
        self.currentPageLabel.setFixedWidth(140)
        self.currentPageLabel.setFont(QFont("仿宋", 12))

        self.jumpToLabel = QLabel(self)
        self.jumpToLabel.setText("跳转到第")
        self.jumpToLabel.setFont(QFont("仿宋", 12))
        self.jumpToLabel.setFixedWidth(90)
        self.pageEdit = QLineEdit()
        self.pageEdit.setFixedWidth(30)
        self.pageEdit.setFont(QFont("仿宋", 12))
        self.pageLabel = QLabel(self)
        self.pageLabel.setText("/" + str(self.totalPage) + "页")
        self.pageLabel.setFont(QFont("仿宋", 12))
        self.pageLabel.setFixedWidth(60)
        self.jumpToButton = QPushButton(self)
        self.jumpToButton.setText("跳转")
        self.jumpToButton.setFont(QFont("仿宋", 12))
        self.jumpToButton.setFixedHeight(30)
        self.jumpToButton.setFixedWidth(60)
        self.prevButton = QPushButton("前一页")
        self.prevButton.setFont(QFont("仿宋", 12))
        self.prevButton.setFixedHeight(30)
        self.prevButton.setFixedWidth(80)
        self.backButton = QPushButton("后一页")
        self.backButton.setFont(QFont("仿宋", 12))
        self.backButton.setFixedHeight(30)
        self.backButton.setFixedWidth(80)
        self.prevButton.clicked.connect(self.prevButtonClicked)
        self.backButton.clicked.connect(self.backButtonClicked)
        self.jumpToButton.clicked.connect(self.jumpToButtonClicked)
        self.searchButton.clicked.connect(self.searchButtonClicked)

        self.detailbutton = QPushButton(self)
        self.detailbutton.setText("详细信息")
        self.detailbutton.setFixedWidth(90)
        self.detailbutton.setFont(QFont("仿宋", 12))
        self.detailbutton.clicked.connect(self.detailInfo)

        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.currentPageLabel)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.jumpToLabel)
        self.hbox.addWidget(self.pageEdit)
        self.hbox.addWidget(self.pageLabel)
        self.hbox.addWidget(self.jumpToButton)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.detailbutton)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.prevButton)
        self.hbox.addWidget(self.backButton)
        widget = QWidget()
        widget.setLayout(self.hbox)
        self.h2box.addWidget(widget)

        self.tableView = QTableView()

        self.tableView.horizontalHeader().setStretchLastSection(True)
        # self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Interactive)
        self.tableView.verticalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.tableView.verticalHeader().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.setFont(QFont("仿宋", 10))
        self.tableView.horizontalHeader().setFont(QFont("仿宋", 12))

        self.queryModel = QStandardItemModel(self.pageRecord, 2)
        self.updateQueryModel()

        self.vbox.addLayout(self.h1box)
        self.vbox.addWidget(self.tableView)
        self.vbox.addLayout(self.h2box)
        self.setLayout(self.vbox)

    def setButtonStatus(self):
        if self.currentPage == self.totalPage and self.currentPage == 1:
            self.prevButton.setEnabled(False)
            self.backButton.setEnabled(False)
        elif self.currentPage == self.totalPage:
            self.prevButton.setEnabled(True)
            self.backButton.setEnabled(False)
        elif self.currentPage == 1:
            self.backButton.setEnabled(True)
            self.prevButton.setEnabled(False)
        elif self.currentPage < self.totalPage and self.currentPage > 1:
            self.prevButton.setEnabled(True)
            self.backButton.setEnabled(True)

    def searchButtonClicked(self):
        f = FETCH()
        try:
            if self.searchEdit.text() == "":
                self.init_data = f.fetch_backtest_history()
                self.totalRecord = len(self.init_data)
                self.totalPage = self.totalRecord // 10 + 1
                self.currentPage = 1
                self.pageLabel.setText("/" + str(self.totalPage) + "页")
                self.updateQueryModel()
            elif self.condisionComboBox.currentText() == "按回测编号查找":
                self.init_data = f.fuzzy_fetch_backtest_history(
                    self.searchEdit.text(), "ac_id")
                self.totalRecord = len(self.init_data)
                self.totalPage = self.totalRecord // 10 + 1
                self.currentPage = 1
                self.pageLabel.setText("/" + str(self.totalPage) + "页")
                self.updateQueryModel()
            elif self.condisionComboBox.currentText() == "按回测类型查找":
                self.init_data = f.fuzzy_fetch_backtest_history(
                    self.searchEdit.text(), "type")
                self.totalRecord = len(self.init_data)
                self.totalPage = self.totalRecord // 10 + 1
                self.currentPage = 1
                self.pageLabel.setText("/" + str(self.totalPage) + "页")
                self.updateQueryModel()
        except KeyError:
            print(
                QMessageBox.warning(self, "警告", "没有记录与之匹配", QMessageBox.Yes,
                                    QMessageBox.Yes))

    def prevButtonClicked(self):
        self.currentPage -= 1
        self.updateQueryModel()

    def backButtonClicked(self):
        self.currentPage += 1
        self.updateQueryModel()

    def jumpToButtonClicked(self):
        if (self.pageEdit.text().isdigit()):
            self.currentPage = int(self.pageEdit.text())
            if (self.currentPage > self.totalPage):
                self.currentPage = self.totalPage
            if (self.currentPage <= 1):
                self.currentPage = 1
        else:
            self.currentPage = 1
        self.updateQueryModel()

    def updateQueryModel(self):
        self.queryModel.clear()
        self.displayRecord = self.pageRecord if self.currentPage < self.totalPage else self.totalRecord % self.pageRecord
        for row in range(0, self.displayRecord):
            for column in range(4):
                if column > 1:
                    item = QStandardItem(
                        str(self.init_data.iloc[(self.currentPage - 1) *
                                                self.pageRecord + row,
                                                column]))
                else:
                    item = QStandardItem(
                        self.init_data.iloc[(self.currentPage - 1) *
                                            self.pageRecord + row, column])
                self.queryModel.setItem(row, column, item)
        self.currentPageLabel.setText("当前页数:" + str(self.currentPage))
        self.tableView.setModel(self.queryModel)
        self.setButtonStatus()
        self.queryModel.setHeaderData(0, Qt.Horizontal, "回测编号")
        self.queryModel.setHeaderData(1, Qt.Horizontal, "回测类型")
        self.queryModel.setHeaderData(2, Qt.Horizontal, "回报率")
        self.queryModel.setHeaderData(3, Qt.Horizontal, "初始值")
        self.pageEdit.setText("")
        return

    def detailInfo(self):
        index_ = self.tableView.currentIndex().row()
        if (index_ == -1):
            print(
                QMessageBox.warning(self, "警告", "您没有选中任何纪录", QMessageBox.Yes,
                                    QMessageBox.Yes))
            return
        else:
            ac_id = self.queryModel.data(self.queryModel.index(index_, 0))
            self.BackTestResultoDialog(ac_id)

    def BackTestResultoDialog(self, ac_id):
        dialog = BackTestResult(ac_id)
        dialog.show()
        dialog.exec_()
Exemple #17
0
class comics_project_manager_docker(DockWidget):
    setupDictionary = {}
    stringName = i18n("Comics Manager")
    projecturl = None

    def __init__(self):
        super().__init__()
        self.setWindowTitle(self.stringName)

        # Setup layout:
        base = QHBoxLayout()
        widget = QWidget()
        widget.setLayout(base)
        baseLayout = QSplitter()
        base.addWidget(baseLayout)
        self.setWidget(widget)
        buttonLayout = QVBoxLayout()
        buttonBox = QWidget()
        buttonBox.setLayout(buttonLayout)
        baseLayout.addWidget(buttonBox)

        # Comic page list and pages model
        self.comicPageList = QTableView()
        self.comicPageList.verticalHeader().setSectionsMovable(True)
        self.comicPageList.verticalHeader().setDragEnabled(True)
        self.comicPageList.verticalHeader().setDragDropMode(
            QAbstractItemView.InternalMove)
        self.comicPageList.setAcceptDrops(True)
        self.comicPageList.horizontalHeader().setStretchLastSection(True)
        self.pagesModel = QStandardItemModel()
        self.comicPageList.doubleClicked.connect(self.slot_open_page)
        self.comicPageList.setIconSize(QSize(128, 128))
        # self.comicPageList.itemDelegate().closeEditor.connect(self.slot_write_description)
        self.pagesModel.layoutChanged.connect(self.slot_write_config)
        self.pagesModel.rowsInserted.connect(self.slot_write_config)
        self.pagesModel.rowsRemoved.connect(self.slot_write_config)
        self.comicPageList.verticalHeader().sectionMoved.connect(
            self.slot_write_config)
        self.comicPageList.setModel(self.pagesModel)
        pageBox = QWidget()
        pageBox.setLayout(QVBoxLayout())
        zoomSlider = QSlider(Qt.Horizontal, None)
        zoomSlider.setRange(1, 8)
        zoomSlider.setValue(4)
        zoomSlider.setTickInterval(1)
        zoomSlider.setMinimumWidth(10)
        zoomSlider.valueChanged.connect(self.slot_scale_thumbnails)
        self.projectName = Elided_Text_Label()
        pageBox.layout().addWidget(self.projectName)
        pageBox.layout().addWidget(zoomSlider)
        pageBox.layout().addWidget(self.comicPageList)
        baseLayout.addWidget(pageBox)

        self.btn_project = QToolButton()
        self.btn_project.setPopupMode(QToolButton.MenuButtonPopup)
        self.btn_project.setSizePolicy(QSizePolicy.Minimum,
                                       QSizePolicy.Minimum)
        menu_project = QMenu()
        self.action_new_project = QAction(i18n("New Project"), self)
        self.action_new_project.triggered.connect(self.slot_new_project)
        self.action_load_project = QAction(i18n("Open Project"), self)
        self.action_load_project.triggered.connect(self.slot_open_config)
        menu_project.addAction(self.action_new_project)
        menu_project.addAction(self.action_load_project)
        self.btn_project.setMenu(menu_project)
        self.btn_project.setDefaultAction(self.action_load_project)
        buttonLayout.addWidget(self.btn_project)

        # Settings dropdown with actions for the different settings menus.
        self.btn_settings = QToolButton()
        self.btn_settings.setPopupMode(QToolButton.MenuButtonPopup)
        self.btn_settings.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)
        self.action_edit_project_settings = QAction(i18n("Project Settings"),
                                                    self)
        self.action_edit_project_settings.triggered.connect(
            self.slot_edit_project_settings)
        self.action_edit_meta_data = QAction(i18n("Meta Data"), self)
        self.action_edit_meta_data.triggered.connect(self.slot_edit_meta_data)
        self.action_edit_export_settings = QAction(i18n("Export Settings"),
                                                   self)
        self.action_edit_export_settings.triggered.connect(
            self.slot_edit_export_settings)
        menu_settings = QMenu()
        menu_settings.addAction(self.action_edit_project_settings)
        menu_settings.addAction(self.action_edit_meta_data)
        menu_settings.addAction(self.action_edit_export_settings)
        self.btn_settings.setDefaultAction(self.action_edit_project_settings)
        self.btn_settings.setMenu(menu_settings)
        buttonLayout.addWidget(self.btn_settings)
        self.btn_settings.setDisabled(True)

        # Add page drop down with different page actions.
        self.btn_add_page = QToolButton()
        self.btn_add_page.setPopupMode(QToolButton.MenuButtonPopup)
        self.btn_add_page.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)

        self.action_add_page = QAction(i18n("Add Page"), self)
        self.action_add_page.triggered.connect(self.slot_add_new_page_single)
        self.action_add_template = QAction(i18n("Add Page From Template"),
                                           self)
        self.action_add_template.triggered.connect(
            self.slot_add_new_page_from_template)
        self.action_add_existing = QAction(i18n("Add Existing Pages"), self)
        self.action_add_existing.triggered.connect(self.slot_add_page_from_url)
        self.action_remove_selected_page = QAction(i18n("Remove Page"), self)
        self.action_remove_selected_page.triggered.connect(
            self.slot_remove_selected_page)
        self.action_resize_all_pages = QAction(i18n("Batch Resize"), self)
        self.action_resize_all_pages.triggered.connect(self.slot_batch_resize)
        self.btn_add_page.setDefaultAction(self.action_add_page)
        self.action_show_page_viewer = QAction(i18n("View Page In Window"),
                                               self)
        self.action_show_page_viewer.triggered.connect(
            self.slot_show_page_viewer)
        self.action_scrape_authors = QAction(i18n("Scrape Author Info"), self)
        self.action_scrape_authors.setToolTip(
            i18n(
                "Search for author information in documents and add it to the author list. This doesn't check for duplicates."
            ))
        self.action_scrape_authors.triggered.connect(
            self.slot_scrape_author_list)
        actionList = []
        menu_page = QMenu()
        actionList.append(self.action_add_page)
        actionList.append(self.action_add_template)
        actionList.append(self.action_add_existing)
        actionList.append(self.action_remove_selected_page)
        actionList.append(self.action_resize_all_pages)
        actionList.append(self.action_show_page_viewer)
        actionList.append(self.action_scrape_authors)
        menu_page.addActions(actionList)
        self.btn_add_page.setMenu(menu_page)
        buttonLayout.addWidget(self.btn_add_page)
        self.btn_add_page.setDisabled(True)

        self.comicPageList.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.comicPageList.addActions(actionList)

        # Export button that... exports.
        self.btn_export = QPushButton(i18n("Export Comic"))
        self.btn_export.clicked.connect(self.slot_export)
        buttonLayout.addWidget(self.btn_export)
        self.btn_export.setDisabled(True)

        self.btn_project_url = QPushButton(i18n("Copy Location"))
        self.btn_project_url.setToolTip(
            i18n(
                "Copies the path of the project to the clipboard. Useful for quickly copying to a file manager or the like."
            ))
        self.btn_project_url.clicked.connect(self.slot_copy_project_url)
        self.btn_project_url.setDisabled(True)
        buttonLayout.addWidget(self.btn_project_url)

        self.page_viewer_dialog = comics_project_page_viewer.comics_project_page_viewer(
        )

        Application.notifier().imageSaved.connect(
            self.slot_check_for_page_update)

        buttonLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum,
                        QSizePolicy.MinimumExpanding))

    """
    Open the config file and load the json file into a dictionary.
    """

    def slot_open_config(self):
        self.path_to_config = QFileDialog.getOpenFileName(
            caption=i18n("Please select the json comic config file."),
            filter=str(i18n("json files") + "(*.json)"))[0]
        if os.path.exists(self.path_to_config) is True:
            configFile = open(self.path_to_config,
                              "r",
                              newline="",
                              encoding="utf-16")
            self.setupDictionary = json.load(configFile)
            self.projecturl = os.path.dirname(str(self.path_to_config))
            configFile.close()
            self.load_config()

    """
    Further config loading.
    """

    def load_config(self):
        self.projectName.setMainText(
            text=str(self.setupDictionary["projectName"]))
        self.fill_pages()
        self.btn_settings.setEnabled(True)
        self.btn_add_page.setEnabled(True)
        self.btn_export.setEnabled(True)
        self.btn_project_url.setEnabled(True)

    """
    Fill the pages model with the pages from the pages list.
    """

    def fill_pages(self):
        self.loadingPages = True
        self.pagesModel.clear()
        self.pagesModel.setHorizontalHeaderLabels(
            [i18n("Page"), i18n("Description")])
        pagesList = []
        if "pages" in self.setupDictionary.keys():
            pagesList = self.setupDictionary["pages"]
        progress = QProgressDialog()
        progress.setMinimum(0)
        progress.setMaximum(len(pagesList))
        progress.setWindowTitle(i18n("Loading pages..."))
        for url in pagesList:
            absurl = os.path.join(self.projecturl, url)
            if (os.path.exists(absurl)):
                #page = Application.openDocument(absurl)
                page = zipfile.ZipFile(absurl, "r")
                thumbnail = QImage.fromData(page.read("preview.png"))
                pageItem = QStandardItem()
                dataList = self.get_description_and_title(
                    page.read("documentinfo.xml"))
                if (dataList[0].isspace() or len(dataList[0]) < 1):
                    dataList[0] = os.path.basename(url)
                pageItem.setText(dataList[0].replace("_", " "))
                pageItem.setDragEnabled(True)
                pageItem.setDropEnabled(False)
                pageItem.setEditable(False)
                pageItem.setIcon(QIcon(QPixmap.fromImage(thumbnail)))
                pageItem.setToolTip(url)
                page.close()
                description = QStandardItem()
                description.setText(dataList[1])
                description.setEditable(False)
                listItem = []
                listItem.append(pageItem)
                listItem.append(description)
                self.pagesModel.appendRow(listItem)
                self.comicPageList.resizeRowsToContents()
                self.comicPageList.setColumnWidth(0, 200)
                self.comicPageList.setColumnWidth(1, 256)
                progress.setValue(progress.value() + 1)
        progress.setValue(len(pagesList))
        self.loadingPages = False

    """
    Function that is triggered by the zoomSlider
    Resizes the thumbnails.
    """

    def slot_scale_thumbnails(self, multiplier=4):
        self.comicPageList.setIconSize(QSize(multiplier * 32, multiplier * 32))
        self.comicPageList.resizeRowsToContents()

    """
    Function that takes the documentinfo.xml and parses it for the title, subject and abstract tags,
    to get the title and description.
    
    @returns a stringlist with the name on 0 and the description on 1.
    """

    def get_description_and_title(self, string):
        xmlDoc = ET.fromstring(string)
        calligra = str("{http://www.calligra.org/DTD/document-info}")
        name = ""
        if ET.iselement(xmlDoc[0].find(calligra + 'title')):
            name = xmlDoc[0].find(calligra + 'title').text
            if name is None:
                name = " "
        desc = ""
        if ET.iselement(xmlDoc[0].find(calligra + 'subject')):
            desc = xmlDoc[0].find(calligra + 'subject').text
        if desc is None or desc.isspace() or len(desc) < 1:
            if ET.iselement(xmlDoc[0].find(calligra + 'abstract')):
                desc = str(xmlDoc[0].find(calligra + 'abstract').text)
                if desc.startswith("<![CDATA["):
                    desc = desc[len("<![CDATA["):]
                if desc.startswith("]]>"):
                    desc = desc[:-len("]]>")]
        return [name, desc]

    """
    Scrapes authors from the author data in the document info and puts them into the author list.
    Doesn't check for duplicates.
    """

    def slot_scrape_author_list(self):
        listOfAuthors = []
        if "authorList" in self.setupDictionary.keys():
            listOfAuthors = self.setupDictionary["authorList"]
        if "pages" in self.setupDictionary.keys():
            for relurl in self.setupDictionary["pages"]:
                absurl = os.path.join(self.projecturl, relurl)
                page = zipfile.ZipFile(absurl, "r")
                xmlDoc = ET.fromstring(page.read("documentinfo.xml"))
                calligra = str("{http://www.calligra.org/DTD/document-info}")
                authorelem = xmlDoc.find(calligra + 'author')
                author = {}
                if ET.iselement(authorelem.find(calligra + 'full-name')):
                    author["nickname"] = str(
                        authorelem.find(calligra + 'full-name').text)

                if ET.iselement(
                        authorelem.find(calligra + 'creator-first-name')):
                    author["first-name"] = str(
                        authorelem.find(calligra + 'creator-first-name').text)

                if ET.iselement(authorelem.find(calligra + 'initial')):
                    author["initials"] = str(
                        authorelem.find(calligra + 'initial').text)

                if ET.iselement(authorelem.find(calligra +
                                                'creator-last-name')):
                    author["last-name"] = str(
                        authorelem.find(calligra + 'creator-last-name').text)

                if ET.iselement(authorelem.find(calligra + 'email')):
                    author["email"] = str(
                        authorelem.find(calligra + 'email').text)

                if ET.iselement(authorelem.find(calligra + 'contact')):
                    contact = authorelem.find(calligra + 'contact')
                    contactMode = contact.get("type")
                    if contactMode == "email":
                        author["email"] = str(contact.text)
                    if contactMode == "homepage":
                        author["homepage"] = str(contact.text)

                if ET.iselement(authorelem.find(calligra + 'position')):
                    author["role"] = str(
                        authorelem.find(calligra + 'position').text)
                listOfAuthors.append(author)
                page.close()
        self.setupDictionary["authorList"] = listOfAuthors

    """
    Edit the general project settings like the project name, concept, pages location, export location, template location, metadata
    """

    def slot_edit_project_settings(self):
        dialog = comics_project_settings_dialog.comics_project_details_editor(
            self.projecturl)
        dialog.setConfig(self.setupDictionary, self.projecturl)

        if dialog.exec_() == QDialog.Accepted:
            self.setupDictionary = dialog.getConfig(self.setupDictionary)
            self.slot_write_config()
            self.setWindowTitle(self.stringName + ": " +
                                str(self.setupDictionary["projectName"]))

    """
    This allows users to select existing pages and add them to the pages list. The pages are currently not copied to the pages folder. Useful for existing projects.
    """

    def slot_add_page_from_url(self):
        # get the pages.
        urlList = QFileDialog.getOpenFileNames(
            caption=i18n("Which existing pages to add?"),
            directory=self.projecturl,
            filter=str(i18n("Krita files") + "(*.kra)"))[0]

        # get the existing pages list.
        pagesList = []
        if "pages" in self.setupDictionary.keys():
            pagesList = self.setupDictionary["pages"]

        # And add each url in the url list to the pages list and the model.
        for url in urlList:
            if self.projecturl not in urlList:
                newUrl = os.path.join(self.projecturl,
                                      self.setupDictionary["pagesLocation"],
                                      os.path.basename(url))
                shutil.move(url, newUrl)
                url = newUrl
            relative = os.path.relpath(url, self.projecturl)
            if url not in pagesList:
                page = zipfile.ZipFile(url, "r")
                thumbnail = QImage.fromData(page.read("preview.png"))
                dataList = self.get_description_and_title(
                    page.read("documentinfo.xml"))
                if (dataList[0].isspace() or len(dataList[0]) < 1):
                    dataList[0] = os.path.basename(url)
                newPageItem = QStandardItem()
                newPageItem.setIcon(QIcon(QPixmap.fromImage(thumbnail)))
                newPageItem.setDragEnabled(True)
                newPageItem.setDropEnabled(False)
                newPageItem.setEditable(False)
                newPageItem.setText(dataList[0].replace("_", " "))
                newPageItem.setToolTip(relative)
                page.close()
                description = QStandardItem()
                description.setText(dataList[1])
                description.setEditable(False)
                listItem = []
                listItem.append(newPageItem)
                listItem.append(description)
                self.pagesModel.appendRow(listItem)
                self.comicPageList.resizeRowsToContents()

    """
    Remove the selected page from the list of pages. This does not remove it from disk(far too dangerous).
    """

    def slot_remove_selected_page(self):
        index = self.comicPageList.currentIndex()
        self.pagesModel.removeRow(index.row())

    """
    This function adds a new page from the default template. If there's no default template, or the file does not exist, it will 
    show the create/import template dialog. It will remember the selected item as the default template.
    """

    def slot_add_new_page_single(self):
        templateUrl = "templatepage"
        templateExists = False

        if "singlePageTemplate" in self.setupDictionary.keys():
            templateUrl = self.setupDictionary["singlePageTemplate"]
        if os.path.exists(os.path.join(self.projecturl, templateUrl)):
            templateExists = True

        if templateExists is False:
            if "templateLocation" not in self.setupDictionary.keys():
                self.setupDictionary["templateLocation"] = os.path.relpath(
                    QFileDialog.getExistingDirectory(
                        caption=i18n("Where are the templates located?"),
                        options=QFileDialog.ShowDirsOnly), self.projecturl)

            templateDir = os.path.join(
                self.projecturl, self.setupDictionary["templateLocation"])
            template = comics_template_dialog.comics_template_dialog(
                templateDir)

            if template.exec_() == QDialog.Accepted:
                templateUrl = os.path.relpath(template.url(), self.projecturl)
                self.setupDictionary["singlePageTemplate"] = templateUrl
        if os.path.exists(os.path.join(self.projecturl, templateUrl)):
            self.add_new_page(templateUrl)

    """
    This function always asks for a template showing the new template window. This allows users to have multiple different
    templates created for back covers, spreads, other and have them accesible, while still having the convenience of a singular
    "add page" that adds a default.
    """

    def slot_add_new_page_from_template(self):
        if "templateLocation" not in self.setupDictionary.keys():
            self.setupDictionary["templateLocation"] = os.path.relpath(
                QFileDialog.getExistingDirectory(
                    caption=i18n("Where are the templates located?"),
                    options=QFileDialog.ShowDirsOnly), self.projecturl)

        templateDir = os.path.join(self.projecturl,
                                   self.setupDictionary["templateLocation"])
        template = comics_template_dialog.comics_template_dialog(templateDir)

        if template.exec_() == QDialog.Accepted:
            templateUrl = os.path.relpath(template.url(), self.projecturl)
            self.add_new_page(templateUrl)

    """
    This is the actual function that adds the template using the template url.
    It will attempt to name the new page projectName+number.
    """

    def add_new_page(self, templateUrl):

        # check for page list and or location.
        pagesList = []
        if "pages" in self.setupDictionary.keys():
            pagesList = self.setupDictionary["pages"]
        if not "pageNumber" in self.setupDictionary.keys():
            self.setupDictionary['pageNumber'] = 0

        if (str(self.setupDictionary["pagesLocation"]).isspace()):
            self.setupDictionary["pagesLocation"] = os.path.relpath(
                QFileDialog.getExistingDirectory(
                    caption=i18n("Where should the pages go?"),
                    options=QFileDialog.ShowDirsOnly), self.projecturl)

        # Search for the possible name.
        extraUnderscore = str()
        if str(self.setupDictionary["projectName"])[-1].isdigit():
            extraUnderscore = "_"
        self.setupDictionary['pageNumber'] += 1
        pageName = str(self.setupDictionary["projectName"]).replace(
            " ", "_") + extraUnderscore + str(
                format(self.setupDictionary['pageNumber'], "03d"))
        url = os.path.join(str(self.setupDictionary["pagesLocation"]),
                           pageName + ".kra")

        # open the page by opening the template and resaving it, or just opening it.
        absoluteUrl = os.path.join(self.projecturl, url)
        if (os.path.exists(absoluteUrl)):
            newPage = Application.openDocument(absoluteUrl)
        else:
            booltemplateExists = os.path.exists(
                os.path.join(self.projecturl, templateUrl))
            if booltemplateExists is False:
                templateUrl = os.path.relpath(
                    QFileDialog.getOpenFileName(
                        caption=i18n(
                            "Which image should be the basis the new page?"),
                        directory=self.projecturl,
                        filter=str(i18n("Krita files") + "(*.kra)"))[0],
                    self.projecturl)
            newPage = Application.openDocument(
                os.path.join(self.projecturl, templateUrl))
            newPage.waitForDone()
            newPage.setFileName(absoluteUrl)
            newPage.setName(pageName.replace("_", " "))
            newPage.save()
            newPage.waitForDone()

        # Get out the extra data for the standard item.
        newPageItem = QStandardItem()
        newPageItem.setIcon(
            QIcon(QPixmap.fromImage(newPage.thumbnail(256, 256))))
        newPageItem.setDragEnabled(True)
        newPageItem.setDropEnabled(False)
        newPageItem.setEditable(False)
        newPageItem.setText(pageName.replace("_", " "))
        newPageItem.setToolTip(url)

        # close page document.
        while os.path.exists(absoluteUrl) is False:
            qApp.processEvents()

        newPage.close()

        # add item to page.
        description = QStandardItem()
        description.setText(str(""))
        description.setEditable(False)
        listItem = []
        listItem.append(newPageItem)
        listItem.append(description)
        self.pagesModel.appendRow(listItem)
        self.comicPageList.resizeRowsToContents()
        self.comicPageList.resizeColumnToContents(0)

    """
    Write to the json configuratin file.
    This also checks the current state of the pages list.
    """

    def slot_write_config(self):

        # Don't load when the pages are still being loaded, otherwise we'll be overwriting our own pages list.
        if (self.loadingPages is False):
            print("CPMT: writing comic configuration...")

            # Generate a pages list from the pagesmodel.
            # Because we made the drag-and-drop use the tableview header, we need to first request the logicalIndex
            # for the visualIndex, and then request the items for the logical index in the pagesmodel.
            # After that, we rename the verticalheader to have the appropriate numbers it will have when reloading.
            pagesList = []
            listOfHeaderLabels = []
            for i in range(self.pagesModel.rowCount()):
                listOfHeaderLabels.append(str(i))
            for i in range(self.pagesModel.rowCount()):
                iLogical = self.comicPageList.verticalHeader().logicalIndex(i)
                index = self.pagesModel.index(iLogical, 0)
                if index.isValid() is False:
                    index = self.pagesModel.index(i, 0)
                url = str(self.pagesModel.data(index, role=Qt.ToolTipRole))
                if url not in pagesList:
                    pagesList.append(url)
                listOfHeaderLabels[iLogical] = str(i + 1)
            self.pagesModel.setVerticalHeaderLabels(listOfHeaderLabels)
            self.comicPageList.verticalHeader().update()
            self.setupDictionary["pages"] = pagesList

            # Save to our json file.
            configFile = open(self.path_to_config,
                              "w",
                              newline="",
                              encoding="utf-16")
            json.dump(self.setupDictionary,
                      configFile,
                      indent=4,
                      sort_keys=True,
                      ensure_ascii=False)
            configFile.close()
            print("CPMT: done")

    """
    Open a page in the pagesmodel in Krita.
    """

    def slot_open_page(self, index):
        if index.column() is 0:
            # Get the absolute url from the relative one in the pages model.
            absoluteUrl = os.path.join(
                self.projecturl,
                str(self.pagesModel.data(index, role=Qt.ToolTipRole)))

            # Make sure the page exists.
            if os.path.exists(absoluteUrl):
                page = Application.openDocument(absoluteUrl)

                # Set the title to the filename if it was empty. It looks a bit neater.
                if page.name().isspace or len(page.name()) < 1:
                    page.setName(
                        str(self.pagesModel.data(index,
                                                 role=Qt.DisplayRole)).replace(
                                                     "_", " "))

                # Add views for the document so the user can use it.
                Application.activeWindow().addView(page)
                Application.setActiveDocument(page)
            else:
                print(
                    "CPMT: The page cannot be opened because the file doesn't exist:",
                    absoluteUrl)

    """
    Call up the metadata editor dialog. Only when the dialog is "Accepted" will the metadata be saved.
    """

    def slot_edit_meta_data(self):
        dialog = comics_metadata_dialog.comic_meta_data_editor()

        dialog.setConfig(self.setupDictionary)
        if (dialog.exec_() == QDialog.Accepted):
            self.setupDictionary = dialog.getConfig(self.setupDictionary)
            self.slot_write_config()

    """
    An attempt at making the description editable from the comic pages list. It is currently not working because ZipFile
    has no overwrite mechanism, and I don't have the energy to write one yet.
    """

    def slot_write_description(self, index):

        for row in range(self.pagesModel.rowCount()):
            index = self.pagesModel.index(row, 1)
            indexUrl = self.pagesModel.index(row, 0)
            absoluteUrl = os.path.join(
                self.projecturl,
                str(self.pagesModel.data(indexUrl, role=Qt.ToolTipRole)))
            page = zipfile.ZipFile(absoluteUrl, "a")
            xmlDoc = ET.ElementTree()
            ET.register_namespace("",
                                  "http://www.calligra.org/DTD/document-info")
            location = os.path.join(self.projecturl, "documentinfo.xml")
            xmlDoc.parse(location)
            xmlroot = ET.fromstring(page.read("documentinfo.xml"))
            calligra = "{http://www.calligra.org/DTD/document-info}"
            aboutelem = xmlroot.find(calligra + 'about')
            if ET.iselement(aboutelem.find(calligra + 'subject')):
                desc = aboutelem.find(calligra + 'subject')
                desc.text = self.pagesModel.data(index, role=Qt.EditRole)
                xmlstring = ET.tostring(xmlroot,
                                        encoding='unicode',
                                        method='xml',
                                        short_empty_elements=False)
                page.writestr(zinfo_or_arcname="documentinfo.xml",
                              data=xmlstring)
                for document in Application.documents():
                    if str(document.fileName()) == str(absoluteUrl):
                        document.setDocumentInfo(xmlstring)
            page.close()

    """
    Calls up the export settings dialog. Only when accepted will the configuration be written.
    """

    def slot_edit_export_settings(self):
        dialog = comics_export_dialog.comic_export_setting_dialog()
        dialog.setConfig(self.setupDictionary)

        if (dialog.exec_() == QDialog.Accepted):
            self.setupDictionary = dialog.getConfig(self.setupDictionary)
            self.slot_write_config()

    """
    Export the comic. Won't work without export settings set.
    """

    def slot_export(self):
        exporter = comics_exporter.comicsExporter()
        exporter.set_config(self.setupDictionary, self.projecturl)
        exportSuccess = exporter.export()
        if exportSuccess:
            print(
                "CPMT: Export success! The files have been written to the export folder!"
            )

    """
    Calls up the comics project setup wizard so users can create a new json file with the basic information.
    """

    def slot_new_project(self):
        setup = comics_project_setup_wizard.ComicsProjectSetupWizard()
        setup.showDialog()

    """
    This is triggered by any document save.
    It checks if the given url in in the pages list, and if so,
    updates the appropriate page thumbnail.
    This helps with the management of the pages, because the user
    will be able to see the thumbnails as a todo for the whole comic,
    giving a good overview over whether they still need to ink, color or
    the like for a given page, and it thus also rewards the user whenever
    they save.
    """

    def slot_check_for_page_update(self, url):
        if "pages" in self.setupDictionary.keys():
            relUrl = os.path.relpath(url, self.projecturl)
            if relUrl in self.setupDictionary["pages"]:
                index = self.pagesModel.index(
                    self.setupDictionary["pages"].index(relUrl), 0)
                index2 = self.pagesModel.index(index.row(), 1)
                if index.isValid():
                    pageItem = self.pagesModel.itemFromIndex(index)
                    page = zipfile.ZipFile(url, "r")
                    dataList = self.get_description_and_title(
                        page.read("documentinfo.xml"))
                    if (dataList[0].isspace() or len(dataList[0]) < 1):
                        dataList[0] = os.path.basename(url)
                    thumbnail = QImage.fromData(page.read("preview.png"))
                    pageItem.setIcon(QIcon(QPixmap.fromImage(thumbnail)))
                    pageItem.setText(dataList[0])
                    self.pagesModel.setItem(index.row(), index.column(),
                                            pageItem)
                    self.pagesModel.setData(index2, str(dataList[1]),
                                            Qt.DisplayRole)

    """
    Resize all the pages in the pages list.
    It will show a dialog with the options for resizing. Then, it will try to pop up a progress dialog while resizing.
    The progress dialog shows the remaining time and pages.
    """

    def slot_batch_resize(self):
        dialog = QDialog()
        dialog.setWindowTitle(i18n("Risize all pages."))
        buttons = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)
        buttons.accepted.connect(dialog.accept)
        buttons.rejected.connect(dialog.reject)
        sizesBox = comics_export_dialog.comic_export_resize_widget(
            "Scale", batch=True, fileType=False)
        exporterSizes = comics_exporter.sizesCalculator()
        dialog.setLayout(QVBoxLayout())
        dialog.layout().addWidget(sizesBox)
        dialog.layout().addWidget(buttons)

        if dialog.exec_() == QDialog.Accepted:
            progress = QProgressDialog(i18n("Resizing pages..."), str(), 0,
                                       len(self.setupDictionary["pages"]))
            progress.setWindowTitle(i18n("Resizing pages."))
            progress.setCancelButton(None)
            timer = QElapsedTimer()
            timer.start()
            config = {}
            config = sizesBox.get_config(config)
            for p in range(len(self.setupDictionary["pages"])):
                absoluteUrl = os.path.join(self.projecturl,
                                           self.setupDictionary["pages"][p])
                progress.setValue(p)
                timePassed = timer.elapsed()
                if (p > 0):
                    timeEstimated = (len(self.setupDictionary["pages"]) -
                                     p) * (timePassed / p)
                    passedString = str(int(timePassed / 60000)) + ":" + format(
                        int(timePassed / 1000), "02d") + ":" + format(
                            timePassed % 1000, "03d")
                    estimatedString = str(int(
                        timeEstimated / 60000)) + ":" + format(
                            int(timeEstimated / 1000), "02d") + ":" + format(
                                int(timeEstimated % 1000), "03d")
                    progress.setLabelText(
                        str(
                            i18n(
                                "{pages} of {pagesTotal} done. \nTime passed: {passedString}:\n Estimated:{estimated}"
                            )).format(pages=p,
                                      pagesTotal=len(
                                          self.setupDictionary["pages"]),
                                      passedString=passedString,
                                      estimated=estimatedString))
                    qApp.processEvents()
                if os.path.exists(absoluteUrl):
                    doc = Application.openDocument(absoluteUrl)
                    listScales = exporterSizes.get_scale_from_resize_config(
                        config["Scale"], [
                            doc.width(),
                            doc.height(),
                            doc.resolution(),
                            doc.resolution()
                        ])
                    doc.scaleImage(listScales[0], listScales[1], listScales[2],
                                   listScales[3], "bicubic")
                    doc.waitForDone()
                    doc.save()
                    doc.waitForDone()
                    doc.close()

    def slot_show_page_viewer(self):
        index = self.comicPageList.currentIndex()
        if index.column() is not 0:
            index = self.pagesModel.index(index.row(), 0)
        # Get the absolute url from the relative one in the pages model.
        absoluteUrl = os.path.join(
            self.projecturl,
            str(self.pagesModel.data(index, role=Qt.ToolTipRole)))

        # Make sure the page exists.
        if os.path.exists(absoluteUrl):
            page = zipfile.ZipFile(absoluteUrl, "r")
            image = QImage.fromData(page.read("mergedimage.png"))
            self.page_viewer_dialog.update_image(image)
            self.page_viewer_dialog.show()
            page.close()

    """
    Function to copy the current project location into the clipboard.
    This is useful for users because they'll be able to use that url to quickly
    move to the project location in outside applications.
    """

    def slot_copy_project_url(self):
        if self.projecturl is not None:
            clipboard = qApp.clipboard()
            clipboard.setText(str(self.projecturl))

    """
    This is required by the dockwidget class, otherwise unused.
    """

    def canvasChanged(self, canvas):
        pass
class NormaOdk(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.skrot = QShortcut(QKeySequence(Qt.Key_Return), self)
        self.naglowki = {
            'iddetale': 'ID',
            'nr_detalu': 'Detal',
            'maszyna': 'Maszyna',
            "ilosc_m": 'Ilość maszyn',
            'ilosc_szt': 'Ilość sztuk na operację',
            'nazwa_op': 'Nazwa operacji',
            'nr_op': 'Nr operacji',
            'tm': 'Czas Tm [s]',
            'tp': 'Czas Tp [s]',
            'tj': 'Czas Tj [h]',
            'norma': 'Norma [szt.]',
            'uwagi': 'Uwagi',
            'id_uzytkownika': 'Użytkownik'
        }
        self.proxy = QSortFilterProxyModel(self)
        self.parent = parent
        self.formularz = QGroupBox("Normy")
        self.lbl_w = QLabel("Wyszukaj")
        self.edit_w = QLineEdit(self)
        self.table = QTableView(self)
        self.btn_odswiez = QPushButton("Odśwież bazę")
        sciezka = czy_istnieje()
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(sciezka)
        if self.db.open():
            print('Otworzono bazę danych')
        self.model = QSqlRelationalTableModel(self, self.db)
        self.initUI()

    def initUI(self):
        # Zainicjowanie tabeli zawsze przed wszystkim
        self.tabela()

        # lista wybieralna
        with open('./resources/Maszyny i operacje.json', 'r',
                  encoding='utf-8') as file:
            plik_json = json.load(file)
        masz = plik_json['Maszyny']
        operacje = plik_json['Operacje']
        self.table.setItemDelegateForColumn(2, ComboDelegate(self, masz))
        self.table.setItemDelegateForColumn(6, ComboDelegate(self, operacje))
        for row in range(0, self.model.rowCount()):
            self.table.openPersistentEditor(self.model.index(row, 2))
            self.table.openPersistentEditor(self.model.index(row, 6))

        # Zatwierdzenie
        ok_button = QPushButton("Dodaj")
        cancel_button = QPushButton("Cofnij")
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(self.btn_odswiez)
        hbox.addWidget(ok_button)
        hbox.addWidget(cancel_button)

        # Layouty
        layout_v = QVBoxLayout()
        layout_h = QHBoxLayout()

        # Tabela
        self.proxy.setSourceModel(self.model)
        self.table.setModel(self.proxy)

        # przyporządkowanie
        layout_h.addWidget(self.lbl_w)
        layout_h.addWidget(self.edit_w)
        layout_v.addLayout(layout_h)
        layout_v.addWidget(self.table)
        self.formularz.setLayout(layout_v)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.formularz)
        main_layout.addLayout(hbox)
        self.setLayout(main_layout)

        # export
        # self.export()
        # Funkcje
        cancel_button.clicked.connect(self.anulowanie)
        ok_button.clicked.connect(self.dodaj)
        self.edit_w.textChanged.connect(self.wyszukiwanie)
        self.btn_odswiez.clicked.connect(self.refresh_db)
        self.skrot.activated.connect(self.refresh_db)
        # Menu kontekstowe własne
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.prawoklik)

    def prawoklik(self):
        menu = QMenu(self)
        if self.model.rowCount():
            akcja = QAction('Usuń wiersz', self)
            akcja.triggered.connect(self.usun_wiersz)
            menu.addAction(akcja)
            menu.exec_(QCursor.pos())

    def usun_wiersz(self):
        ok = QMessageBox.question(self, 'Potwierdzenie',
                                  'Czy na pewno chcesz usunąć pozycję?',
                                  QMessageBox.Ok, QMessageBox.Cancel)
        if ok == QMessageBox.Ok:
            selected = self.table.currentIndex()
            self.model.removeRow(selected.row())
            self.model.submitAll()
            self.model.select()

    @pyqtSlot(str)
    def wyszukiwanie(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)

    @pyqtSlot()
    def uzupelniene(self):
        # Pobranie tp, tm z bazy
        query = 'SELECT iddetale, tm, tp, ilosc_m, ilosc_szt FROM detale'
        dane_db = multipolaczenie(query)
        for i in range(len(dane_db)):
            # if dane_db[i][1] and dane_db[i][2]:
            tm = dane_db[i][1]
            tp1 = dane_db[i][2]
            ilosc_m = dane_db[i][3]
            ilosc_szt = dane_db[i][4]
            if not ilosc_m:
                ilosc_m = 1
                zm = 1
            else:
                zm = 0.95
            if not ilosc_szt:
                ilosc_szt = 1
            if isinstance(tm, int) and isinstance(tp1, int):
                tw = tm + tp1
            else:
                tw = 0
            tp2 = tw * 0.05
            tj = (tw + tp2) * 1.1
            tjh = tj / 3600

            if tj != 0:
                norma = 8 / tj * 3600 * ilosc_m * zm * ilosc_szt
            else:
                norma = 0
            print(round(norma))
            # update bazy
            query = 'UPDATE "detale" SET "tj" = ' + str(round(
                tjh, 5)) + ', "norma" = ' + str(
                    round(norma)) + ' WHERE "iddetale" = ' + str(dane_db[i][0])
            update_bazy(query)
            # query = 'UPDATE "detale" SET "norma" = ' + str(round(norma)) +
            # ' WHERE "iddetale" = ' + str(dane_db[i][0]) update_bazy(query)

    @pyqtSlot()
    def refresh_db(self):
        try:
            self.uzupelniene()
        except:
            pass
        # Odświeżenie tabeli
        self.model.select()

    def tabela(self):
        self.model.setTable('detale')
        self.model.setRelation(
            12, QSqlRelation('uzytkownicy', 'iduzytkownicy', 'nazwa_uz'))
        # Za zmianę w bazie odpowiada OnFieldChange
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)

        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal,
                                     self.naglowki[nazwa_kolumn])
        self.model.select()

        # Odpowiada za edycję pojednynczym kliknieciem
        '''
        Constant    Value   Description
        QAbstractItemView::NoEditTriggers   0   No editing possible.
        QAbstractItemView::CurrentChanged   1   Editing start whenever current item changes.
        QAbstractItemView::DoubleClicked    2   Editing starts when an item is double clicked.
        QAbstractItemView::SelectedClicked  4   Editing starts when clicking on an already selected item.
        QAbstractItemView::EditKeyPressed   8   Editing starts when the platform edit key has been pressed over an item.
        QAbstractItemView::AnyKeyPressed    16  Editing starts when any key is pressed over an item.
        QAbstractItemView::AllEditTriggers  31  Editing starts for all above actions.
        '''
        if self.odczyt():
            self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
        else:
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.resizeColumnsToContents()
        self.table.setModel(self.model)
        self.table.setAlternatingRowColors(True)
        self.table.resizeColumnsToContents()

        # self.table.doubleClicked.connect(self.klikniecie)

    def anulowanie(self):
        self.parent.statusBar().clearMessage()
        from opcje_qt import Wewnatrz
        menu_gl = Wewnatrz(self.parent)
        self.parent.setCentralWidget(menu_gl)

    def odczyt(self):
        id = str(self.parent.id_user[0])
        query = 'SELECT odczyt FROM uzytkownicy WHERE iduzytkownicy=' + id
        return polaczenie(query)[0]

    def dodaj(self):
        poz, masz, op, tm, tp, ok = MultiDialog().getMultidialog(self)
        print(poz, masz, op, tm, tp, ok)
        id = self.parent.id_user[0]
        if ok and poz:
            query = "INSERT INTO detale(nr_detalu,maszyna,nazwa_op,tm,tp," \
                    "id_uzytkownika) VALUES ('" + poz + "','" + masz + "','" + op + "','" + tm + "','" + tp + "','" + str(
                id) + "');"
            print(query)
            polaczenie(query)
            if tm and tp:
                try:
                    self.uzupelniene()
                except:
                    pass
            self.model.select()
            self.parent.statusBar().showMessage("Dodano nową pozycję", 10000)
        else:
            print("Nie wpisano pozycji")
Exemple #19
0
class Window(QMainWindow):
    """Main Window."""

    def __init__(self, parent=None):
        """Initializer."""
        super().__init__(parent)
        self.setWindowTitle("RP Contacts")
        self.resize(550, 250)
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.layout = QHBoxLayout()
        self.centralWidget.setLayout(self.layout)

        self.contactsModel = ContactsModel()
        self.setupUI()

    def setupUI(self):
        """Setup the main window's GUI."""
        # Create the table view widget
        self.table = QTableView()
        self.table.setModel(self.contactsModel.model)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.resizeColumnsToContents()
        # Create buttons
        self.addButton = QPushButton("Add...")
        self.addButton.clicked.connect(self.openAddDialog)
        self.deleteButton = QPushButton("Delete")
        self.deleteButton.clicked.connect(self.deleteContact)
        self.clearAllButton = QPushButton("Clear All")
        self.clearAllButton.clicked.connect(self.clearContacts)
        # Lay out the GUI
        layout = QVBoxLayout()
        layout.addWidget(self.addButton)
        layout.addWidget(self.deleteButton)
        layout.addStretch()
        layout.addWidget(self.clearAllButton)
        self.layout.addWidget(self.table)
        self.layout.addLayout(layout)

    def openAddDialog(self):
        """Open the Add Contact dialog."""
        dialog = AddDialog(self)
        if dialog.exec() == QDialog.Accepted:
            self.contactsModel.addContact(dialog.data)
            self.table.resizeColumnsToContents()

    def deleteContact(self):
        """Delete the selected contact from the database."""
        row = self.table.currentIndex().row()
        if row < 0:
            return

        messageBox = QMessageBox.warning(
            self,
            "Warning!",
            "Do you want to remove the selected contact?",
            QMessageBox.Ok | QMessageBox.Cancel,
        )

        if messageBox == QMessageBox.Ok:
            self.contactsModel.deleteContact(row)

    def clearContacts(self):
        """Remove all contacts from the database."""
        messageBox = QMessageBox.warning(
            self,
            "Warning!",
            "Do you want to remove all your contacts?",
            QMessageBox.Ok | QMessageBox.Cancel,
        )

        if messageBox == QMessageBox.Ok:
            self.contactsModel.clearContacts()
Exemple #20
0
class Window(QMainWindow):
    """Ventana Principal."""
    def __init__(self, parent=None):
        """Inicializador."""
        super().__init__(parent)
        self.setWindowTitle("Database de Contactos 2021")
        self.resize(550, 250)
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.layout = QHBoxLayout()
        self.centralWidget.setLayout(self.layout)

        self.contactsModel = ContactsModel()
        self.setupUI()

    def setupUI(self):
        """Setup la GUI de la ventana principal."""
        # Crear la table view widget
        self.table = QTableView()
        self.table.setModel(self.contactsModel.model)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.resizeColumnsToContents()
        # Crear botones
        self.addButton = QPushButton("Añadir...")
        self.addButton.clicked.connect(self.openAddDialog)
        self.deleteButton = QPushButton("Borrar")
        self.deleteButton.clicked.connect(self.deleteContact)
        self.clearAllButton = QPushButton("Borrar Todo")
        self.clearAllButton.clicked.connect(self.clearContacts)
        # Extender la GUI
        layout = QVBoxLayout()
        layout.addWidget(self.addButton)
        layout.addWidget(self.deleteButton)
        layout.addStretch()
        layout.addWidget(self.clearAllButton)
        self.layout.addWidget(self.table)
        self.layout.addLayout(layout)

    def openAddDialog(self):
        """Abrir el cuadro de dialogo de "Agregar contacto"."""
        dialog = AddDialog(self)
        if dialog.exec() == QDialog.Accepted:
            self.contactsModel.addContact(dialog.data)
            self.table.resizeColumnsToContents()

    def deleteContact(self):
        """Eliminar el contacto seleccionado de la base de datos."""
        row = self.table.currentIndex().row()
        if row < 0:
            return

        messageBox = QMessageBox.warning(
            self,
            "¡Cuidado!",
            "¿Deseas remover el contacto seleccionado?",
            QMessageBox.Ok | QMessageBox.Cancel,
        )

        if messageBox == QMessageBox.Ok:
            self.contactsModel.deleteContact(row)

    def clearContacts(self):
        """Remover todos los contactos de la base de datos."""
        messageBox = QMessageBox.warning(
            self,
            "¡Cuidado!",
            "¿Deseas remover todos los contactos seleccionados?",
            QMessageBox.Ok | QMessageBox.Cancel,
        )

        if messageBox == QMessageBox.Ok:
            self.contactsModel.clearContacts()
Exemple #21
0
class RecordsViewer(QDialog):
    def __init__(self):
        super(RecordsViewer, self).__init__()
        self.resize(800, 500)
        self.setWindowTitle('myOCR——我的识别历史')
        self.setWindowIcon(QIcon('./images/icon.png'))
        self.queryModel = None
        self.tableView = None
        self.currentPage = 0
        self.totalPage = 0
        self.totalRecord = 0
        self.pageRecord = 10
        self.initUI()

    def initUI(self):
        self.vbox = QVBoxLayout()
        self.h1box = QHBoxLayout()
        self.h2box = QHBoxLayout()

        self.searchEdit = QLineEdit()
        self.searchEdit.setFixedHeight(32)
        self.searchEdit.setFont(QFont("苏新诗柳楷繁", 15))

        self.searchButton = QPushButton("查询")
        self.searchButton.setFixedHeight(32)
        self.searchButton.setFont(QFont("苏新诗柳楷繁", 15))

        self.condisionComboBox = QComboBox()
        searchCondision = ['按识别编号查询', '按识别时间查询', '按识别类型查询', '按识别文字查询']
        self.condisionComboBox.setFixedHeight(32)
        self.condisionComboBox.setFont(QFont("苏新诗柳楷繁", 15))
        self.condisionComboBox.addItems(searchCondision)

        self.h1box.addWidget(self.searchEdit)
        self.h1box.addWidget(self.condisionComboBox)
        self.h1box.addWidget(self.searchButton)

        self.jumpToLabel = QLabel(self)
        self.jumpToLabel.setText("跳转到第")
        self.jumpToLabel.setFont(QFont("苏新诗柳楷繁", 12))
        self.jumpToLabel.setFixedWidth(90)
        self.pageEdit = QLineEdit()
        self.pageEdit.setFixedWidth(30)
        self.pageEdit.setFont(QFont("苏新诗柳楷繁", 12))
        s = "/" + str(self.totalPage) + "页"
        self.pageLabel = QLabel(s)
        self.pageLabel.setFont(QFont("苏新诗柳楷繁", 12))
        self.pageLabel.setFixedWidth(40)
        self.jumpToButton = QPushButton(self)
        self.jumpToButton.setText("跳转")
        self.jumpToButton.setFont(QFont("苏新诗柳楷繁", 12))
        self.jumpToButton.setFixedHeight(30)
        self.jumpToButton.setFixedWidth(60)
        self.prevButton = QPushButton("前一页")
        self.prevButton.setFont(QFont("苏新诗柳楷繁", 12))
        self.prevButton.setFixedHeight(30)
        self.prevButton.setFixedWidth(80)
        self.backButton = QPushButton("后一页")
        self.backButton.setFont(QFont("苏新诗柳楷繁", 12))
        self.backButton.setFixedHeight(30)
        self.backButton.setFixedWidth(80)

        self.detailbutton = QPushButton(self)
        self.detailbutton.setText("详细信息")
        self.detailbutton.setFixedWidth(90)
        self.detailbutton.setFont(QFont("苏新诗柳楷繁", 12))
        self.detailbutton.clicked.connect(self.detailInfo)

        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.jumpToLabel)
        self.hbox.addWidget(self.pageEdit)
        self.hbox.addWidget(self.pageLabel)
        self.hbox.addWidget(self.jumpToButton)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.detailbutton)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.prevButton)
        self.hbox.addWidget(self.backButton)
        widget = QWidget()
        widget.setLayout(self.hbox)
        widget.setFixedWidth(600)
        self.h2box.addWidget(widget)

        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName('./db/myOCR.db')
        self.db.open()
        self.tableView = QTableView()
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.setFont(QFont("苏新诗柳楷繁", 12))
        self.tableView.horizontalHeader().setFont(QFont("苏新诗柳楷繁", 12))
        self.queryModel = QSqlQueryModel()
        self.searchButtonClicked()
        self.tableView.setModel(self.queryModel)

        self.queryModel.setHeaderData(0, Qt.Horizontal, "识别编号")
        self.queryModel.setHeaderData(1, Qt.Horizontal, "识别时间")
        self.queryModel.setHeaderData(2, Qt.Horizontal, "识别类型")
        self.queryModel.setHeaderData(3, Qt.Horizontal, "识别文字")

        self.vbox.addLayout(self.h1box)
        self.vbox.addWidget(self.tableView)
        self.vbox.addLayout(self.h2box)
        self.setLayout(self.vbox)
        self.searchButton.clicked.connect(self.searchButtonClicked)
        self.prevButton.clicked.connect(self.prevButtonClicked)
        self.backButton.clicked.connect(self.backButtonClicked)
        self.jumpToButton.clicked.connect(self.jumpToButtonClicked)
        self.searchEdit.returnPressed.connect(self.searchButtonClicked)

    def setButtonStatus(self):
        if (self.currentPage == self.totalPage):
            self.prevButton.setEnabled(True)
            self.backButton.setEnabled(False)
        if (self.currentPage == 1):
            self.backButton.setEnabled(True)
            self.prevButton.setEnabled(False)
        if (self.currentPage < self.totalPage and self.currentPage > 1):
            self.prevButton.setEnabled(True)
            self.backButton.setEnabled(True)

    def getTotalRecordCount(self):
        self.queryModel.setQuery(
            "select RecordId,RecordTime,RecordType,RecordText from records")
        self.totalRecord = self.queryModel.rowCount()
        return

    def getPageCount(self):
        self.getTotalRecordCount()
        self.totalPage = int(
            (self.totalRecord + self.pageRecord - 1) / self.pageRecord)
        return

    def recordQuery(self, index):
        conditionChoice = self.condisionComboBox.currentText()
        if (conditionChoice == "按识别编号查询"):
            conditionChoice = 'RecordId'
        elif (conditionChoice == "按识别时间查询"):
            conditionChoice = 'RecordTime'
        elif (conditionChoice == "按识别类型查询"):
            conditionChoice = 'RecordType'
        else:
            conditionChoice = 'RecordText'

        if (self.searchEdit.text() == ""):
            queryCondition = "select RecordId,RecordTime,RecordType,RecordText from records order by RecordTime DESC"
            self.queryModel.setQuery(queryCondition)
            self.totalRecord = self.queryModel.rowCount()
            self.totalPage = int(
                (self.totalRecord + self.pageRecord - 1) / self.pageRecord)
            label = "/" + str(int(self.totalPage)) + "页"
            self.pageLabel.setText(label)
            queryCondition = (
                "select RecordId,RecordTime,RecordType,RecordText from records order by %s desc limit %d,%d "
                % (conditionChoice, index, self.pageRecord))
            self.queryModel.setQuery(queryCondition)
            self.setButtonStatus()
            return

        temp = self.searchEdit.text()
        s = '%'
        for i in range(0, len(temp)):
            s = s + temp[i] + "%"
        queryCondition = (
            "select RecordId,RecordTime,RecordType,RecordText from records where %s like '%s' order by %s desc"
            % (conditionChoice, s, conditionChoice))
        self.queryModel.setQuery(queryCondition)
        self.totalRecord = self.queryModel.rowCount()
        if (self.totalRecord == 0):
            print(
                QMessageBox.information(self, "提醒", "查询无记录", QMessageBox.Yes,
                                        QMessageBox.Yes))
            queryCondition = "select RecordId,RecordTime,RecordType,RecordText from records order by RecordTime DESC"
            self.queryModel.setQuery(queryCondition)
            self.totalRecord = self.queryModel.rowCount()
            self.totalPage = int(
                (self.totalRecord + self.pageRecord - 1) / self.pageRecord)
            label = "/" + str(int(self.totalPage)) + "页"
            self.pageLabel.setText(label)
            queryCondition = (
                "select RecordId,RecordTime,RecordType,RecordText from records order by %s desc limit %d,%d "
                % (conditionChoice, index, self.pageRecord))
            self.queryModel.setQuery(queryCondition)
            self.setButtonStatus()
            return
        self.totalPage = int(
            (self.totalRecord + self.pageRecord - 1) / self.pageRecord)
        label = "/" + str(int(self.totalPage)) + "页"
        self.pageLabel.setText(label)
        queryCondition = (
            "select RecordId,RecordTime,RecordType,RecordText from records where %s like '%s' order by %s desc limit %d,%d "
            % (conditionChoice, s, conditionChoice, index, self.pageRecord))
        self.queryModel.setQuery(queryCondition)
        self.setButtonStatus()
        return

    def searchButtonClicked(self):
        self.currentPage = 1
        self.pageEdit.setText(str(self.currentPage))
        self.getPageCount()
        s = "/" + str(int(self.totalPage)) + "页"
        self.pageLabel.setText(s)
        index = (self.currentPage - 1) * self.pageRecord
        self.recordQuery(index)
        return

    def prevButtonClicked(self):
        self.currentPage -= 1
        if (self.currentPage <= 1):
            self.currentPage = 1
        self.pageEdit.setText(str(self.currentPage))
        index = (self.currentPage - 1) * self.pageRecord
        self.recordQuery(index)
        return

    def backButtonClicked(self):
        self.currentPage += 1
        if (self.currentPage >= int(self.totalPage)):
            self.currentPage = int(self.totalPage)
        self.pageEdit.setText(str(self.currentPage))
        index = (self.currentPage - 1) * self.pageRecord
        self.recordQuery(index)
        return

    def jumpToButtonClicked(self):
        if (self.pageEdit.text().isdigit()):
            self.currentPage = int(self.pageEdit.text())
            if (self.currentPage > self.totalPage):
                self.currentPage = self.totalPage
            if (self.currentPage <= 1):
                self.currentPage = 1
        else:
            self.currentPage = 1
        index = (self.currentPage - 1) * self.pageRecord
        self.pageEdit.setText(str(self.currentPage))
        self.recordQuery(index)
        return

    def detailInfo(self):
        index_ = self.tableView.currentIndex().row()
        if (index_ == -1):
            print(
                QMessageBox.warning(self, "警告", "您没有选中任何记录", QMessageBox.Yes,
                                    QMessageBox.Yes))
            return
        else:
            str = self.queryModel.data(self.queryModel.index(index_, 0))
            type = self.queryModel.data(self.queryModel.index(index_, 2))
            if (type == '身份证识别'):
                self.recordDetail_id(str)
            else:
                self.recordDetail(str)

    def recordDetail(self, RecordId):
        recorddetaildialog = RecordDetailDialog(RecordId)
        recorddetaildialog.show()
        recorddetaildialog.exec_()

    def recordDetail_id(self, RecordId):
        recorddetail_id = RecordDetailDialog_id(RecordId)
        recorddetail_id.show()
        recorddetail_id.exec_()
Exemple #22
0
class SudokuMainWindow(QWidget):
    def __init__(self, model):
        super().__init__()

        self.model = model
        self.init_ui()

    def init_ui(self):

        # create table view
        self.sudoku_view = QTableView(self)
        self.sudoku_view.setModel(self.model)
        self.sudoku_view.verticalHeader().hide()
        self.sudoku_view.horizontalHeader().hide()
        self.sudoku_view.setFont(QFont("Times", 20))
        # self.sudoku_view.setFocusPolicy(Qt.NoFocus)

        # change palette - to change highlighting color
        palette = self.sudoku_view.palette()
        palette.setBrush(QPalette.Highlight, QBrush(Qt.lightGray))
        self.sudoku_view.setPalette(palette)

        # resize the
        for col in range(9):
            self.sudoku_view.setColumnWidth(col, 90)

        for row in range(9):
            self.sudoku_view.setRowHeight(row, 90)

        # # create tablewidget to act as grid lines
        # self.grid_lines = QTableWidget(3, 3, self)

        # create clear button
        self.clear_btn = QPushButton('Clear')
        self.clear_btn.setToolTip("clear the board and reset the puzzle")

        # create solve button
        self.solve_btn = QPushButton('Solve')
        self.solve_btn.setToolTip("solve the puzzle for me")

        # create how am I doing? button
        self.progress_btn = QPushButton('How Am I Doing')
        self.progress_btn.setToolTip("highlight mistakes")
        self.progress_highlight = False

        # create new board button
        self.get_new_board_btn = QPushButton('Get New Board')
        self.get_new_board_btn.setToolTip("gets you a new board")

        # create how am I doing? button
        # hide_progress_btn = QPushButton('Clear Highlights')
        # hide_progress_btn.setToolTip("clear highlighted mistakes")

        # connect buttons to slots
        self.clear_btn.clicked.connect(self.clear_board)
        self.solve_btn.clicked.connect(self.solve_board)
        self.progress_btn.clicked.connect(self.show_progress)
        self.get_new_board_btn.clicked.connect(self.get_new_board)

        # create layout for buttons, and add them
        self.hbox = QHBoxLayout()
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.progress_btn)
        self.hbox.addWidget(self.clear_btn)
        self.hbox.addWidget(self.solve_btn)
        self.hbox.addWidget(self.get_new_board_btn)
        self.hbox.addStretch(1)

        # create layout to hold sudoku view, and
        self.vbox = QVBoxLayout()
        self.vbox.addWidget(self.sudoku_view)
        self.vbox.addLayout(self.hbox)

        # set the layout, and set the window title, size, and trigger show()
        self.setLayout(self.vbox)
        self.setFixedSize(860, 915)
        self.setWindowTitle("Sudoku")
        self.show()

    def show_progress(self):
        index = self.sudoku_view.currentIndex()
        if self.progress_highlight == True:
            self.progress_highlight = False
            self.progress_btn.setText("How Am I Doing")
            self.progress_btn.setToolTip("highlight mistakes")
        else:
            self.progress_highlight = True
            self.progress_btn.setText("Hide Highlights")
            self.progress_btn.setToolTip("hide highlighted mistakes")
        self.model.set_highlight_mistakes()
        self.model.setData(index, value=QVariant(), role=Qt.BackgroundRole)
        self.update()

    def clear_board(self):
        index = self.sudoku_view.currentIndex()
        self.model.setData(index, value=QVariant, role=Qt.UserRole)

    def solve_board(self):
        index = self.sudoku_view.currentIndex()
        self.model.setData(index, value=QVariant(), role=Qt.UserRole + 1)

    def get_new_board(self):
        index = self.sudoku_view.currentIndex()
        self.model.setData(index, value=QVariant(), role=Qt.UserRole + 2)
class Crud(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.name = QLabel('Название', self)
        self.nameEdit = QLineEdit(self)
        self.name.move(700, 10)
        self.nameEdit.setGeometry(700, 30, 250, 25)

        self.price = QLabel('Цена', self)
        self.priceEdit = QLineEdit(self)
        self.price.move(700, 70)
        self.priceEdit.setGeometry(700, 90, 250, 25)

        self.link = QLabel('Ссылка на страницу', self)
        self.linkEdit = QLineEdit(self)
        self.link.move(700, 130)
        self.linkEdit.setGeometry(700, 150, 250, 25)

        self.notation = QLabel('Примечание', self)
        self.notationEdit = QLineEdit(self)
        self.notation.move(700, 190)
        self.notationEdit.setGeometry(700, 210, 250, 25)

        self.btn_add = QPushButton('Создать', self)
        self.btn_add.move(700, 250)
        self.btn_update = QPushButton('Обновить', self)
        self.btn_update.move(785, 250)
        self.btn_delete = QPushButton('Удалить', self)
        self.btn_delete.move(870, 250)

        self.table = QTableView(self)

        # Данные для подключения к БД
        self.db = QtSql.QSqlDatabase.addDatabase('QMYSQL')
        self.db.setHostName('localhost')
        self.db.setDatabaseName('DBvishlist')
        self.db.setUserName('user')
        self.db.setPassword('pass')

        self.model = QtSql.QSqlTableModel()
        self.model.setTable('vishlist')
        self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
        self.model.select()
        self.table.setModel(self.model)

        self.table.resize(685, 530)
        self.table.setColumnWidth(0, 33)
        self.table.setColumnWidth(1, 150)
        self.table.setColumnWidth(2, 100)
        self.table.setColumnWidth(3, 180)
        self.table.setColumnWidth(4, 180)

        self.setFixedSize(960, 550)
        self.setGeometry(300, 300, 960, 600)
        self.show()

        self.btn_add.clicked.connect(self.addToDb)
        self.btn_update.clicked.connect(self.updaterow)
        self.btn_delete.clicked.connect(self.delrow)

        self.i = self.model.rowCount()

    def addToDb(self):

        self.model.insertRows(self.i, 1)
        self.model.setData(self.model.index(self.i, 1), self.nameEdit.text())
        self.model.setData(self.model.index(self.i, 2), self.priceEdit.text())
        self.model.setData(self.model.index(self.i, 3), self.linkEdit.text())
        self.model.setData(self.model.index(self.i, 4),
                           self.notationEdit.text())
        self.model.submitAll()
        self.i += 1

    def delrow(self):

        if self.table.currentIndex().row() > -1:
            self.model.removeRow(self.table.currentIndex().row())
            self.i -= 1
            self.model.select()
        else:
            QMessageBox.question(self, 'Message',
                                 "Выберите строку для удаления",
                                 QMessageBox.Ok)
            self.show()

    def updaterow(self):

        if self.table.currentIndex().row() > -1:
            record = self.model.record(self.table.currentIndex().row())
            record.setValue("Название", self.nameEdit.text())
            record.setValue("Цена", self.priceEdit.text())
            record.setValue("Ссылка", self.linkEdit.text())
            record.setValue("Примечание", self.notationEdit.text())
            self.model.setRecord(self.table.currentIndex().row(), record)
        else:
            QMessageBox.question(self, 'Message',
                                 "Выберите строку для обновления",
                                 QMessageBox.Ok)
            self.show()
Exemple #24
0
class TableDemo(QWidget):
    def __init__(self, parent=None):
        super(TableDemo, self).__init__(parent)
        self.setWindowTitle('TableView Demo')
        self.resize(600, 500)

        modelVerticalTitleLabelList = ['A', 'B', 'C', 'D', 'E']
        modelHorizontalTitleLabelList = ['甲', '乙', '丙', '丁', '戊', '已']

        self.model = QStandardItemModel(5, 5)
        self.model.setHorizontalHeaderLabels(modelVerticalTitleLabelList)
        self.model.setVerticalHeaderLabels(modelHorizontalTitleLabelList)
        for i in range(5):
            for j in range(5):
                item = QStandardItem(str(i + j))
                self.model.setItem(i, j, item)

        self.tabletView = QTableView()
        self.tabletView.setModel(self.model)

        self.tabletView.horizontalHeader().setStretchLastSection(True)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.tabletView)

        self.testRowColumn()

        self.setLayout(mainLayout)

    def testRowColumn(self):
        # 用rowAt()和columnAt(),返回一个坐标在table中的行和列的序号
        x, y = 100, 200
        row_at_x = self.tabletView.rowAt(x)
        column_at_y = self.tabletView.columnAt(y)
        print('坐标(%d,%d)在表格中是第%d行,第%d列' %
              (x, y, row_at_x + 1, column_at_y + 1))
        # 如果(x,y)不在表格内,函数返回值是-1

        # setRowHeight,setColumnWidth:可以设置行高'列宽
        self.tabletView.setRowHeight(1, 50)
        self.tabletView.setColumnWidth(1, 150)
        # <int> columnWidth():返回指定列的宽度
        # <int> rowHeight():返回指定行的高度
        print('第(2,2)单元格的列宽,行高为为:%d,%d(像素)' %
              (self.tabletView.columnWidth(1), self.tabletView.rowHeight(1)))

        # setSpan():设定指定行和列的行跨度和列跨度
        self.tabletView.setSpan(2, 2, 2, 2)
        # <int> rowSpan():返回指定行的位置的行跨度
        # <int> columnSpan:返回指定(row,column)的列跨度
        print(
            '第(3,3)单元格的的行和列跨度为(%dx%d)' %
            (self.tabletView.columnSpan(2, 2), self.tabletView.rowSpan(2, 2)))

        # setCornerButtonEnable():设置是否启用左上角的按钮
        # 此按钮(用来全选整个表格),默认是启用的
        self.tabletView.setCornerButtonEnabled(False)  # 此时,左上角的按钮将不再起作用

    def contextMenuEvent(self, QContextMenuEvent):
        # 设置tableView的右键弹出菜单和菜单信号槽
        # 如何只在单元格内弹出右键菜单呢?现在在空白地方点击右键也会弹出菜单????????
        menu = QMenu(self)
        hideMenu = menu.addAction('&Hide')
        hideMenu.triggered.connect(self.hideCurrentColumn)

        # 设置显示所有被隐藏的列
        showhiddenColumnMenu = menu.addAction('显示隐藏列')
        showhiddenColumnMenu.triggered.connect(self.showAllHiddenColumns)

        menu.addSeparator()

        # 设置当前点击的列按照内容自适应列宽度
        resizeColumnToCtnsMenu = menu.addAction('宽度适应')
        resizeColumnToCtnsMenu.triggered.connect(
            lambda: self.tabletView.resizeColumnToContents(
                self.tabletView.currentIndex().column()))

        # 排序当前选择的列
        orderCurentColumnMenu = menu.addAction('排序')
        orderCurentColumnMenu.triggered.connect(self.orderCurrentColum)

        menu.exec_(QContextMenuEvent.globalPos())

    def hideCurrentColumn(self):
        print('第%d列被隐藏了!' % self.tabletView.currentIndex().column())
        self.tabletView.setColumnHidden(
            self.tabletView.currentIndex().column(), True)

    def showAllHiddenColumns(self):
        print('显示所有被隐藏的列')
        # 遍历所有的列,找到隐藏的列,设置其隐藏为False
        for i in range(self.model.columnCount()):
            if self.tabletView.isColumnHidden(i):
                self.tabletView.setColumnHidden(i, False)
                print('列%d已被重新显示' % (i + 1))

    def orderCurrentColum(self):
        self.tabletView.setSortingEnabled(True)
        self.tabletView.sortByColumn(self.tabletView.currentIndex().column(),
                                     Qt.AscendingOrder)
Exemple #25
0
class Materials(QWidget):

    def __init__(self):
        super().__init__()

        self.initUi()

    def initUi(self):
        self.setObjectName("Main window")
        self.resize(370, 300)
        self.setWindowTitle("Материалы")
        self.btn_add = QPushButton(self)
        self.btn_add.setObjectName("btn_add")
        self.btn_add.setText("Добавить")
        self.btn_delete = QPushButton(self)
        self.btn_delete.setObjectName("btn_delete")
        self.btn_delete.setText("Удалить")
        self.btn_exit = QPushButton(self)
        self.btn_exit.setObjectName("btn_exit")
        self.btn_exit.setText("Выход")
        self.btn_refresh = QPushButton(self)
        self.btn_refresh.setText("Обновить")
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName('ocenka.db')
        self.db.open()
        self.model = QSqlRelationalTableModel(self)
        self.model.setTable("v_materials")
        self.model.setEditStrategy(QSqlRelationalTableModel.OnFieldChange)
        self.model.setJoinMode(QSqlRelationalTableModel.LeftJoin)
        self.model.setHeaderData(0, Qt.Horizontal, "Идентификатор")
        self.model.setHeaderData(1, Qt.Horizontal, "Наименование")
        self.model.setHeaderData(2, Qt.Horizontal, "Ед.изм.")
        self.model.setHeaderData(3, Qt.Horizontal, "Количество")
        self.model.setHeaderData(4, Qt.Horizontal, "Стоимость")
        self.model.setHeaderData(5, Qt.Horizontal, "Сумма")
        self.model.setHeaderData(6, Qt.Horizontal, "Выбрать")
        #self.proxyModel = QSortFilterProxyModel(self)
        #self.proxyModel.setSourceModel(self.model)
        self.view = QTableView(self)
        
        self.view.setSortingEnabled(True)
        self.view.setModel(self.model)
        self.view.resizeColumnsToContents()
        self.view.hideColumn(0)
        self.view.horizontalHeader().setStretchLastSection(True)
        #self.view.hideColumn(1)
        self.view.setItemDelegate(QSqlRelationalDelegate(self.model))
        self.model.select()
        

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.btn_add)
        self.layout.addWidget(self.btn_delete)
        self.layout.addWidget(self.btn_exit)
        self.layout.addWidget(self.btn_refresh)
        vlayout = QVBoxLayout()
        vlayout.addWidget(self.view)
        vlayout.addLayout(self.layout)
        self.setLayout(vlayout)
        self.show()

        self.view.clicked.connect(self.findrow)
        self.btn_add.clicked.connect(self.addrow)
        self.btn_delete.clicked.connect(lambda: self.model.removeRow(self.view.currentIndex().row()))
        self.btn_exit.clicked.connect(self.close_event)
        self.btn_refresh.clicked.connect(lambda: self.model.select())

    def close_database(self):
        self.view.setModel(None)
        del self.model
        self.db.close()
        del self.db
        QSqlDatabase.removeDatabase('ocenka.db')
        self.close()

    def close_event(self, event):
        self.close_database()            
       

    def findrow(self, i):
        delrow = i.row()

    def addrow(self):
        print(self.model.rowCount())
        ret = self.model.insertRows(self.model.rowCount(), 1)
        return ret
class comic_meta_data_editor(QDialog):
    configGroup = "ComicsProjectManagementTools"

    # Translatable genre dictionary that has it's translated entries added to the genrelist and from which the untranslated items are taken.
    acbfGenreList = {"science_fiction": str(i18n("Science Fiction")), "fantasy": str(i18n("Fantasy")), "adventure": str(i18n("Adventure")), "horror": str(i18n("Horror")), "mystery": str(i18n("Mystery")), "crime": str(i18n("Crime")), "military": str(i18n("Military")), "real_life": str(i18n("Real Life")), "superhero": str(i18n("Superhero")), "humor": str(i18n("Humor")), "western": str(i18n("Western")), "manga": str(i18n("Manga")), "politics": str(i18n("Politics")), "caricature": str(i18n("Caricature")), "sports": str(i18n("Sports")), "history": str(i18n("History")), "biography": str(i18n("Biography")), "education": str(i18n("Education")), "computer": str(i18n("Computer")), "religion": str(i18n("Religion")), "romance": str(i18n("Romance")), "children": str(i18n("Children")), "non-fiction": str(i18n("Non Fiction")), "adult": str(i18n("Adult")), "alternative": str(i18n("Alternative")), "artbook": str(i18n("Artbook")), "other": str(i18n("Other"))}
    acbfAuthorRolesList = {"Writer": str(i18n("Writer")), "Adapter": str(i18n("Adapter")), "Artist": str(i18n("Artist")), "Penciller": str(i18n("Penciller")), "Inker": str(i18n("Inker")), "Colorist": str(i18n("Colorist")), "Letterer": str(i18n("Letterer")), "Cover Artist": str(i18n("Cover Artist")), "Photographer": str(i18n("Photographer")), "Editor": str(i18n("Editor")), "Assistant Editor": str(i18n("Assistant Editor")), "Designer": str(i18n("Designer")), "Translator": str(i18n("Translator")), "Other": str(i18n("Other"))}

    def __init__(self):
        super().__init__()
        # Get the keys for the autocompletion.
        self.genreKeysList = []
        self.characterKeysList = []
        self.ratingKeysList = {}
        self.formatKeysList = []
        self.otherKeysList = []
        self.authorRoleList = []
        for g in self.acbfGenreList.values():
            self.genreKeysList.append(g)
        for r in self.acbfAuthorRolesList.values():
            self.authorRoleList.append(r)
        mainP = Path(os.path.abspath(__file__)).parent
        self.get_auto_completion_keys(mainP)
        extraKeyP = Path(QDir.homePath()) / Application.readSetting(self.configGroup, "extraKeysLocation", str())
        self.get_auto_completion_keys(extraKeyP)

        # Setup the dialog.
        self.setLayout(QVBoxLayout())
        mainWidget = QTabWidget()
        self.layout().addWidget(mainWidget)
        self.setWindowTitle(i18n("Comic Metadata"))
        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.layout().addWidget(buttons)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)

        # Title, concept, summary, genre, characters, format, rating, language, series, other keywords
        metadataPage = QWidget()
        mformLayout = QFormLayout()
        metadataPage.setLayout(mformLayout)

        self.lnTitle = QLineEdit()
        self.lnTitle.setToolTip(i18n("The proper title of the comic."))

        self.teSummary = QPlainTextEdit()
        self.teSummary.setToolTip(i18n("What will you tell others to entice them to read your comic?"))

        self.lnGenre = QLineEdit()
        genreCompletion = multi_entry_completer()
        genreCompletion.setModel(QStringListModel(self.genreKeysList))
        self.lnGenre.setCompleter(genreCompletion)
        genreCompletion.setCaseSensitivity(False)
        self.lnGenre.setToolTip(i18n("The genre of the work. Prefilled values are from the ACBF, but you can fill in your own. Separate genres with commas. Try to limit the amount to about two or three."))

        self.lnCharacters = QLineEdit()
        characterCompletion = multi_entry_completer()
        characterCompletion.setModel(QStringListModel(self.characterKeysList))
        characterCompletion.setCaseSensitivity(False)
        characterCompletion.setFilterMode(Qt.MatchContains)  # So that if there is a list of names with last names, people can type in a last name.
        self.lnCharacters.setCompleter(characterCompletion)
        self.lnCharacters.setToolTip(i18n("The names of the characters that this comic revolves around. Comma-separated."))

        self.lnFormat = QLineEdit()
        formatCompletion = multi_entry_completer()
        formatCompletion.setModel(QStringListModel(self.formatKeysList))
        formatCompletion.setCaseSensitivity(False)
        self.lnFormat.setCompleter(formatCompletion)

        ratingLayout = QHBoxLayout()
        self.cmbRatingSystem = QComboBox()
        self.cmbRatingSystem.addItems(self.ratingKeysList.keys())
        self.cmbRatingSystem.setEditable(True)
        self.cmbRating = QComboBox()
        self.cmbRating.setEditable(True)
        self.cmbRatingSystem.currentIndexChanged.connect(self.slot_refill_ratings)
        ratingLayout.addWidget(self.cmbRatingSystem)
        ratingLayout.addWidget(self.cmbRating)

        self.lnSeriesName = QLineEdit()
        self.lnSeriesName.setToolTip(i18n("If this is part of a series, enter the name of the series and the number."))
        self.spnSeriesNumber = QSpinBox()
        self.spnSeriesNumber.setPrefix(i18n("No. "))
        self.spnSeriesVol = QSpinBox()
        self.spnSeriesVol.setPrefix(i18n("Vol. "))
        seriesLayout = QHBoxLayout()
        seriesLayout.addWidget(self.lnSeriesName)
        seriesLayout.addWidget(self.spnSeriesVol)
        seriesLayout.addWidget(self.spnSeriesNumber)

        otherCompletion = multi_entry_completer()
        otherCompletion.setModel(QStringListModel(self.otherKeysList))
        otherCompletion.setCaseSensitivity(False)
        otherCompletion.setFilterMode(Qt.MatchContains)
        self.lnOtherKeywords = QLineEdit()
        self.lnOtherKeywords.setCompleter(otherCompletion)
        self.lnOtherKeywords.setToolTip(i18n("Other keywords that do not fit in the previously mentioned sets. As always, comma-separated."))

        self.cmbLanguage = language_combo_box()
        self.cmbCountry = country_combo_box()
        self.cmbLanguage.currentIndexChanged.connect(self.slot_update_countries)
        self.cmbReadingMode = QComboBox()
        self.cmbReadingMode.addItem(i18n("Left to Right"))
        self.cmbReadingMode.addItem(i18n("Right to Left"))

        self.cmbCoverPage = QComboBox()
        self.cmbCoverPage.setToolTip(i18n("Which page is the cover page? This will be empty if there are no pages."))

        mformLayout.addRow(i18n("Title:"), self.lnTitle)
        mformLayout.addRow(i18n("Cover page:"), self.cmbCoverPage)
        mformLayout.addRow(i18n("Summary:"), self.teSummary)
        mformLayout.addRow(i18n("Language:"), self.cmbLanguage)
        mformLayout.addRow("", self.cmbCountry)
        mformLayout.addRow(i18n("Reading direction:"), self.cmbReadingMode)
        mformLayout.addRow(i18n("Genre:"), self.lnGenre)
        mformLayout.addRow(i18n("Characters:"), self.lnCharacters)
        mformLayout.addRow(i18n("Format:"), self.lnFormat)
        mformLayout.addRow(i18n("Rating:"), ratingLayout)
        mformLayout.addRow(i18n("Series:"), seriesLayout)
        mformLayout.addRow(i18n("Other:"), self.lnOtherKeywords)

        mainWidget.addTab(metadataPage, i18n("Work"))

        # The page for the authors.
        authorPage = QWidget()
        authorPage.setLayout(QVBoxLayout())
        explanation = QLabel(i18n("The following is a table of the authors that contributed to this comic. You can set their nickname, proper names (first, middle, last), role (penciller, inker, etc), email and homepage."))
        explanation.setWordWrap(True)
        self.authorModel = QStandardItemModel(0, 8)
        labels = [i18n("Nick Name"), i18n("Given Name"), i18n("Middle Name"), i18n("Family Name"), i18n("Role"), i18n("Email"), i18n("Homepage"), i18n("Language")]
        self.authorModel.setHorizontalHeaderLabels(labels)
        self.authorTable = QTableView()
        self.authorTable.setModel(self.authorModel)
        self.authorTable.verticalHeader().setDragEnabled(True)
        self.authorTable.verticalHeader().setDropIndicatorShown(True)
        self.authorTable.verticalHeader().setSectionsMovable(True)
        self.authorTable.verticalHeader().sectionMoved.connect(self.slot_reset_author_row_visual)
        delegate = author_delegate()
        delegate.setCompleterData(self.authorRoleList, 4)
        delegate.setLanguageData(len(labels) - 1)
        self.authorTable.setItemDelegate(delegate)
        author_button_layout = QWidget()
        author_button_layout.setLayout(QHBoxLayout())
        btn_add_author = QPushButton(i18n("Add Author"))
        btn_add_author.clicked.connect(self.slot_add_author)
        btn_remove_author = QPushButton(i18n("Remove Author"))
        btn_remove_author.clicked.connect(self.slot_remove_author)
        author_button_layout.layout().addWidget(btn_add_author)
        author_button_layout.layout().addWidget(btn_remove_author)
        authorPage.layout().addWidget(explanation)
        authorPage.layout().addWidget(self.authorTable)
        authorPage.layout().addWidget(author_button_layout)
        mainWidget.addTab(authorPage, i18n("Authors"))

        # The page with publisher information.
        publisherPage = QWidget()
        publisherLayout = QFormLayout()
        publisherPage.setLayout(publisherLayout)
        self.publisherName = QLineEdit()
        self.publisherName.setToolTip(i18n("The name of the company, group or person who is responsible for the final version the reader gets."))
        publishDateLayout = QHBoxLayout()
        self.publishDate = QDateEdit()
        self.publishDate.setDisplayFormat(QLocale().system().dateFormat())
        currentDate = QPushButton(i18n("Set Today"))
        currentDate.setToolTip(i18n("Sets the publish date to the current date."))
        currentDate.clicked.connect(self.slot_set_date)
        publishDateLayout.addWidget(self.publishDate)
        publishDateLayout.addWidget(currentDate)
        self.publishCity = QLineEdit()
        self.publishCity.setToolTip(i18n("Traditional publishers are always mentioned in source with the city they are located."))
        self.isbn = QLineEdit()
        self.license = license_combo_box()  # Maybe ought to make this a QLineEdit...
        self.license.setEditable(True)
        self.license.completer().setCompletionMode(QCompleter.PopupCompletion)
        dataBaseReference = QVBoxLayout()
        self.ln_database_name = QLineEdit()
        self.ln_database_name.setToolTip(i18n("If there is an entry in a comics data base, that should be added here. It is unlikely to be a factor for comics from scratch, but useful when doing a conversion."))
        self.cmb_entry_type = QComboBox()
        self.cmb_entry_type.addItems(["IssueID", "SeriesID", "URL"])
        self.cmb_entry_type.setEditable(True)
        self.ln_source = QLineEdit()
        self.ln_source.setToolTip(i18n("Whether the comic is an adaptation of an existing source, and if so, how to find information about that source. So for example, for an adapted webcomic, the official website url should go here."))
        self.label_uuid = QLabel()
        self.label_uuid.setToolTip(i18n("By default this will be filled with a generated universal unique identifier. The ID by itself is merely so that comic book library management programs can figure out if this particular comic is already in their database and whether it has been rated. Of course, the UUID can be changed into something else by manually changing the JSON, but this is advanced usage."))
        self.ln_database_entry = QLineEdit()
        dbHorizontal = QHBoxLayout()
        dbHorizontal.addWidget(self.ln_database_name)
        dbHorizontal.addWidget(self.cmb_entry_type)
        dataBaseReference.addLayout(dbHorizontal)
        dataBaseReference.addWidget(self.ln_database_entry)
        publisherLayout.addRow(i18n("Name:"), self.publisherName)
        publisherLayout.addRow(i18n("City:"), self.publishCity)
        publisherLayout.addRow(i18n("Date:"), publishDateLayout)
        publisherLayout.addRow(i18n("ISBN:"), self.isbn)
        publisherLayout.addRow(i18n("Source:"), self.ln_source)
        publisherLayout.addRow(i18n("UUID:"), self.label_uuid)
        publisherLayout.addRow(i18n("License:"), self.license)
        publisherLayout.addRow(i18n("Database:"), dataBaseReference)

        mainWidget.addTab(publisherPage, i18n("Publisher"))
    """
    Ensure that the drag and drop of authors doesn't mess up the labels.
    """

    def slot_reset_author_row_visual(self):
        headerLabelList = []
        for i in range(self.authorTable.verticalHeader().count()):
            headerLabelList.append(str(i))
        for i in range(self.authorTable.verticalHeader().count()):
            logicalI = self.authorTable.verticalHeader().logicalIndex(i)
            headerLabelList[logicalI] = str(i + 1)
        self.authorModel.setVerticalHeaderLabels(headerLabelList)
    """
    Set the publish date to the current date.
    """

    def slot_set_date(self):
        self.publishDate.setDate(QDate().currentDate())
        
    def slot_update_countries(self):
        code = self.cmbLanguage.codeForCurrentEntry()
        self.cmbCountry.set_country_for_locale(code)

    """
    Append keys to autocompletion lists from the directory mainP.
    """

    def get_auto_completion_keys(self, mainP=Path()):
        genre = Path(mainP / "key_genre")
        characters = Path(mainP / "key_characters")
        rating = Path(mainP / "key_rating")
        format = Path(mainP / "key_format")
        keywords = Path(mainP / "key_other")
        authorRole = Path(mainP / "key_author_roles")
        if genre.exists():
            for t in list(genre.glob('**/*.txt')):
                file = open(str(t), "r", errors="replace")
                for l in file:
                    if str(l).strip("\n") not in self.genreKeysList:
                        self.genreKeysList.append(str(l).strip("\n"))
                file.close()
        if characters.exists():
            for t in list(characters.glob('**/*.txt')):
                file = open(str(t), "r", errors="replace")
                for l in file:
                    if str(l).strip("\n") not in self.characterKeysList:
                        self.characterKeysList.append(str(l).strip("\n"))
                file.close()
        if format.exists():
            for t in list(format.glob('**/*.txt')):
                file = open(str(t), "r", errors="replace")
                for l in file:
                    if str(l).strip("\n") not in self.formatKeysList:
                        self.formatKeysList.append(str(l).strip("\n"))
                file.close()
        if rating.exists():
            for t in list(rating.glob('**/*.csv')):
                file = open(str(t), "r", newline="", encoding="utf-8")
                ratings = csv.reader(file)
                title = os.path.basename(str(t))
                r = 0
                for row in ratings:
                    listItem = []
                    if r is 0:
                        title = row[1]
                    else:
                        listItem = self.ratingKeysList[title]
                        item = []
                        item.append(row[0])
                        item.append(row[1])
                        listItem.append(item)
                    self.ratingKeysList[title] = listItem
                    r += 1
                file.close()
        if keywords.exists():
            for t in list(keywords.glob('**/*.txt')):
                file = open(str(t), "r", errors="replace")
                for l in file:
                    if str(l).strip("\n") not in self.otherKeysList:
                        self.otherKeysList.append(str(l).strip("\n"))
                file.close()
        if authorRole.exists():
            for t in list(authorRole.glob('**/*.txt')):
                file = open(str(t), "r", errors="replace")
                for l in file:
                    if str(l).strip("\n") not in self.authorRoleList:
                        self.authorRoleList.append(str(l).strip("\n"))
                file.close()

    """
    Refill the ratings box.
    This is called whenever the rating system changes.
    """

    def slot_refill_ratings(self):
        if self.cmbRatingSystem.currentText() in self.ratingKeysList.keys():
            self.cmbRating.clear()
            model = QStandardItemModel()
            for i in self.ratingKeysList[self.cmbRatingSystem.currentText()]:
                item = QStandardItem()
                item.setText(i[0])
                item.setToolTip(i[1])
                model.appendRow(item)
            self.cmbRating.setModel(model)

    """
    Add an author with default values initialised.
    """

    def slot_add_author(self):
        listItems = []
        listItems.append(QStandardItem(i18n("Anon")))  # Nick name
        listItems.append(QStandardItem(i18n("John")))  # First name
        listItems.append(QStandardItem())  # Middle name
        listItems.append(QStandardItem(i18n("Doe")))  # Last name
        listItems.append(QStandardItem())  # role
        listItems.append(QStandardItem())  # email
        listItems.append(QStandardItem())  # homepage
        language = QLocale.system().name().split("_")[0]
        if language == "C":
            language = "en"
        listItems.append(QStandardItem(language))  # Language
        self.authorModel.appendRow(listItems)

    """
    Remove the selected author from the author list.
    """

    def slot_remove_author(self):
        self.authorModel.removeRow(self.authorTable.currentIndex().row())

    """
    Load the UI values from the config dictionary given.
    """

    def setConfig(self, config):

        if "title" in config.keys():
            self.lnTitle.setText(config["title"])
        self.teSummary.clear()
        if "pages" in config.keys():
            self.cmbCoverPage.clear()
            for page in config["pages"]:
                self.cmbCoverPage.addItem(page)
            if "cover" in config.keys():
                if config["cover"] in config["pages"]:
                    self.cmbCoverPage.setCurrentText(config["cover"])
        if "summary" in config.keys():
            self.teSummary.appendPlainText(config["summary"])
        if "genre" in config.keys():
            genreList = []
            genreListConf = config["genre"]
            totalMatch = 100
            if isinstance(config["genre"], dict):
                genreListConf = config["genre"].keys()
                totalMatch = 0
            for genre in genreListConf:
                genreKey = genre
                if genre in self.acbfGenreList:
                    genreKey = self.acbfGenreList[genre]
                if isinstance(config["genre"], dict):
                    genreValue = config["genre"][genre]
                    if genreValue > 0:
                        genreKey = str(genreKey + "(" + str(genreValue) + ")")
                genreList.append(genreKey)
            self.lnGenre.setText(", ".join(genreList))
        if "characters" in config.keys():
            self.lnCharacters.setText(", ".join(config["characters"]))
        if "format" in config.keys():
            self.lnFormat.setText(", ".join(config["format"]))
        if "rating" in config.keys():
            self.cmbRating.setCurrentText(config["rating"])
        else:
            self.cmbRating.setCurrentText("")
        if "ratingSystem" in config.keys():
            self.cmbRatingSystem.setCurrentText(config["ratingSystem"])
        else:
            self.cmbRatingSystem.setCurrentText("")
        if "otherKeywords" in config.keys():
            self.lnOtherKeywords.setText(", ".join(config["otherKeywords"]))
        if "seriesName" in config.keys():
            self.lnSeriesName.setText(config["seriesName"])
        if "seriesVolume" in config.keys():
            self.spnSeriesVol.setValue(config["seriesVolume"])
        if "seriesNumber" in config.keys():
            self.spnSeriesNumber.setValue(config["seriesNumber"])
        if "language" in config.keys():
            code = config["language"]
            if "_" in code:
                self.cmbLanguage.setEntryToCode(code.split("_")[0])
                self.cmbCountry.setEntryToCode(code.split("_")[-1])
            elif "-" in code:
                self.cmbLanguage.setEntryToCode(code.split("-")[0])
                self.cmbCountry.setEntryToCode(code.split("-")[-1])
            else:
                self.cmbLanguage.setEntryToCode(code)
        if "readingDirection" in config.keys():
            if config["readingDirection"] is "leftToRight":
                self.cmbReadingMode.setCurrentIndex(int(Qt.LeftToRight))
            else:
                self.cmbReadingMode.setCurrentIndex(int(Qt.RightToLeft))
        else:
            self.cmbReadingMode.setCurrentIndex(QLocale(self.cmbLanguage.codeForCurrentEntry()).textDirection())
        if "publisherName" in config.keys():
            self.publisherName.setText(config["publisherName"])
        if "publisherCity" in config.keys():
            self.publishCity.setText(config["publisherCity"])
        if "publishingDate" in config.keys():
            self.publishDate.setDate(QDate.fromString(config["publishingDate"], Qt.ISODate))
        if "isbn-number" in config.keys():
            self.isbn.setText(config["isbn-number"])
        if "source" in config.keys():
            self.ln_source.setText(config["source"])
        elif "acbfSource" in config.keys():
            self.ln_source.setText(config["acbfSource"])
        if "uuid" in config.keys():
            self.label_uuid.setText(config["uuid"])
        else:
            uuid = str()
            if "acbfID" in config.keys():
                uuid = config["acbfID"]
                uuid = uuid.strip("{")
                uuid = uuid.strip("}")
                uuidVerify = uuid.split("-")
                if len(uuidVerify[0])!=8 or len(uuidVerify[1])!=4 or len(uuidVerify[2])!=4 or len(uuidVerify[3])!=4 or len(uuidVerify[4])!=12:
                    uuid = QUuid.createUuid().toString()
            self.label_uuid.setText(uuid)
            config["uuid"] = uuid
        if "license" in config.keys():
            self.license.setCurrentText(config["license"])
        else:
            self.license.setCurrentText("")  # I would like to keep it ambiguous whether the artist has thought about the license or not.
        if "authorList" in config.keys():
            authorList = config["authorList"]
            for i in range(len(authorList)):
                author = authorList[i]
                if len(author.keys()) > 0:
                    listItems = []
                    listItems = []
                    listItems.append(QStandardItem(author.get("nickname", "")))
                    listItems.append(QStandardItem(author.get("first-name", "")))
                    listItems.append(QStandardItem(author.get("initials", "")))
                    listItems.append(QStandardItem(author.get("last-name", "")))
                    role = author.get("role", "")
                    if role in self.acbfAuthorRolesList.keys():
                        role = self.acbfAuthorRolesList[role]
                    listItems.append(QStandardItem(role))
                    listItems.append(QStandardItem(author.get("email", "")))
                    listItems.append(QStandardItem(author.get("homepage", "")))
                    listItems.append(QStandardItem(author.get("language", "")))
                    self.authorModel.appendRow(listItems)
        else:
            self.slot_add_author()
        dbRef = config.get("databaseReference", {})
        self.ln_database_name.setText(dbRef.get("name", ""))
        self.ln_database_entry.setText(dbRef.get("entry", ""))
        stringCmbEntryType = self.cmb_entry_type.itemText(0)
        self.cmb_entry_type.setCurrentText(dbRef.get("type", stringCmbEntryType))

    """
    Store the GUI values into the config dictionary given.
    
    @return the config diactionary filled with new values.
    """

    def getConfig(self, config):

        text = self.lnTitle.text()
        if len(text) > 0 and text.isspace() is False:
            config["title"] = text
        elif "title" in config.keys():
            config.pop("title")
        config["cover"] = self.cmbCoverPage.currentText()
        listkeys = self.lnGenre.text()
        if len(listkeys) > 0 and listkeys.isspace() is False:
            preSplit = self.lnGenre.text().split(",")
            genreMatcher = re.compile(r'\((\d+)\)')
            genreList = {}
            totalValue = 0
            for key in preSplit:
                m = genreMatcher.search(key)
                if m:
                    genre = str(genreMatcher.sub("", key)).strip()
                    match = int(m.group()[:-1][1:])
                else:
                    genre = key.strip()
                    match = 0
                if genre in self.acbfGenreList.values():
                    i = list(self.acbfGenreList.values()).index(genre)
                    genreList[list(self.acbfGenreList.keys())[i]] = match
                else:
                    genreList[genre] = match
                totalValue += match
            # Normalize the values:
            for key in genreList.keys():
                if genreList[key] > 0:
                    genreList[key] = round(genreList[key] / totalValue * 100)
            config["genre"] = genreList
        elif "genre" in config.keys():
            config.pop("genre")
        listkeys = self.lnCharacters.text()
        if len(listkeys) > 0 and listkeys.isspace() is False:
            config["characters"] = self.lnCharacters.text().split(", ")
        elif "characters" in config.keys():
            config.pop("characters")
        listkeys = self.lnFormat.text()
        if len(listkeys) > 0 and listkeys.isspace() is False:
            config["format"] = self.lnFormat.text().split(", ")
        elif "format" in config.keys():
            config.pop("format")
        config["ratingSystem"] = self.cmbRatingSystem.currentText()
        config["rating"] = self.cmbRating.currentText()
        listkeys = self.lnOtherKeywords.text()
        if len(listkeys) > 0 and listkeys.isspace() is False:
            config["otherKeywords"] = self.lnOtherKeywords.text().split(", ")
        elif "otherKeywords" in config.keys():
            config.pop("otherKeywords")
        text = self.teSummary.toPlainText()
        if len(text) > 0 and text.isspace() is False:
            config["summary"] = text
        elif "summary" in config.keys():
            config.pop("summary")
        if len(self.lnSeriesName.text()) > 0:
            config["seriesName"] = self.lnSeriesName.text()
            config["seriesNumber"] = self.spnSeriesNumber.value()
            if self.spnSeriesVol.value() > 0:
                config["seriesVolume"] = self.spnSeriesVol.value()
        config["language"] = str(self.cmbLanguage.codeForCurrentEntry()+"-"+self.cmbCountry.codeForCurrentEntry())
        if self.cmbReadingMode.currentIndex() is int(Qt.LeftToRight):
            config["readingDirection"] = "leftToRight"
        else:
            config["readingDirection"] = "rightToLeft"
        authorList = []
        for row in range(self.authorTable.verticalHeader().count()):
            logicalIndex = self.authorTable.verticalHeader().logicalIndex(row)
            listEntries = ["nickname", "first-name", "initials", "last-name", "role", "email", "homepage", "language"]
            author = {}
            for i in range(len(listEntries)):
                entry = self.authorModel.data(self.authorModel.index(logicalIndex, i))
                if entry is None:
                    entry = " "
                if entry.isspace() is False and len(entry) > 0:
                    if listEntries[i] == "role":
                        if entry in self.acbfAuthorRolesList.values():
                            entryI = list(self.acbfAuthorRolesList.values()).index(entry)
                            entry = list(self.acbfAuthorRolesList.keys())[entryI]
                    author[listEntries[i]] = entry
                elif listEntries[i] in author.keys():
                    author.pop(listEntries[i])
            authorList.append(author)
        config["authorList"] = authorList
        config["publisherName"] = self.publisherName.text()
        config["publisherCity"] = self.publishCity.text()
        config["publishingDate"] = self.publishDate.date().toString(Qt.ISODate)
        config["isbn-number"] = self.isbn.text()
        config["source"] = self.ln_source.text()
        config["license"] = self.license.currentText()
        if self.ln_database_name.text().isalnum() and self.ln_database_entry.text().isalnum():
            dbRef = {}
            dbRef["name"] = self.ln_database_name.text()
            dbRef["entry"] = self.ln_database_entry.text()
            dbRef["type"] = self.cmb_entry_type.currentText()
            config["databaseReference"] = dbRef

        return config
Exemple #27
0
class sqlDemo(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.dbop=DbOp()
        self.table_name=''
    def initUI(self):
        self.setWindowTitle('界面对数据库操作')
        self.resize(600,400)
        widget=QWidget()
        self.setCentralWidget(widget)
        layout=QHBoxLayout()
        widget.setLayout(layout)
 
#左边
        box=QGroupBox('数据库按钮')
        boxlayout=QVBoxLayout()
        box.setLayout(boxlayout)
        #添加数据库按钮
        self.b1=QPushButton('创建连接数据库')
        boxlayout.addWidget(self.b1)
        self.b1.clicked.connect(self.create_db)
        self.b11=QPushButton('创建表')
        boxlayout.addWidget(self.b11)
        self.b11.setEnabled(False)
        self.b11.clicked.connect(self.create_table)
        self.b11.clicked.connect(self.create_table)
        self.b2=QPushButton('浏览数据')
        boxlayout.addWidget(self.b2)
        self.b2.setEnabled(False)
        self.b2.clicked.connect(self.show_db)
        self.b3=QPushButton('添加一行')
        boxlayout.addWidget(self.b3)
        self.b3.setEnabled(False)
        self.b3.clicked.connect(self.add_db)
        self.b4=QPushButton('删除一行')
        boxlayout.addWidget(self.b4)
        self.b4.setEnabled(False)
        self.b4.clicked.connect(self.del_db)
        self.b5=QPushButton('退出')
        boxlayout.addWidget(self.b5)
        self.b5.setEnabled(False)
        self.b5.clicked.connect(self.exit_db)
 
        layout.addWidget(box)
 
#右边
        self.tableview=QTableView()
        layout.addWidget(self.tableview)
        layout.setStretchFactor(box,1)
        layout.setStretchFactor(self.tableview,3)
 
        
 
    def create_db(self):
        text,ok=QInputDialog.getText(self,'数据库名称','输入数据库名称(输入英文)')
        j=Judege_English()
        if ok and (text.replace(' ','')!='')and j.judge(text):
            fin=self.dbop.database_creator(text)
            if fin:
                self.b11.setEnabled(True)
                self.b2.setEnabled(True)
                
       
 
        else:
            QMessageBox.critical(self,'信息','输入的名字有误,请从新创建',QMessageBox.Ok|QMessageBox.No,QMessageBox.Ok)
            
    def create_table(self):
        text,ok=QInputDialog.getText(self,'数据表的名称添加','输入表名(输入英文)')
        j=Judege_English()
        if ok and (text.replace(' ','')!='')and j.judge(text):
            self.dbop.table_creator(text)        
        else:
            QMessageBox.critical(self,'信息','输入的名字有误,请从新创建',QMessageBox.Ok|QMessageBox.No,QMessageBox.Ok)
 
        
    def show_db(self):
        table_name,ok=QInputDialog.getText(self,'展示数据表','输入表名(输入英文)')
        #判断是否存在输入的表
        isbeing=self.dbop.check_table(table_name)
        #存在
        if isbeing:
            model=self.dbop.data_show(table_name)
            self.tableview.setModel(model)
            self.table_name=table_name
            self.b3.setEnabled(True)
            self.b4.setEnabled(True)
            self.b5.setEnabled(True)
        #不存在
        else:
            QMessageBox.critical(self,'信息','表不存在',QMessageBox.Ok|QMessageBox.No,QMessageBox.Ok)
            self.b3.setEnabled(False)
            self.b4.setEnabled(False)
            self.b5.setEnabled(False)        
    def add_db(self):
        self.dbop.data_add()
    
    def del_db(self):
        row=self.tableview.currentIndex().row()
        self.dbop.data_del(row)
    
    def exit_db(self):
        self.dbop.data_close()
       
        self.b11.setEnabled(False)
        self.b2.setEnabled(False) 
        self.b3.setEnabled(False)
        self.b4.setEnabled(False)
        self.b5.setEnabled(False) 
Exemple #28
0
class CSerWind(QMainWindow):
    """
    主窗口
    """
    def __init__(self, inp_host, inp_port):
        super().__init__()

        self.lock = QReadWriteLock()

        self.recordSignal = RecordSignal()
        self.recordSignal.sendSignal.connect(self.my_record)

        self.tcpServer = TcpServer(self.recordSignal, self.lock)
        if not self.tcpServer.listen(QHostAddress(inp_host), inp_port):
            QMessageBox.critical(
                self, '交易服务器',
                '服务器启动失败:{0}'.format(self.tcpServer.errorString()))
            rec_text = my_cur_time() + ' 服务器启动失败!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()
            self.close()
            return
        else:
            self._initUI()
            rec_text = my_cur_time() + ' 开启交易服务器!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()

    def _initUI(self):
        self.setFixedSize(600, 400)
        self.move(0, 60)
        self.setWindowTitle('服务器:交易跟单——复制信号')
        self.setWindowIcon(QIcon('myIcon.ico'))

        # TableView设置MT4账号及Files文件夹路径
        self.model = QStandardItemModel(2, 2)
        self.model.setHorizontalHeaderLabels(['MT4账号', 'Files文件夹路径'])
        row = 0
        for key, value in account_dir.items():
            self.model.setItem(row, 0, QStandardItem(key))
            self.model.setItem(row, 1, QStandardItem(value))
            row += 1
        self.table = QTableView(self)
        self.table.setModel(self.model)
        self.table.resize(500, 180)
        self.table.move(10, 15)
        self.table.horizontalHeader().setStretchLastSection(True)

        tbn_append = QPushButton('添 加', self)
        tbn_append.resize(70, 25)
        tbn_append.move(520, 30)
        tbn_append.clicked.connect(self.my_btn_append_clicked)
        btn_delete = QPushButton('删 除', self)
        btn_delete.resize(70, 25)
        btn_delete.move(520, 90)
        btn_delete.clicked.connect(self.my_btn_delete_clicked)
        btn_save = QPushButton('保 存', self)
        btn_save.resize(70, 25)
        btn_save.move(520, 150)
        btn_save.clicked.connect(self.my_btn_save_clicked)

        # 逐条显示交易服务器操作的每个记录
        self.text_browser = QTextBrowser(self)
        self.text_browser.resize(580, 180)
        self.text_browser.move(10, 210)

        self.show()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '操作提示!', '您确定要关闭“交易服务器”?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            rec_text = my_cur_time() + ' 关闭交易服务器!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()
            event.accept()
        else:
            event.ignore()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.showMinimized()

    def my_btn_append_clicked(self):
        """
        增加一个MT4账户
        """
        self.model.appendRow([QStandardItem(''), QStandardItem('')])

    def my_btn_delete_clicked(self):
        """
        删除当前行的MT4账号信息
        """
        reply = QMessageBox.question(self, '操作提示!', '确定要删除这条数据?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            index = self.table.currentIndex()
            self.model.removeRow(index.row())

    def my_btn_save_clicked(self):
        """
        保存MT4账户信息到account_dir.txt文件中
        """
        reply = QMessageBox.question(self, '操作提示!', '确定要覆盖原有数据?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            account_dir_new = {}
            rows = self.model.rowCount()
            for row in range(rows):
                key = self.model.item(row, 0).text()
                # 对MT4账号进行正则表达式匹配检查
                if not re.match(r'^[1-9]\d+$', key):
                    QMessageBox.critical(
                        self, '错误提示!',
                        self.tr('第 %s 行MT4账号格式不对!' % str(row + 1)))
                    return
                value = self.model.item(row, 1).text()
                if not os.path.exists(value) or value.find('\MQL4\Files') < 0:
                    QMessageBox.critical(
                        self, '错误提示!',
                        self.tr('第 %s 行Files文件路径不对!' % str(row + 1)))
                    return
                account_dir_new[key] = value
            # 保存文件
            try:
                account_dir = account_dir_new
                with open('account_dir.txt', 'w') as file_object:
                    file_object.write(str(account_dir))
            except Exception as e:
                QMessageBox.critical(
                    self, '错误提示!',
                    self.tr('保存MT4账户信息出现错误!{0}'.format(str(Exception))))
            # 记录这一操作
            rec_text = my_cur_time() + ' 已经保存了当前列表中MT4账户信息!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()

    def my_record(self, inp_text):
        """
        记录服务器操作日志保存到日志文件,并在主窗口TextBrowser组件中显示出来
        """
        now = time.localtime()
        file_name = 'ser_' + time.strftime('%Y-%m-%d', now) + '.txt'
        rec_text = inp_text + '\n'

        with open(file_name, 'a+', encoding='UTF-8') as file_object:
            file_object.write(rec_text)

        # text_browser只显示当天的操作记录
        pre_text = self.text_browser.toPlainText()
        if len(pre_text) > 0 and pre_text[0:10] != inp_text[0:10]:
            self.text_browser.setText('')
        self.text_browser.append(inp_text)
class comic_export_setting_dialog(QDialog):
    acbfStylesList = [
        "speech", "commentary", "formal", "letter", "code", "heading", "audio",
        "thought", "sign", "sound", "emphasis", "strong"
    ]

    def __init__(self):
        super().__init__()
        self.setLayout(QVBoxLayout())
        self.setWindowTitle(i18n("Export Settings"))
        buttons = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)

        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        mainWidget = QTabWidget()
        self.layout().addWidget(mainWidget)
        self.layout().addWidget(buttons)

        # Set basic crop settings
        # Set which layers to remove before export.
        mainExportSettings = QWidget()
        mainExportSettings.setLayout(QVBoxLayout())
        groupExportCrop = QGroupBox(i18n("Crop Settings"))
        formCrop = QFormLayout()
        groupExportCrop.setLayout(formCrop)
        self.chk_toOutmostGuides = QCheckBox(i18n("Crop to outmost guides"))
        self.chk_toOutmostGuides.setChecked(True)
        self.chk_toOutmostGuides.setToolTip(
            i18n(
                "This will crop to the outmost guides if possible and otherwise use the underlying crop settings."
            ))
        formCrop.addRow("", self.chk_toOutmostGuides)
        btn_fromSelection = QPushButton(
            i18n("Set Margins from Active Selection"))
        btn_fromSelection.clicked.connect(self.slot_set_margin_from_selection)
        # This doesn't work.
        formCrop.addRow("", btn_fromSelection)
        self.spn_marginLeft = QSpinBox()
        self.spn_marginLeft.setMaximum(99999)
        self.spn_marginLeft.setSuffix(" px")
        formCrop.addRow(i18n("Left:"), self.spn_marginLeft)
        self.spn_marginTop = QSpinBox()
        self.spn_marginTop.setMaximum(99999)
        self.spn_marginTop.setSuffix(" px")
        formCrop.addRow(i18n("Top:"), self.spn_marginTop)
        self.spn_marginRight = QSpinBox()
        self.spn_marginRight.setMaximum(99999)
        self.spn_marginRight.setSuffix(" px")
        formCrop.addRow(i18n("Right:"), self.spn_marginRight)
        self.spn_marginBottom = QSpinBox()
        self.spn_marginBottom.setMaximum(99999)
        self.spn_marginBottom.setSuffix(" px")
        formCrop.addRow(i18n("Bottom:"), self.spn_marginBottom)
        groupExportLayers = QGroupBox(i18n("Layers"))
        formLayers = QFormLayout()
        groupExportLayers.setLayout(formLayers)
        self.cmbLabelsRemove = labelSelector()
        formLayers.addRow(i18n("Label for removal:"), self.cmbLabelsRemove)
        self.ln_text_layer_name = QLineEdit()
        self.ln_text_layer_name.setToolTip(
            i18n(
                "These are keywords that can be used to identify text layers. A layer only needs to contain the keyword to be recognized. Keywords should be comma separated."
            ))
        self.ln_panel_layer_name = QLineEdit()
        self.ln_panel_layer_name.setToolTip(
            i18n(
                "These are keywords that can be used to identify panel layers. A layer only needs to contain the keyword to be recognized. Keywords should be comma separated."
            ))
        formLayers.addRow(i18n("Text Layer Key:"), self.ln_text_layer_name)
        formLayers.addRow(i18n("Panel Layer Key:"), self.ln_panel_layer_name)

        mainExportSettings.layout().addWidget(groupExportCrop)
        mainExportSettings.layout().addWidget(groupExportLayers)
        mainWidget.addTab(mainExportSettings, i18n("General"))

        # CBZ, crop, resize, which metadata to add.
        CBZexportSettings = QWidget()
        CBZexportSettings.setLayout(QVBoxLayout())
        self.CBZactive = QCheckBox(i18n("Export to CBZ"))
        CBZexportSettings.layout().addWidget(self.CBZactive)
        self.CBZgroupResize = comic_export_resize_widget("CBZ")
        CBZexportSettings.layout().addWidget(self.CBZgroupResize)
        self.CBZactive.clicked.connect(self.CBZgroupResize.setEnabled)
        CBZgroupMeta = QGroupBox(i18n("Metadata to Add"))
        # CBZexportSettings.layout().addWidget(CBZgroupMeta)
        CBZgroupMeta.setLayout(QFormLayout())

        mainWidget.addTab(CBZexportSettings, i18n("CBZ"))

        # ACBF, crop, resize, creator name, version history, panel layer, text layers.
        ACBFExportSettings = QWidget()
        ACBFform = QFormLayout()
        ACBFExportSettings.setLayout(QVBoxLayout())
        ACBFdocInfo = QGroupBox()
        ACBFdocInfo.setTitle(i18n("ACBF Document Info"))
        ACBFdocInfo.setLayout(ACBFform)
        self.lnACBFID = QLabel()
        self.lnACBFID.setToolTip(
            i18n(
                "By default this will be filled with a generated universal unique identifier. The ID by itself is merely so that comic book library management programs can figure out if this particular comic is already in their database and whether it has been rated. Of course, the UUID can be changed into something else by manually changing the JSON, but this is advanced usage."
            ))
        self.spnACBFVersion = QSpinBox()
        self.ACBFhistoryModel = QStandardItemModel()
        acbfHistoryList = QListView()
        acbfHistoryList.setModel(self.ACBFhistoryModel)
        btn_add_history = QPushButton(i18n("Add History Entry"))
        btn_add_history.clicked.connect(self.slot_add_history_item)
        self.chkIncludeTranslatorComments = QCheckBox()
        self.chkIncludeTranslatorComments.setText(
            i18n("Include translator's comments"))
        self.chkIncludeTranslatorComments.setToolTip(
            i18n(
                "A PO file can contain translator's comments. If this is checked, the translations comments will be added as references into the ACBF file."
            ))
        self.lnTranslatorHeader = QLineEdit()

        ACBFform.addRow(i18n("ACBF UID:"), self.lnACBFID)
        ACBFform.addRow(i18n("Version:"), self.spnACBFVersion)
        ACBFform.addRow(i18n("Version history:"), acbfHistoryList)
        ACBFform.addRow("", btn_add_history)
        ACBFform.addRow("", self.chkIncludeTranslatorComments)
        ACBFform.addRow(i18n("Translator header:"), self.lnTranslatorHeader)

        ACBFAuthorInfo = QWidget()
        acbfAVbox = QVBoxLayout(ACBFAuthorInfo)
        infoLabel = QLabel(
            i18n(
                "The people responsible for the generation of the CBZ/ACBF files."
            ))
        infoLabel.setWordWrap(True)
        ACBFAuthorInfo.layout().addWidget(infoLabel)
        self.ACBFauthorModel = QStandardItemModel(0, 6)
        labels = [
            i18n("Nick Name"),
            i18n("Given Name"),
            i18n("Middle Name"),
            i18n("Family Name"),
            i18n("Email"),
            i18n("Homepage")
        ]
        self.ACBFauthorModel.setHorizontalHeaderLabels(labels)
        self.ACBFauthorTable = QTableView()
        acbfAVbox.addWidget(self.ACBFauthorTable)
        self.ACBFauthorTable.setModel(self.ACBFauthorModel)
        self.ACBFauthorTable.verticalHeader().setDragEnabled(True)
        self.ACBFauthorTable.verticalHeader().setDropIndicatorShown(True)
        self.ACBFauthorTable.verticalHeader().setSectionsMovable(True)
        self.ACBFauthorTable.verticalHeader().sectionMoved.connect(
            self.slot_reset_author_row_visual)
        AuthorButtons = QHBoxLayout()
        btn_add_author = QPushButton(i18n("Add Author"))
        btn_add_author.clicked.connect(self.slot_add_author)
        AuthorButtons.addWidget(btn_add_author)
        btn_remove_author = QPushButton(i18n("Remove Author"))
        btn_remove_author.clicked.connect(self.slot_remove_author)
        AuthorButtons.addWidget(btn_remove_author)
        acbfAVbox.addLayout(AuthorButtons)

        ACBFStyle = QWidget()
        ACBFStyle.setLayout(QHBoxLayout())
        self.ACBFStylesModel = QStandardItemModel()
        self.ACBFStyleClass = QListView()
        self.ACBFStyleClass.setModel(self.ACBFStylesModel)
        ACBFStyle.layout().addWidget(self.ACBFStyleClass)
        ACBFStyleEdit = QWidget()
        ACBFStyleEditVB = QVBoxLayout(ACBFStyleEdit)
        self.ACBFuseFont = QCheckBox(i18n("Use font"))
        self.ACBFFontList = QListView()
        self.ACBFFontList.setItemDelegate(font_list_delegate())
        self.ACBFuseFont.toggled.connect(self.font_slot_enable_font_view)
        self.ACBFFontListModel = QStandardItemModel()
        self.ACBFFontListModel.rowsRemoved.connect(
            self.slot_font_current_style)
        self.ACBFFontListModel.itemChanged.connect(
            self.slot_font_current_style)
        self.btnAcbfAddFont = QPushButton()
        self.btnAcbfAddFont.setIcon(Application.icon("list-add"))
        self.btnAcbfAddFont.clicked.connect(self.font_slot_add_font)
        self.btn_acbf_remove_font = QPushButton()
        self.btn_acbf_remove_font.setIcon(Application.icon("edit-delete"))
        self.btn_acbf_remove_font.clicked.connect(self.font_slot_remove_font)
        self.ACBFFontList.setModel(self.ACBFFontListModel)
        self.ACBFdefaultFont = QComboBox()
        self.ACBFdefaultFont.addItems(
            ["sans-serif", "serif", "monospace", "cursive", "fantasy"])
        acbfFontButtons = QHBoxLayout()
        acbfFontButtons.addWidget(self.btnAcbfAddFont)
        acbfFontButtons.addWidget(self.btn_acbf_remove_font)
        self.ACBFBold = QCheckBox(i18n("Bold"))
        self.ACBFItal = QCheckBox(i18n("Italic"))
        self.ACBFStyleClass.clicked.connect(self.slot_set_style)
        self.ACBFStyleClass.selectionModel().selectionChanged.connect(
            self.slot_set_style)
        self.ACBFStylesModel.itemChanged.connect(self.slot_set_style)
        self.ACBFBold.toggled.connect(self.slot_font_current_style)
        self.ACBFItal.toggled.connect(self.slot_font_current_style)
        colorWidget = QGroupBox(self)
        colorWidget.setTitle(i18n("Text Colors"))
        colorWidget.setLayout(QVBoxLayout())
        self.regularColor = QColorDialog()
        self.invertedColor = QColorDialog()
        self.btn_acbfRegColor = QPushButton(i18n("Regular Text"), self)
        self.btn_acbfRegColor.clicked.connect(self.slot_change_regular_color)
        self.btn_acbfInvColor = QPushButton(i18n("Inverted Text"), self)
        self.btn_acbfInvColor.clicked.connect(self.slot_change_inverted_color)
        colorWidget.layout().addWidget(self.btn_acbfRegColor)
        colorWidget.layout().addWidget(self.btn_acbfInvColor)
        ACBFStyleEditVB.addWidget(colorWidget)
        ACBFStyleEditVB.addWidget(self.ACBFuseFont)
        ACBFStyleEditVB.addWidget(self.ACBFFontList)
        ACBFStyleEditVB.addLayout(acbfFontButtons)
        ACBFStyleEditVB.addWidget(self.ACBFdefaultFont)
        ACBFStyleEditVB.addWidget(self.ACBFBold)
        ACBFStyleEditVB.addWidget(self.ACBFItal)
        ACBFStyleEditVB.addStretch()
        ACBFStyle.layout().addWidget(ACBFStyleEdit)

        ACBFTabwidget = QTabWidget()
        ACBFTabwidget.addTab(ACBFdocInfo, i18n("Document Info"))
        ACBFTabwidget.addTab(ACBFAuthorInfo, i18n("Author Info"))
        ACBFTabwidget.addTab(ACBFStyle, i18n("Style Sheet"))
        ACBFExportSettings.layout().addWidget(ACBFTabwidget)
        mainWidget.addTab(ACBFExportSettings, i18n("ACBF"))

        # Epub export, crop, resize, other questions.
        EPUBexportSettings = QWidget()
        EPUBexportSettings.setLayout(QVBoxLayout())
        self.EPUBactive = QCheckBox(i18n("Export to EPUB"))
        EPUBexportSettings.layout().addWidget(self.EPUBactive)
        self.EPUBgroupResize = comic_export_resize_widget("EPUB")
        EPUBexportSettings.layout().addWidget(self.EPUBgroupResize)
        self.EPUBactive.clicked.connect(self.EPUBgroupResize.setEnabled)
        mainWidget.addTab(EPUBexportSettings, i18n("EPUB"))

        # For Print. Crop, no resize.
        TIFFExportSettings = QWidget()
        TIFFExportSettings.setLayout(QVBoxLayout())
        self.TIFFactive = QCheckBox(i18n("Export to TIFF"))
        TIFFExportSettings.layout().addWidget(self.TIFFactive)
        self.TIFFgroupResize = comic_export_resize_widget("TIFF")
        TIFFExportSettings.layout().addWidget(self.TIFFgroupResize)
        self.TIFFactive.clicked.connect(self.TIFFgroupResize.setEnabled)
        mainWidget.addTab(TIFFExportSettings, i18n("TIFF"))

        # SVG, crop, resize, embed vs link.
        #SVGExportSettings = QWidget()

        #mainWidget.addTab(SVGExportSettings, i18n("SVG"))

    """
    Add a history item to the acbf version history list.
    """

    def slot_add_history_item(self):
        newItem = QStandardItem()
        newItem.setText(
            str(i18n("v{version}-in this version...")).format(
                version=str(self.spnACBFVersion.value())))
        self.ACBFhistoryModel.appendRow(newItem)

    """
    Get the margins by treating the active selection in a document as the trim area.
    This allows people to snap selections to a vector or something, and then get the margins.
    """

    def slot_set_margin_from_selection(self):
        doc = Application.activeDocument()
        if doc is not None:
            if doc.selection() is not None:
                self.spn_marginLeft.setValue(doc.selection().x())
                self.spn_marginTop.setValue(doc.selection().y())
                self.spn_marginRight.setValue(doc.width() -
                                              (doc.selection().x() +
                                               doc.selection().width()))
                self.spn_marginBottom.setValue(doc.height() -
                                               (doc.selection().y() +
                                                doc.selection().height()))

    """
    Add an author with default values initialised.
    """

    def slot_add_author(self):
        listItems = []
        listItems.append(QStandardItem(i18n("Anon")))  # Nick name
        listItems.append(QStandardItem(i18n("John")))  # First name
        listItems.append(QStandardItem())  # Middle name
        listItems.append(QStandardItem(i18n("Doe")))  # Last name
        listItems.append(QStandardItem())  # email
        listItems.append(QStandardItem())  # homepage
        self.ACBFauthorModel.appendRow(listItems)

    """
    Remove the selected author from the author list.
    """

    def slot_remove_author(self):
        self.ACBFauthorModel.removeRow(
            self.ACBFauthorTable.currentIndex().row())

    """
    Ensure that the drag and drop of authors doesn't mess up the labels.
    """

    def slot_reset_author_row_visual(self):
        headerLabelList = []
        for i in range(self.ACBFauthorTable.verticalHeader().count()):
            headerLabelList.append(str(i))
        for i in range(self.ACBFauthorTable.verticalHeader().count()):
            logicalI = self.ACBFauthorTable.verticalHeader().logicalIndex(i)
            headerLabelList[logicalI] = str(i + 1)
        self.ACBFauthorModel.setVerticalHeaderLabels(headerLabelList)

    """
    Set the style item to the gui item's style.
    """

    def slot_set_style(self):
        index = self.ACBFStyleClass.currentIndex()
        if index.isValid():
            item = self.ACBFStylesModel.item(index.row())
            fontUsed = item.data(role=styleEnum.FONT)
            if fontUsed is not None:
                self.ACBFuseFont.setChecked(fontUsed)
            else:
                self.ACBFuseFont.setChecked(False)
            self.font_slot_enable_font_view()
            fontList = item.data(role=styleEnum.FONTLIST)
            self.ACBFFontListModel.clear()
            for font in fontList:
                NewItem = QStandardItem(font)
                NewItem.setEditable(True)
                self.ACBFFontListModel.appendRow(NewItem)
            self.ACBFdefaultFont.setCurrentText(
                str(item.data(role=styleEnum.FONTGENERIC)))
            bold = item.data(role=styleEnum.BOLD)
            if bold is not None:
                self.ACBFBold.setChecked(bold)
            else:
                self.ACBFBold.setChecked(False)
            italic = item.data(role=styleEnum.ITALIC)
            if italic is not None:
                self.ACBFItal.setChecked(italic)
            else:
                self.ACBFItal.setChecked(False)

    """
    Set the gui items to the currently selected style.
    """

    def slot_font_current_style(self):
        index = self.ACBFStyleClass.currentIndex()
        if index.isValid():
            item = self.ACBFStylesModel.item(index.row())
            fontList = []
            for row in range(self.ACBFFontListModel.rowCount()):
                font = self.ACBFFontListModel.item(row)
                fontList.append(font.text())
            item.setData(self.ACBFuseFont.isChecked(), role=styleEnum.FONT)
            item.setData(fontList, role=styleEnum.FONTLIST)
            item.setData(self.ACBFdefaultFont.currentText(),
                         role=styleEnum.FONTGENERIC)
            item.setData(self.ACBFBold.isChecked(), role=styleEnum.BOLD)
            item.setData(self.ACBFItal.isChecked(), role=styleEnum.ITALIC)
            self.ACBFStylesModel.setItem(index.row(), item)

    """
    Change the regular color
    """

    def slot_change_regular_color(self):
        if (self.regularColor.exec_() == QDialog.Accepted):
            square = QPixmap(32, 32)
            square.fill(self.regularColor.currentColor())
            self.btn_acbfRegColor.setIcon(QIcon(square))

    """
    change the inverted color
    """

    def slot_change_inverted_color(self):
        if (self.invertedColor.exec_() == QDialog.Accepted):
            square = QPixmap(32, 32)
            square.fill(self.invertedColor.currentColor())
            self.btn_acbfInvColor.setIcon(QIcon(square))

    def font_slot_enable_font_view(self):
        self.ACBFFontList.setEnabled(self.ACBFuseFont.isChecked())
        self.btn_acbf_remove_font.setEnabled(self.ACBFuseFont.isChecked())
        self.btnAcbfAddFont.setEnabled(self.ACBFuseFont.isChecked())
        self.ACBFdefaultFont.setEnabled(self.ACBFuseFont.isChecked())
        if self.ACBFFontListModel.rowCount() < 2:
            self.btn_acbf_remove_font.setEnabled(False)

    def font_slot_add_font(self):
        NewItem = QStandardItem(QFont().family())
        NewItem.setEditable(True)
        self.ACBFFontListModel.appendRow(NewItem)

    def font_slot_remove_font(self):
        index = self.ACBFFontList.currentIndex()
        if index.isValid():
            self.ACBFFontListModel.removeRow(index.row())
            if self.ACBFFontListModel.rowCount() < 2:
                self.btn_acbf_remove_font.setEnabled(False)

    """
    Load the UI values from the config dictionary given.
    """

    def setConfig(self, config):
        if "cropToGuides" in config.keys():
            self.chk_toOutmostGuides.setChecked(config["cropToGuides"])
        if "cropLeft" in config.keys():
            self.spn_marginLeft.setValue(config["cropLeft"])
        if "cropTop" in config.keys():
            self.spn_marginTop.setValue(config["cropTop"])
        if "cropRight" in config.keys():
            self.spn_marginRight.setValue(config["cropRight"])
        if "cropBottom" in config.keys():
            self.spn_marginBottom.setValue(config["cropBottom"])
        if "labelsToRemove" in config.keys():
            self.cmbLabelsRemove.setLabels(config["labelsToRemove"])
        if "textLayerNames" in config.keys():
            self.ln_text_layer_name.setText(", ".join(
                config["textLayerNames"]))
        else:
            self.ln_text_layer_name.setText("text")
        if "panelLayerNames" in config.keys():
            self.ln_panel_layer_name.setText(", ".join(
                config["panelLayerNames"]))
        else:
            self.ln_panel_layer_name.setText("panels")
        self.CBZgroupResize.set_config(config)
        if "CBZactive" in config.keys():
            self.CBZactive.setChecked(config["CBZactive"])
        self.EPUBgroupResize.set_config(config)
        if "EPUBactive" in config.keys():
            self.EPUBactive.setChecked(config["EPUBactive"])
        self.TIFFgroupResize.set_config(config)
        if "TIFFactive" in config.keys():
            self.TIFFactive.setChecked(config["TIFFactive"])

        if "acbfAuthor" in config.keys():
            if isinstance(config["acbfAuthor"], list):
                for author in config["acbfAuthor"]:
                    listItems = []
                    listItems.append(QStandardItem(author.get("nickname", "")))
                    listItems.append(
                        QStandardItem(author.get("first-name", "")))
                    listItems.append(QStandardItem(author.get("initials", "")))
                    listItems.append(QStandardItem(author.get("last-name",
                                                              "")))
                    listItems.append(QStandardItem(author.get("email", "")))
                    listItems.append(QStandardItem(author.get("homepage", "")))
                    self.ACBFauthorModel.appendRow(listItems)
                pass
            else:
                listItems = []
                listItems.append(QStandardItem(
                    config["acbfAuthor"]))  # Nick name
                for i in range(0, 5):
                    listItems.append(QStandardItem())  # First name
                self.ACBFauthorModel.appendRow(listItems)

        if "uuid" in config.keys():
            self.lnACBFID.setText(config["uuid"])
        elif "acbfID" in config.keys():
            self.lnACBFID.setText(config["acbfID"])
        else:
            config["uuid"] = QUuid.createUuid().toString()
            self.lnACBFID.setText(config["uuid"])
        if "acbfVersion" in config.keys():
            self.spnACBFVersion.setValue(config["acbfVersion"])
        if "acbfHistory" in config.keys():
            for h in config["acbfHistory"]:
                item = QStandardItem()
                item.setText(h)
                self.ACBFhistoryModel.appendRow(item)
        if "acbfStyles" in config.keys():
            styleDict = config.get("acbfStyles", {})
            for key in self.acbfStylesList:
                keyDict = styleDict.get(key, {})
                style = QStandardItem(key.title())
                style.setCheckable(True)
                if key in styleDict.keys():
                    style.setCheckState(Qt.Checked)
                else:
                    style.setCheckState(Qt.Unchecked)
                fontOn = False
                if "font" in keyDict.keys() or "genericfont" in keyDict.keys():
                    fontOn = True
                style.setData(fontOn, role=styleEnum.FONT)
                if "font" in keyDict:
                    fontlist = keyDict["font"]
                    if isinstance(fontlist, list):
                        font = keyDict.get("font", QFont().family())
                        style.setData(font, role=styleEnum.FONTLIST)
                    else:
                        style.setData([fontlist], role=styleEnum.FONTLIST)
                else:
                    style.setData([QFont().family()], role=styleEnum.FONTLIST)
                style.setData(keyDict.get("genericfont", "sans-serif"),
                              role=styleEnum.FONTGENERIC)
                style.setData(keyDict.get("bold", False), role=styleEnum.BOLD)
                style.setData(keyDict.get("ital", False),
                              role=styleEnum.ITALIC)
                self.ACBFStylesModel.appendRow(style)
            keyDict = styleDict.get("general", {})
            self.regularColor.setCurrentColor(
                QColor(keyDict.get("color", "#000000")))
            square = QPixmap(32, 32)
            square.fill(self.regularColor.currentColor())
            self.btn_acbfRegColor.setIcon(QIcon(square))
            keyDict = styleDict.get("inverted", {})
            self.invertedColor.setCurrentColor(
                QColor(keyDict.get("color", "#FFFFFF")))
            square.fill(self.invertedColor.currentColor())
            self.btn_acbfInvColor.setIcon(QIcon(square))
        else:
            for key in self.acbfStylesList:
                style = QStandardItem(key.title())
                style.setCheckable(True)
                style.setCheckState(Qt.Unchecked)
                style.setData(False, role=styleEnum.FONT)
                style.setData(QFont().family(), role=styleEnum.FONTLIST)
                style.setData("sans-serif", role=styleEnum.FONTGENERIC)
                style.setData(False, role=styleEnum.BOLD)  #Bold
                style.setData(False, role=styleEnum.ITALIC)  #Italic
                self.ACBFStylesModel.appendRow(style)
        self.CBZgroupResize.setEnabled(self.CBZactive.isChecked())
        self.lnTranslatorHeader.setText(
            config.get("translatorHeader", "Translator's Notes"))
        self.chkIncludeTranslatorComments.setChecked(
            config.get("includeTranslComment", False))

    """
    Store the GUI values into the config dictionary given.
    
    @return the config diactionary filled with new values.
    """

    def getConfig(self, config):

        config["cropToGuides"] = self.chk_toOutmostGuides.isChecked()
        config["cropLeft"] = self.spn_marginLeft.value()
        config["cropTop"] = self.spn_marginTop.value()
        config["cropBottom"] = self.spn_marginRight.value()
        config["cropRight"] = self.spn_marginBottom.value()
        config["labelsToRemove"] = self.cmbLabelsRemove.getLabels()
        config["CBZactive"] = self.CBZactive.isChecked()
        config = self.CBZgroupResize.get_config(config)
        config["EPUBactive"] = self.EPUBactive.isChecked()
        config = self.EPUBgroupResize.get_config(config)
        config["TIFFactive"] = self.TIFFactive.isChecked()
        config = self.TIFFgroupResize.get_config(config)
        authorList = []
        for row in range(self.ACBFauthorTable.verticalHeader().count()):
            logicalIndex = self.ACBFauthorTable.verticalHeader().logicalIndex(
                row)
            listEntries = [
                "nickname", "first-name", "initials", "last-name", "email",
                "homepage"
            ]
            author = {}
            for i in range(len(listEntries)):
                entry = self.ACBFauthorModel.data(
                    self.ACBFauthorModel.index(logicalIndex, i))
                if entry is None:
                    entry = " "
                if entry.isspace() is False and len(entry) > 0:
                    author[listEntries[i]] = entry
                elif listEntries[i] in author.keys():
                    author.pop(listEntries[i])
            authorList.append(author)
        config["acbfAuthor"] = authorList
        config["acbfVersion"] = self.spnACBFVersion.value()
        versionList = []
        for r in range(self.ACBFhistoryModel.rowCount()):
            index = self.ACBFhistoryModel.index(r, 0)
            versionList.append(
                self.ACBFhistoryModel.data(index, Qt.DisplayRole))
        config["acbfHistory"] = versionList

        acbfStylesDict = {}
        for row in range(0, self.ACBFStylesModel.rowCount()):
            entry = self.ACBFStylesModel.item(row)
            if entry.checkState() == Qt.Checked:
                key = entry.text().lower()
                style = {}
                if entry.data(role=styleEnum.FONT):
                    font = entry.data(role=styleEnum.FONTLIST)
                    if font is not None:
                        style["font"] = font
                    genericfont = entry.data(role=styleEnum.FONTGENERIC)
                    if font is not None:
                        style["genericfont"] = genericfont
                bold = entry.data(role=styleEnum.BOLD)
                if bold is not None:
                    style["bold"] = bold
                italic = entry.data(role=styleEnum.ITALIC)
                if italic is not None:
                    style["ital"] = italic
                acbfStylesDict[key] = style
        acbfStylesDict["general"] = {
            "color": self.regularColor.currentColor().name()
        }
        acbfStylesDict["inverted"] = {
            "color": self.invertedColor.currentColor().name()
        }
        config["acbfStyles"] = acbfStylesDict
        config["translatorHeader"] = self.lnTranslatorHeader.text()
        config[
            "includeTranslComment"] = self.chkIncludeTranslatorComments.isChecked(
            )

        # Turn this into something that retrieves from a line-edit when string freeze is over.
        config["textLayerNames"] = self.ln_text_layer_name.text().split(",")
        config["panelLayerNames"] = self.ln_panel_layer_name.text().split(",")
        return config
Exemple #30
0
class WindowClass(QMainWindow):
    # 如果集成QMainWindow 则self.setLayout(self.layout) 替换成
    """
        widget=QWidget()
        widget.setLayout(self.layout)
        self.setCentralWidget(widget)
    """

    # 即可, 注意集成QWidget和集成QMainWindow时候区别

    def __init__(self, parent=None):
        super(WindowClass, self).__init__(parent)
        self.layout = QVBoxLayout()
        self.model = QStandardItemModel(5, 5)  # 存储任意结构数据
        self.model.setHorizontalHeaderLabels(['序号', '姓名', '年龄', '地址'])
        for row in range(1, 5):
            for column in range(5):
                i = QStandardItem("  row %s,column %s" % (row, column))
                self.model.setItem(row, column, i)
        self.tableView = QTableView()
        self.tableView.setModel(self.model)
        self.layout.addWidget(self.tableView)

        # 继承QMainWidow使用下面三行代码
        widget = QWidget()
        widget.setLayout(self.layout)
        self.setCentralWidget(widget)

        # 继承QWidget则使用下面这样代码
        # self.setLayout(self.layout)

        # 设置表格充满这个布局QHeaderView
        # self.tableView.horizontalHeader().setStretchLastSection(True)#最后一列决定充满剩下的界面
        self.tableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)  # 所有列自动拉伸,充满界面

        # 添加menu菜单栏,注意:QMainWindow 才可以有菜单栏,QWidget没有,因此上面只能采用继承QMainWIndow
        tool = self.addToolBar(
            "File"
        )  # 这里尝试使用QmenuBar,则此时会卡死,无法完成下面appedRow操作(猜测:可能是因为本身不允许menuBar完成这种操作)
        self.action = QAction("添加", self)
        self.action2 = QAction("删除", self)
        tool.addAction(self.action)
        tool.addAction(self.action2)
        tool.actionTriggered[QAction].connect(self.processtrigger)

        self.tableView.setSelectionMode(
            QAbstractItemView.SingleSelection)  # 设置只能选中一行
        self.tableView.setEditTriggers(QTableView.NoEditTriggers)  # 不可编辑
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 设置只有行选中

    def processtrigger(self, action):
        if action.text() == "添加":
            self.model.appendRow([
                QStandardItem('row %s,column %s' % (11, 11)),
                QStandardItem('row %s,column %s' % (11, 11)),
                QStandardItem('row %s,column %s' % (11, 11)),
                QStandardItem('row %s,column %s' % (11, 11)),
            ])
        if action.text() == "删除":

            r = self.tableView.selectionModel().selectedRows()  # 获取被选中行
            print(r)  # 被选中行的列表,每个元素是ModelIndex对象
            # indexs = self.tableView.selectionModel().selection().indexes()#返回结果是QModelIndex类对象,里面有row和column方法获取行列索引
            # print(indexs[0].row())
            if r:
                # 下面删除时,选中多行中的最后一行,会被删掉;不选中,则默认第一行删掉
                index = self.tableView.currentIndex()
                print(index.row())
                self.model.removeRow(index.row())