示例#1
0
    def initUI(self):
        self.setWindowTitle('TickTackToe 2000')

        self.resize(350, 350)
        self.center()

        self.main_layout = QVBoxLayout()

        self.form_layout = QGridLayout()
        self.main_layout.addLayout(self.form_layout)

        splitter = QSplitter(QtCore.Qt.Horizontal)
        self.main_layout.addWidget(splitter)

        self.game_layout = QGridLayout()
        self.main_layout.addLayout(self.game_layout)

        self.server_label = QLabel("Server: ")
        self.server_input = QLineEdit("127.0.0.1")
        self.form_layout.addWidget(self.server_label, 0, 0)
        self.form_layout.addWidget(self.server_input, 0, 1)

        self.port_label = QLabel("Port: ")
        self.port_input = QLineEdit("1632")
        self.form_layout.addWidget(self.port_label, 1, 0)
        self.form_layout.addWidget(self.port_input, 1, 1)

        self.connect_button = QPushButton("Connect")
        self.connect_button.setMinimumHeight(60)
        self.connect_button.pressed.connect(self.reconnect)
        self.form_layout.addWidget(self.connect_button, 0, 2, 2, 1)

        self.game_fields = {}

        tile_font = QFont()
        tile_font.setPointSize(30)

        for x in range(0, GAME_SIZE):
            for y in range(0, GAME_SIZE):
                f = QPushButton(" ")
                f.setMinimumHeight(90)
                f.setDisabled(True)
                f.setFont(tile_font)
                f.clicked.connect(self.onGameButtonClicked)

                if x in self.game_fields:
                    self.game_fields[x][y] = f
                else:
                    self.game_fields[x] = { 0: f }

                self.game_layout.addWidget(f, y, x)

        central_widget = QtGui.QWidget()
        central_widget.setLayout(self.main_layout)
        self.setCentralWidget(central_widget)

        self.statusBar().showMessage("")

        self.show()
示例#2
0
class MainWindow(QMainWindow):  # Sets up the main window
    def resize_window(self):  # Function for resizing the window
        self.resize(self.minimumSizeHint())

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

        # Set window Icon
        self.setWindowTitle(__appname__)
        iconImage = QImage(iconByteArray)
        iconPixmap = QPixmap(iconImage)
        self.setWindowIcon(QIcon(iconPixmap))

        # Set up private key format widgets
        privateKeyFormatLayout = QHBoxLayout()
        privateKeyFormatLabel = QLabel('Select Key Format: ')
        self.privateKeyTypeCombobox = QComboBox()
        self.privateKeyTypeCombobox.addItems(privateKeyFormats)
        self.privateKeyLengthLabel = QLabel('0')
        privateKeyFormatLayout.addWidget(privateKeyFormatLabel)
        privateKeyFormatLayout.addWidget(self.privateKeyTypeCombobox)
        privateKeyFormatLayout.addWidget(self.privateKeyLengthLabel)

        # Set up private key text widgets
        privateKeyLayout = QVBoxLayout()
        privateKeyButtonsLayout = QHBoxLayout()
        generatePrivateKeyButton = QPushButton('Generate Key')
        generatePrivateKeyButton.clicked.connect(self.get_private_key)
        self.copyPrivateKeyButton = QPushButton('Copy Key')
        self.copyPrivateKeyButton.setDisabled(True)
        self.copyPrivateKeyButton.clicked.connect(self.copy_private_key)
        privateKeyButtonsLayout.addWidget(generatePrivateKeyButton)
        privateKeyButtonsLayout.addWidget(self.copyPrivateKeyButton)
        self.privateKeyEdit = GrowingTextEdit()
        self.privateKeyEdit.setFont(QFont('Courier'))
        self.privateKeyEdit.textChanged.connect(
            self.private_key_or_code_changed)
        privateKeyLayout.addLayout(privateKeyButtonsLayout)
        privateKeyLayout.addWidget(self.privateKeyEdit)

        # Set up cypher code widgets
        codeLayout = QHBoxLayout()
        codeLabel = QLabel('Select Cypher Code: ')
        self.codeSelect = QSpinBox()
        self.codeSelect.setValue(10)
        self.codeSelect.setMinimum(2)
        self.codeSelect.setDisabled(True)
        self.codeSelect.valueChanged.connect(self.private_key_or_code_changed)
        codeLayout.addWidget(codeLabel)
        codeLayout.addWidget(self.codeSelect)

        # Set up cypher text widgets
        cypherLayout = QVBoxLayout()
        cypherButtonsLayout = QHBoxLayout()
        cardButtonsLayout = QHBoxLayout()
        self.generateCypherButton = QPushButton('Generate Cypher')
        self.generateCypherButton.clicked.connect(self.get_cypher)
        self.generateCypherButton.setDisabled(True)
        self.copyCypherButton = QPushButton('Copy Cypher')
        self.copyCypherButton.setDisabled(True)
        self.copyCypherButton.clicked.connect(self.copy_cypher)
        cypherButtonsLayout.addWidget(self.generateCypherButton)
        cypherButtonsLayout.addWidget(self.copyCypherButton)
        self.cypherEdit = GrowingTextEdit()
        self.cypherEdit.setFont(QFont('Courier'))
        self.cypherEdit.setReadOnly(True)
        self.cypherEdit.setVisible(False)
        self.cypherEdit.textChanged.connect(self.resize_window)
        self.cypherPreviewLabel = QLabel('-CYPHER PREVIEW-')
        self.cypherPreviewLabel.setAlignment(Qt.AlignCenter)
        self.cypherPreviewLabel.setVisible(False)
        self.cypherPreview = GrowingTextEdit()
        self.cypherPreview.setFont(QFont('Courier'))
        self.cypherPreview.setAlignment(Qt.AlignHCenter)
        self.cypherPreview.setWordWrapMode(QTextOption.NoWrap)
        self.cypherPreview.setReadOnly(True)
        self.cypherPreview.setVisible(False)
        self.cypherCardsPrintButton = QPushButton('Print Cypher Cards')
        self.cypherCardsPrintButton.setVisible(False)
        self.cypherCardsPrintButton.clicked.connect(partial(self.cards, True))
        self.cypherCardsCopyButton = QPushButton('Copy Cypher Cards')
        self.cypherCardsCopyButton.setVisible(False)
        self.cypherCardsCopyButton.clicked.connect(partial(self.cards, False))
        cardButtonsLayout.addWidget(self.cypherCardsPrintButton)
        cardButtonsLayout.addWidget(self.cypherCardsCopyButton)
        cypherLayout.addLayout(cypherButtonsLayout)
        cypherLayout.addWidget(self.cypherEdit)
        cypherLayout.addWidget(self.cypherPreviewLabel)
        cypherLayout.addWidget(self.cypherPreview)
        cypherLayout.addLayout(cardButtonsLayout)

        # Set up donation widgets
        donationsLayout = QVBoxLayout()
        separater = QFrame()
        separater.setFrameShape(QFrame.HLine)
        self.donationButton = QPushButton('Donate')
        self.donationButton.setVisible(False)
        self.donationButton.clicked.connect(self.donate)
        self.copyEthAddressButton = QPushButton('ETH: Copy Address')
        self.copyEthAddressButton.clicked.connect(
            self.copy_eth_donation_address)
        self.copyEthAddressButton.setVisible(False)
        self.copyBtcAddressButton = QPushButton('BTC: Copy Address')
        self.copyBtcAddressButton.clicked.connect(
            self.copy_btc_donation_address)
        self.copyBtcAddressButton.setVisible(False)
        donationsLayout.addWidget(separater)
        donationsLayout.addWidget(self.donationButton)
        donationsLayout.addWidget(self.copyEthAddressButton)
        donationsLayout.addWidget(self.copyBtcAddressButton)

        # Add all widgets and sub-layouts to the master layout
        self.master_layout = QVBoxLayout()
        self.master_layout.addLayout(privateKeyFormatLayout)
        self.master_layout.addLayout(privateKeyLayout)
        self.master_layout.addLayout(codeLayout)
        self.master_layout.addLayout(cypherLayout)
        self.master_layout.addLayout(donationsLayout)
        self.master_widget = QWidget()
        self.master_widget.setLayout(self.master_layout)
        self.setCentralWidget(self.master_widget)

        # Start and connect the window resizing thread
        self.worker = Worker()
        self.worker.updateWindowSize.connect(self.resize_window)

    def copy_private_key(
            self):  # Copies the private key text to the system clipboard
        clip.setText(self.privateKeyEdit.toPlainText())
        self.copyPrivateKeyButton.setText('Key Copied')
        app.processEvents()
        sleep(2)
        self.copyPrivateKeyButton.setText('Copy Key')

    def copy_cypher(self):  # Copies the cypher text to the system clipboard
        clip.setText(self.cypherEdit.toPlainText())
        self.copyCypherButton.setText('Cypher Copied')
        app.processEvents()
        sleep(2)
        self.copyCypherButton.setText('Copy Cypher')

    def copy_eth_donation_address(
            self):  # Copies the ETH donation address to the system clipboard
        clip.setText(ethDonationAddress)
        self.copyEthAddressButton.setText('ETH: Address Copied\nThanks!')
        app.processEvents()
        sleep(2)
        self.copyEthAddressButton.setText('ETH: Copy Address')

    def copy_btc_donation_address(
            self):  # Copies the BTC donation address to the system clipboard
        clip.setText(btcDonationAddress)
        self.copyBtcAddressButton.setText('BTC: Address Copied\nThanks!')
        app.processEvents()
        sleep(2)
        self.copyBtcAddressButton.setText('BTC: Copy Address')

    def get_private_key(
        self
    ):  # Generates a key of the desired format using two instances of the SystemRandom function
        privateKey = generate_private_key.start(
            self.privateKeyTypeCombobox.currentText())
        self.privateKeyEdit.setText(privateKey)
        self.private_key_or_code_changed()
        self.copyPrivateKeyButton.setDisabled(False)

    def private_key_or_code_changed(
        self
    ):  # Changes visibility and ability of some widgets based on user input
        self.privateKeyLengthLabel.setText(
            str(len(self.privateKeyEdit.toPlainText())))
        self.copyCypherButton.setDisabled(True)
        self.cypherEdit.setText('')
        self.cypherPreview.setText('')
        self.cypherEdit.setVisible(False)
        self.cypherPreviewLabel.setVisible(False)
        self.cypherPreview.setVisible(False)
        if len(self.privateKeyEdit.toPlainText()) <= 2:
            self.copyPrivateKeyButton.setDisabled(True)
            self.generateCypherButton.setDisabled(True)
            self.codeSelect.setDisabled(True)
        else:
            self.codeSelect.setMaximum(
                len(self.privateKeyEdit.toPlainText()) - 1)
            self.copyPrivateKeyButton.setDisabled(False)
            self.generateCypherButton.setDisabled(False)
            self.codeSelect.setDisabled(False)
        self.cypherCardsPrintButton.setDisabled(True)
        self.cypherCardsPrintButton.setVisible(False)
        self.cypherCardsCopyButton.setDisabled(True)
        self.cypherCardsCopyButton.setVisible(False)
        self.worker.start()

    def get_cypher(
        self
    ):  # Converts the raw key into a cypher based on the codeSelect value
        if not 1 >= len(self.privateKeyEdit.toPlainText()) >= int(
                self.privateKeyLengthLabel.text()):
            self.generateCypherButton.setDisabled(False)
            cypherRows, cypherSeed = create_cypher.start(
                self.privateKeyEdit.toPlainText(), self.codeSelect.value())
            self.copyCypherButton.setDisabled(False)
            self.cypherEdit.setVisible(True)
            self.cypherEdit.setText(cypherSeed)
            self.cypherPreviewLabel.setVisible(True)
            self.cypherPreview.setVisible(True)
            previewText = ''
            for i in cypherRows:
                previewText += i + '\n'
            self.cypherPreview.setText(previewText)
            self.worker.start()
            self.cypherCardsPrintButton.setDisabled(False)
            self.cypherCardsPrintButton.setVisible(True)
            self.cypherCardsCopyButton.setDisabled(False)
            self.cypherCardsCopyButton.setVisible(True)
            self.donationButton.setVisible(True)
        else:
            self.generateCypherButton.setDisabled(True)

    def cards(self, print):  # Creates and prints the output.txt file
        cardList = split_cypher_into_pairs.start(self.cypherEdit.toPlainText())
        printString = format_cards.start(cardList)
        if print:
            self.cypherCardsPrintButton.setText('Printing')
            app.processEvents()
            cards_output.start(printString)
            self.cypherCardsPrintButton.setText('Print Cypher Cards')
        else:
            clip.setText(printString)
            self.cypherCardsCopyButton.setText('Cards Copied')
            app.processEvents()
            sleep(2)
            self.cypherCardsCopyButton.setText('Copy Cypher Cards')

    def donate(self):  # Adjusts the visibility of the donation buttons
        if self.donationButton.text() == 'Donate':
            self.copyEthAddressButton.setVisible(True)
            self.copyBtcAddressButton.setVisible(True)
            self.donationButton.setText('Hide')
        elif self.donationButton.text() == 'Hide':
            self.copyEthAddressButton.setVisible(False)
            self.copyBtcAddressButton.setVisible(False)
            self.donationButton.setText('Donate')
        self.worker.start()

    def cleanup(self):  # Clears the clipboard of any copied text
        clip.setText('')
示例#3
0
class ExportOrthoWin(QDialog
                     ):  #новый класс как приложение с интерфейсом и кодом
    def __init__(self, parent):
        #_____________Пременные уровня класса___________
        self.OUT_dir = ''  #выходная дирректория
        self.orthoBounds = []
        # ВЫХОДНАЯ ПРОЕКЦИЯ по умолчанию
        #out_crs='PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        self.out_crs = PhotoScan.CoordinateSystem(
            'PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        )
        #out_crs=PhotoScan.CoordinateSystem('PROJCS["WGS 84 / UTM zone 38N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",45],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32638"]]')
        self.crsShapes = PhotoScan.CoordinateSystem(
            'PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        )
        self.DATA_OK = 0
        #print ('orthoBounds=',len(self.orthoBounds))
        #формат массива:0-имя ортофото, 1-Xmin, 2-Ymin, 3-sizeX, 4-sizeY, 5-ID полигона
        #__________________________________________________

        QDialog.__init__(self, parent)
        self.setWindowTitle("Экспорт Орто по разграфке")  #Заголвок окна
        self.resize(500, 250)  #размер окна
        self.txt_comment = QLabel(
            "	Модуль экспортирует ортофото и DEM из фотоскана по нарезке. \
Нарезка в текстовом файле: название листа, координаты нижнего левого угла, размеры. \n	Проекция нарезки должна совпадать с проекцией выходного ортофотоплана.\
Листы делятся по нарезке, а внутри нарезки по блокам, размеры задаются. ФОРМАТ JPG \n	При импорте SHP должно быть текстовое поле NAME \n \
Адрес сервера: " + ServerIP +
            " меняем в теле программы. Ваша версия фотоскана: " + PH_version +
            " \n")
        self.txt_comment.setWordWrap(True)
        self.now_prj = QLabel(str(self.out_crs))
        self.select_prj = QPushButton("Выберете проекцию")  #(" открыть ")
        self.select_prj.setFixedSize(170, 26)

        self.TXT_dif_pix = QLabel("<B>Размер пикселя: </B>")
        self.TXT_dif_pix.setFixedSize(170, 26)
        self.dif_pix = QLineEdit()
        self.dif_pix.setText('0.1')  # Задает размер пикселя по умолчанию
        self.dif_pix.setFixedSize(100, 26)

        items_bloksize = ('5000', '8192', '10000', '15000', '20000', '25000',
                          '29999', 'Full')  # список с размерами тайлов
        #items_bloksize = {5000:5000, 8192:8192, 10000:10000, 15000:15000, 20000:20000, 25000:25000, 29999:29999}
        self.TXT_block_size = QLabel("<B>Размер блока: </B>", )
        self.TXT_block_size.setFixedSize(170, 26)
        self.block_size = QComboBox()
        self.block_size.setFixedSize(100, 26)
        self.block_size.addItems(items_bloksize)
        self.block_size.setCurrentIndex(
            1)  #Устанавливает по умолчанию второе значение из списка - 8192

        self.TXT_SHPname = QLabel("Файл разграфки SHP (NAME,poligons)")
        self.SHPname = QPushButton(
            "Выберете файл разграфки SHP")  #(" открыть ")
        self.SHPname.setFixedSize(170, 26)

        self.TXT_filename = QLabel(
            "Файл разграфки TXT(имя; X0; Y0; sizeX; SizeY)")
        self.filename = QPushButton("Выберете Файл разграфки")  #(" открыть ")
        self.filename.setFixedSize(170, 26)

        self.TXT_CheckOrthoDem = QLabel("Вид выходной продукции")
        self.TXT_CheckOrthoDem.setFixedSize(170, 26)
        self.CheckOrtho_Radio = QRadioButton("Ортофото")
        self.CheckOrtho_Radio.setChecked(True)
        self.CheckDem_Radio = QRadioButton("ДЕМ")

        self.TXT_OUTFOLDER = QLabel("Выходная дирректория")
        self.OUTFOLDER = QPushButton("Выберете дирректорию")  #(" открыть ")
        self.OUTFOLDER.setFixedSize(170, 26)

        items_format = (
            'JPG', 'TIF'
        )  # список форматов, ПРИ выборе ДЕМ будет выбран второй формат - внимательно при изменении списка!!!
        self.file_format = QComboBox()
        self.file_format.setFixedSize(50, 26)
        self.file_format.addItems(items_format)
        self.file_format.setCurrentIndex(
            0)  #Устанавливает по умолчанию первое значение

        self.TXT_checkExportOrtho = QLabel("Построить ортофото:")  # Ортофото
        self.TXT_checkExportOrtho.setFixedSize(170, 26)
        self.checkExportOrtho = QCheckBox()
        self.checkExportOrtho.setChecked(False)

        self.GoGo = QPushButton("Экспорт локально")  #(" Экспорт локально ")
        self.GoGo.setFixedSize(170, 26)
        self.GoGo.setDisabled(True)

        self.GoGoNet = QPushButton("Экспорт по сети")  #(" Экспорт по сети ")
        self.GoGoNet.setFixedSize(170, 26)
        self.GoGoNet.setDisabled(True)

        hbox0 = QHBoxLayout()
        hbox0.addWidget(self.txt_comment, alignment=0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.select_prj, alignment=0)
        hbox1.addWidget(self.now_prj, alignment=0)

        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.TXT_block_size, alignment=1)
        hbox2.addWidget(self.block_size, alignment=1)

        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.TXT_dif_pix, alignment=1)
        hbox3.addWidget(self.dif_pix, alignment=1)

        hbox4 = QHBoxLayout()
        #hbox4.addStretch(1)
        hbox4.addWidget(self.SHPname, alignment=0)
        hbox4.addWidget(self.TXT_SHPname, alignment=0)

        hbox5 = QHBoxLayout()
        #hbox5.addStretch(1)
        hbox5.addWidget(self.filename, alignment=0)
        hbox5.addWidget(self.TXT_filename, alignment=0)

        hbox51 = QHBoxLayout()
        hbox51.addWidget(self.TXT_CheckOrthoDem, alignment=0)
        hbox51.addWidget(self.CheckOrtho_Radio, alignment=0)
        hbox51.addWidget(self.CheckDem_Radio, alignment=0)

        hbox6 = QHBoxLayout()
        #hbox5.addStretch(1)
        hbox6.addWidget(self.OUTFOLDER, alignment=0)
        hbox6.addWidget(self.TXT_OUTFOLDER, alignment=0)
        hbox6.addWidget(self.file_format, alignment=0)

        hbox7 = QHBoxLayout()  #build ortho
        hbox7.addWidget(self.TXT_checkExportOrtho, alignment=0)
        hbox7.addWidget(self.checkExportOrtho, alignment=0)

        hbox8 = QHBoxLayout()
        hbox8.addWidget(self.GoGo, stretch=0, alignment=0)
        hbox8.addWidget(self.GoGoNet, stretch=0, alignment=0)

        vbox = QVBoxLayout()  #Определяем вбокс и забиваем его Нбоксами
        #vbox.addStretch(1)
        vbox.addLayout(hbox0)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)
        vbox.addLayout(hbox5)
        vbox.addLayout(hbox51)  #выбор, что строить орто или дем
        vbox.addLayout(hbox6)
        #Функция построения ортофото спрятана, поскольку работает не стабильно и построение ортофото для каждого листа в сумме занимает очень много времени,
        #гораздо больше, чем один раз построить ортофото для всех
        #vbox.addLayout(hbox7) #build ortho
        vbox.addLayout(hbox8)

        self.setLayout(vbox)

        self.select_prj.clicked.connect(self.set_projection)
        self.SHPname.clicked.connect(self.input_razgr_SHPname)
        self.filename.clicked.connect(self.input_razgr_name)
        self.OUTFOLDER.clicked.connect(self.input_out_dir)
        self.GoGo.clicked.connect(self.ortho_local)
        self.GoGoNet.clicked.connect(self.ortho_net)
        #Организация блокировки интерфейса для радио кнопок
        self.CheckOrtho_Radio.clicked.connect(self.CheckOrtho_Radio_DO)
        self.CheckDem_Radio.clicked.connect(self.CheckDem_Radio_DO)
        #____________
        self.checkExportOrtho.clicked.connect(
            self.PrintChkStat)  #Функция для проверки работы чека
        #self.WindowContextHelpButtonHint.clicked.connect(self.prog_hint)
        #self.WindowTitleHint.clicked.connect(self.prog_hint)

        self.exec()
        #____________________________________________________________________________

    def PrintChkStat(
        self
    ):  #Эта функция работает в принте с подстановкой и получение значения чека
        if self.checkExportOrtho.isChecked() == True:
            stat = 'ДА'
        else:
            stat = 'НЕТ'
        print('Строить орто %s здесь' % stat)

    def CheckOrtho_Radio_DO(
            self):  #Если выбран Ортоф - формат Джипег и свободен!!!
        print("Орто")
        self.file_format.setCurrentIndex(0)
        self.file_format.setDisabled(False)

    def CheckDem_Radio_DO(
            self):  #Если выбран ДЕМ - формат тифф и блокируется!!!
        print("DEM")
        self.file_format.setCurrentIndex(1)
        self.file_format.setDisabled(True)

    def ortho_local(self):
        self.export_ortho('local')

    def ortho_net(self):
        self.export_ortho('net')

    def prog_hint(self):
        print("OK")

    def unlock_export(self, sel):
        #Переменная нужна для разблокирования кнопки Экспорт. Два критических параметра:Файл разграфки и выходная дирректория, каждый добавляет по еденице.
        #Sel=5 блокирует кнопки при запуске сетевой обработки
        '''
		DATA_OK логика работы: Для экспорта нужно задать выходную директорию и файл разграфки, текстовый или векторный
		при запуске сетевой обработки кнопки опять блокируются
		DATA_OK меняет только эта процедура!!!
		
		0-ничего не задано экспорт заблокирован
		1-выбран  файл разграфки проверяем выбран ли путь, да, разблокируем 3
		2-выбран путь проверяем выбран ли файл разграфки, да, разблокируем 3
		'''
        if sel == 5 and self.DATA_OK == 1:
            self.DATA_OK = 0
            self.GoGo.setDisabled(True)
            self.GoGoNet.setDisabled(True)
        if sel == 5 and self.DATA_OK == 2:
            self.DATA_OK = 2
            self.GoGo.setDisabled(True)
            self.GoGoNet.setDisabled(True)
        if sel == 5 and self.DATA_OK == 3:
            self.DATA_OK = 2
            self.GoGo.setDisabled(True)
            self.GoGoNet.setDisabled(True)
        if self.DATA_OK == 1 and sel == 2: self.DATA_OK = 3
        if self.DATA_OK == 2 and sel == 1: self.DATA_OK = 3
        if self.DATA_OK == 0 and sel != 5: self.DATA_OK = sel
        if self.DATA_OK == 3 and sel != 5:
            self.GoGo.setDisabled(False)
            self.GoGoNet.setDisabled(False)
            print('unlock')
        print(sel, self.DATA_OK)

    def OrthoBoundCalc(self, Xn, Yn, XS,
                       YS):  # изменить под сетевую обработку с тайлами
        DifPix = float(self.dif_pix.text())
        ''' Округление начала Если надо
		Xnround=floor(Xn/DifPix)*DifPix #
		Ynround=floor(Yn/DifPix)*DifPix
		'''
        '''
		if self.block_size.currentText()=='Full' or CommandStack==5 : #Экспорт целикового фрагмента
			print('границы целиковые')
			Xnround=Xn
			Ynround=Yn-DifPix
			XSround=ceil(XS/DifPix+1)*DifPix #Границы округляем в большую сторону и расширяем на пиксель
			YSround=ceil(YS/DifPix+1)*DifPix
			XSround=Xnround+XSround
			YSround=Ynround+YSround
			
		elif CommandStack==1 and self.block_size.currentText()!='Full': # Экспорт по тайлам
			print("Границы со сдвигом")
			BlockSize=float(self.block_size.currentText())
			Xnround=Xn
			Ynround=Yn #-DifPix
			XSround=ceil(XS/DifPix+1)*DifPix #Границы округляем в большую сторону и расширяем на пиксель
			YSround=ceil(YS/DifPix+1)*DifPix
			YBlockSize=BlockSize*DifPix 
			TileShift=YBlockSize-YSround
			Ynround=Ynround+TileShift
			XSround=Xnround+XSround
			YSround=Ynround+YSround+TileShift
		else:
			Print("Bound version error, OrthoBoundCalc")
			pass
			'''
        Xnround = Xn
        Ynround = Yn - DifPix
        XSround = ceil(
            XS / DifPix + 1
        ) * DifPix  #Границы округляем в большую сторону и расширяем на пиксель
        YSround = ceil(YS / DifPix + 1) * DifPix
        XSround = Xnround + XSround
        YSround = Ynround + YSround
        point = [
        ]  #"Эта конструкция нужна для поиска максимальных координат квадрата при переходе из системы в систему
        print("точки")
        point.append(PhotoScan.Vector((Xnround, Ynround)))
        point.append(PhotoScan.Vector((Xnround, YSround)))
        point.append(PhotoScan.Vector((XSround, YSround)))
        point.append(PhotoScan.Vector((XSround, Ynround)))
        print("точки2")
        point_trans = []
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[0], self.crsShapes,
                                                 self.out_crs))
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[1], self.crsShapes,
                                                 self.out_crs))
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[2], self.crsShapes,
                                                 self.out_crs))
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[3], self.crsShapes,
                                                 self.out_crs))
        x = []
        y = []
        for i in range(4):
            print(i)
            x.append(point_trans[i][0])
            y.append(point_trans[i][1])
        xMin = min(x)
        yMin = min(y)
        xMax = max(x)
        yMax = max(y)
        #OrthoBound=(Xnround,Ynround,XSround,YSround)
        OrthoBound = (Xnround, Ynround, XSround, YSround)
        print(OrthoBound)
        OrthoBound = (xMin, yMin, xMax, yMax)
        print(OrthoBound)
        return OrthoBound

    def input_razgr_SHPname(self):
        #global listShapes
        SHPname = ''  #Векторный файл разграфки
        DataDir = os.path.dirname(
            __file__)  # Дирректория по умолчанию - дирректория скрипта!!
        shpfilename = QFileDialog.getOpenFileName(
            self, 'выберете векторный файл разграфки', DataDir,
            filter='*.shp')  #Координаты в выходной проекции
        #проверка  на пустоту
        if not shpfilename[0] == '':
            SHP_name = shpfilename[0]
        else:
            return
        sname = os.path.basename(SHP_name)
        file_sname = os.path.splitext(sname)[0]

        print('Путь до шейпа: ', SHP_name)
        print('Имя шейпа: ', file_sname)
        chunk.importShapes(SHP_name, True)  # Импорт шейпфайла с заменой
        shapes = chunk.shapes
        #Сделать проверку на ИМЯ ПОЛИГОНА
        #shapes=PhotoScan.app.document.chunk.shapes
        listShapes = shapes.items()  #Массив (список) шейпов в проекте
        self.crsShapes = shapes.crs  #Проекция шейпа
        print(self.crsShapes)
        PhotoScan.app.messageBox('Импортированы объекты: ' + str(shapes) +
                                 '\n Старые объекты удалены')

        #Получили список векторных объектов, загруженных в проект, теперь проходим по каждому объекту и определяем его минимум и максимум по коориднатам

        if len(listShapes) != 0:
            poligon_ID = 0
            self.orthoBounds = []
            for shape in listShapes:  # ЗДЕСЬ определяются координаты минимум и максимум в текущей проекции в другой все по другому - Могут быть дыры
                # в OrthoBoundCalc стоит заглушка - имщет максимальные коориднаты углов прямоугольника после перепроецирования - можно но не совсем корректно
                x = []
                y = []
                vertices = shape.vertices
                for vertex in vertices:
                    x.append(vertex[0])
                    y.append(vertex[1])

                # Если есть NAME - это будет имя, если нет - имя шейпа и номер фичи
                if str(shape.label) == '':
                    poligonName = str(file_sname) + '_' + str(poligon_ID)
                else:
                    poligonName = str(shape.label)
                xMin = min(x)
                yMin = min(y)
                xSize = max(x) - min(x)
                ySize = max(y) - min(y)
                element = [poligonName, xMin, yMin, xSize, ySize, poligon_ID]
                self.orthoBounds.append(
                    element)  #ЭТО МАССИВ с ГРАНИЦАМИ ОРТОФОТО
                #формат массива:0-имя ортофото, 1-Xmin, 2-Ymin, 3-sizeX, 4-sizeY
                poligon_ID += 1  #Увеличение на единицу
            print(len(self.orthoBounds), poligon_ID)
            if len(self.orthoBounds) != 0: self.unlock_export(1)
            self.TXT_SHPname.setText(str(sname))
            self.TXT_filename.setText(
                "Файл разграфки TXT(имя; X0; Y0; sizeX; SizeY)")
        else:
            PhotoScan.app.messageBox('Пустой SHP файл')
            self.unlock_export(5)
        print('orthoBounds=', len(self.orthoBounds))
        # Шейп засосали,  минимум максимум нашли, с обрезкой дальше разберемся
        #_____________________________________________________________________________

    def input_razgr_name(self):
        TXT_name = ''  #имя файла с разграфкой
        # КООРДИАНТЫ ДОЛЖНЫ БЫТЬ В ВЫХОДНОЙ ПРОЕКЦИИ!!!!!
        DataDir = os.path.dirname(
            __file__)  # Дирректория по умолчанию - дирректория скрипта!!
        textfilename = QFileDialog.getOpenFileName(
            self, 'выберете  файл разграфки', DataDir,
            filter='*.txt')  #Координаты в выходной проекции
        #проверка текстфайлнайм на пустоту
        if not textfilename[0] == '':
            with open(textfilename[0]) as f:
                for line in f:
                    znach = line.split(";")
                    try:
                        if not (isinstance(znach[0], str)):
                            PhotoScan.app.messageBox('Неверный форматS')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[1]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат1i')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[2]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат2i')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[3]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат3i')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[4]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат4i')
                            self.unlock_export(5)
                            return
                    except:
                        PhotoScan.app.messageBox('Неверный формат_;')
                        self.unlock_export(5)
                        return
        else:
            return
        if not (textfilename[0]
                == ''):  #Если все нормально заполняем orthoBounds
            TXT_name = textfilename
            self.orthoBounds = []
            with open(TXT_name[0]) as f:
                count = 0
                for line in f:
                    znach = line.split(";")
                    element = [
                        znach[0], znach[1], znach[2], znach[3], znach[4], count
                    ]
                    self.orthoBounds.append(
                        element)  #ЭТО МАССИВ с ГРАНИЦАМИ ОРТОФОТО
                    count += 1
            print('orthoBounds=', len(self.orthoBounds))
            self.unlock_export(
                1)  #разблокирует экспорт, если заданы разграфка и дирректория
            self.TXT_filename.setText(str(TXT_name[0]))
            self.TXT_SHPname.setText("Файл разграфки SHP (NAME,poligons)")

    def set_projection(self):
        self.out_crs = PhotoScan.app.getCoordinateSystem(
            'Система координат',
            self.out_crs)  #Специальная форма для задания системы координат
        self.now_prj.setText(str(self.out_crs))

    def input_out_dir(self):
        DataDir = os.path.dirname(__file__)
        outputdir = QFileDialog.getExistingDirectory(self,
                                                     'выберете дирректорию',
                                                     DataDir)
        if not outputdir == '':
            self.OUT_dir = outputdir
            self.TXT_OUTFOLDER.setText(str(self.OUT_dir))
            self.unlock_export(
                2)  #разблокирует экспорт, если заданы разграфка и дирректория
        else:
            return
        print('orthoBounds=', len(self.orthoBounds))

    def export_ortho(
        self, proc_type
    ):  # универсальная процедура экспорта для локлаьной и для сетевой обработки
        #global chunk
        ''' ЭТО ПРОВЕРКА ДЛЯ ПОСТРОЕНИЯ ОРТО ПЕРЕД РАБОТОЙ В ТЕКУЩЕЙ ВЕРСИИ ФУНКЦИЯ ОТКЛЮЧЕНА!!
		if self.checkExportOrtho.isChecked()==True:
			statOrthoBuild=True
		else:
			statOrthoBuild=False
		# 000000 Проверка на наличие ортофото или дем перед работой
		if (doc.chunk.orthomosaic==None and statOrthoBuild==False):
			PhotoScan.app.messageBox('Нет орто!!')
			return
		elif (doc.chunk.elevation==None and statOrthoBuild==True):
			PhotoScan.app.messageBox('Нет ДЕМ!!')
			return
		'''
        #Определение вида экспорта - орто или дем
        if self.CheckOrtho_Radio.isChecked() == True:
            ExportType = 'ORTHO'
        elif self.CheckDem_Radio.isChecked() == True:
            ExportType = 'DEM'
        else:
            AssertionError("Какой процесс экспорта?")

        #ПРОВЕРКИ НАЛИЧИЯ ДЕМ И ОРТО
        if (doc.chunk.orthomosaic == None and ExportType == 'ORTHO'):
            PhotoScan.app.messageBox('Нет орто!!')
            return
        elif (doc.chunk.elevation == None and ExportType == 'DEM'):
            PhotoScan.app.messageBox('Нет ДЕМ!!')
            return

        file_format = self.file_format.currentText()
        print('orthoBounds=', len(self.orthoBounds))
        task = []  #Это СПИСОК тасков
        DifPix = float(self.dif_pix.text())
        if self.block_size.currentText() == 'Full':
            BlockSize = 0
        else:
            BlockSize = int(self.block_size.currentText())

        # Цикл для запуска ортофото локально или для забивания стека на сеть из массива
        try:
            for cu_string in self.orthoBounds:
                OName = cu_string[0]
                XMLeft = float(cu_string[1])
                YMDown = float(cu_string[2])
                sizeXM = float(cu_string[3])
                sizeYM = float(cu_string[4])
                shapeNumber = int(cu_string[5])
                cu_Region = self.OrthoBoundCalc(
                    XMLeft, YMDown, sizeXM, sizeYM
                )  #Функция вычисления границ # изменить под сетевую обработку с тайлами
                if file_format == 'JPG' and ExportType == 'ORTHO':
                    fileoutname = self.OUT_dir + "\\ortho_" + OName + ".jpg"
                elif file_format == 'TIF' and ExportType == 'ORTHO':
                    fileoutname = self.OUT_dir + "\\ortho_" + OName + ".tif"
                elif file_format == 'TIF' and ExportType == 'DEM':
                    fileoutname = self.OUT_dir + "\\dem_" + OName + ".tif"
                else:
                    print("Формат файла?")

                if proc_type == 'local':  #КОММАНДЫ для локальной обработки
                    print('Обработка локально')
                    ''' ПОСТРОЕНИЕ ОРТОФОТО В ЭТОЙ ВЕРСИИ ОТКЛЮЧЕНО
					if statOrthoBuild==True: 
						#chunk.buildOrthomosaic(surface=PhotoScan.ElevationData, blending=PhotoScan.MosaicBlending, color_correction=False, projection=self.out_crs, region=cu_Region,dx=DifPix, dy=DifPix)
						chunk.buildOrthomosaic(surface=PhotoScan.ElevationData, blending=PhotoScan.MosaicBlending, projection=self.out_crs, region=cu_Region,dx=DifPix, dy=DifPix)
					'''

                    if CommandStack == 1 and ExportType == 'ORTHO':
                        if file_format == 'JPG':
                            chunk.exportOrthomosaic(fileoutname,
                                                    format="jpg",
                                                    projection=self.out_crs,
                                                    region=cu_Region,
                                                    dx=DifPix,
                                                    dy=DifPix,
                                                    blockw=BlockSize,
                                                    blockh=BlockSize,
                                                    write_kml=False,
                                                    write_world=True)
                        elif file_format == 'TIF':
                            chunk.exportOrthomosaic(fileoutname,
                                                    format="tif",
                                                    projection=self.out_crs,
                                                    region=cu_Region,
                                                    dx=DifPix,
                                                    dy=DifPix,
                                                    blockw=BlockSize,
                                                    blockh=BlockSize,
                                                    write_kml=False,
                                                    write_world=True,
                                                    tiff_compression="jpeg",
                                                    tiff_big=False)
                            #сжатие LZW
                            #elif file_format=='TIF': chunk.exportOrthomosaic(fileoutname, format="tif", region=cu_Region, projection=self.out_crs,dx=DifPix, dy=DifPix, blockw=BlockSize, blockh=BlockSize, write_kml=False, write_world=True, tiff_compression="lzw", tiff_big=False)
                        else:
                            print("Формат файла?")
                    elif CommandStack == 5 and ExportType == 'ORTHO':
                        if file_format == 'JPG':
                            chunk.exportOrthomosaic(
                                fileoutname,
                                PhotoScan.RasterFormatTiles,
                                PhotoScan.ImageFormatJPEG,
                                region=cu_Region,
                                projection=self.out_crs,
                                dx=DifPix,
                                dy=DifPix,
                                blockw=BlockSize,
                                blockh=BlockSize,
                                write_kml=False,
                                write_world=True)
                        elif file_format == 'TIF':
                            chunk.exportOrthomosaic(
                                fileoutname,
                                PhotoScan.RasterFormatTiles,
                                PhotoScan.ImageFormatTIFF,
                                region=cu_Region,
                                projection=self.out_crs,
                                dx=DifPix,
                                dy=DifPix,
                                blockw=BlockSize,
                                blockh=BlockSize,
                                write_kml=False,
                                write_world=True,
                                tiff_compression=PhotoScan.TiffCompressionJPEG,
                                tiff_big=False)
                            #сжатие LZW
                            #elif file_format=='TIF': chunk.exportOrthomosaic(fileoutname, PhotoScan.RasterFormatTiles,PhotoScan.ImageFormatTIFF, region=cu_Region, projection=self.out_crs,dx=DifPix, dy=DifPix, blockw=BlockSize, blockh=BlockSize, write_kml=False, write_world=True, tiff_compression=PhotoScan.TiffCompressionLZW, tiff_big=False)
                        else:
                            print("Формат файла?")
                    elif CommandStack == 1 and ExportType == 'DEM':
                        print("Экспорт ДЕМ локально")
                        if file_format == 'TIF':
                            chunk.exportDem(fileoutname,
                                            format="tif",
                                            projection=self.out_crs,
                                            region=cu_Region,
                                            dx=DifPix,
                                            dy=DifPix,
                                            blockw=BlockSize,
                                            blockh=BlockSize,
                                            write_kml=False,
                                            write_world=True,
                                            tiff_big=False)
                    elif CommandStack == 5 and ExportType == 'DEM':
                        print("Экспорт ДЕМ локально")
                        if file_format == 'TIF':
                            chunk.exportDem(fileoutname,
                                            PhotoScan.RasterFormatTiles,
                                            PhotoScan.ImageFormatTIFF,
                                            region=cu_Region,
                                            projection=self.out_crs,
                                            dx=DifPix,
                                            dy=DifPix,
                                            blockw=BlockSize,
                                            blockh=BlockSize,
                                            write_kml=False,
                                            write_world=True,
                                            tiff_big=False)

                elif proc_type == 'net':
                    print('Обработка по сети')
                    ''' ПОСТРОЕНИЕ ОРТОФОТО В ЭТОЙ ВЕРСИИ ОТКЛЮЧЕНО
					#Построить ортофото
					if statOrthoBuild==True:
						workBuild = PhotoScan.NetworkTask() # СОздаем ворк и забиваем его параметрами
						#Версионность
						if CommandStack==1:
							workBuild.params['ortho_surface'] = 0
							workBuild.params['resolution_x'] = DifPix
							workBuild.params['resolution_y'] = DifPix
						elif CommandStack==5:
							workBuild.params['ortho_surface'] = 4
							workBuild.params['resolution'] = DifPix
						else:
							return
						workBuild.name = "BuildOrthomosaic"
						workBuild.frames.append((chunk.key,0))
						workBuild.params['network_distribute'] = True
						
						task.append(workBuild) #Добавляем задачу построения в таск
					'''

                    #Экспортировать ортофото
                    workExport = PhotoScan.NetworkTask(
                    )  # СОздаем ворк и забиваем его параметрами
                    #ВЕРСИОННОСТЬ
                    if CommandStack == 1 and ExportType == 'ORTHO':
                        workExport.name = "ExportOrthomosaic"
                        workExport.params['resolution_x'] = DifPix
                        workExport.params['resolution_y'] = DifPix
                        if file_format == 'JPG':
                            workExport.params['raster_format'] = 2
                        elif file_format == 'TIF':
                            workExport.params['raster_format'] = 1
                        else:
                            print("Формат файла?")
                    elif CommandStack == 5 and ExportType == 'ORTHO':
                        workExport.name = "ExportRaster"
                        workExport.params['resolution'] = DifPix
                        if file_format == 'JPG':
                            workExport.params['image_format'] = 1
                        elif file_format == 'TIF':
                            workExport.params[
                                'image_format'] = 2  #Значение на шару!!! ПРОВЕРИТЬ
                        else:
                            print("Формат файла?")
                    elif CommandStack == 1 and ExportType == 'DEM':
                        print("Экспорт ДЕМ по сети")
                        workExport.name = "ExportDem"
                        workExport.params['resolution_x'] = DifPix
                        workExport.params['resolution_y'] = DifPix
                    elif CommandStack == 5 and ExportType == 'DEM':  #НЕ ОТЛАЖЕНО ПАРАМЕТРЫ НА ШАРУ
                        print("Экспорт ДЕМ по сети")
                        workExport.name = "ExportOrthomosaic"
                        workExport.params['resolution'] = DifPix
                        pass
                    else:
                        return

                    workExport.frames.append((chunk.key, 0))
                    workExport.params['write_world'] = 1
                    if self.block_size.currentText(
                    ) == 'Full':  # Условие на запись тайлов
                        workExport.params['write_tiles'] = 0
                    else:
                        workExport.params['write_tiles'] = 1
                    workExport.params['tile_width'] = BlockSize
                    workExport.params['tile_height'] = BlockSize
                    workExport.params[
                        'path'] = fileoutname  #выходная дирректория с именем файла
                    workExport.params['region'] = cu_Region
                    # ВНИМАНИЕ! По сети нельзя экспортировать в пользовательской проекции ИЛИ проекция должна быть НА ВСЕХ НОДАХ
                    workExport.params[
                        'projection'] = self.out_crs.authority  #Из объекта проекция берется только ее номер EPSG::32637
                    #ВНИМАНИЕ ЭКСПОРТ ОТКЛЮЧЕН!!!!
                    task.append(workExport)  #Добавляем задачу в таск
                else:
                    print('Пока не задано')
            PhotoScan.app.messageBox('Обработка закончена')
        except Exception as e:
            print(e)
            PhotoScan.app.messageBox('Что-то пошло не так ((')
            return
            #break
#Запуск сетевого стека, таска в обработку
        if proc_type == 'net':
            print(ProjectLocalPath_auto)
            print(ProjectPath)
            client.connect(ServerIP)
            batch_id = client.createBatch(ProjectPath, task)

            if batch_id == None:  #Проверка наличия проекта в сети
                PhotoScan.app.messageBox(
                    '<B>Этот проект уже запущен в обработку!!!<B>')
                self.unlock_export(5)
            else:
                print('Проект работает под номером ', batch_id)
                client.resumeBatch(batch_id)
                self.unlock_export(5)
                PhotoScan.app.messageBox(
                    'Проект поставлен в очередь сетевой обработки')

            client.disconnect()
            pass
示例#4
0
class MainWindow(QMainWindow):
    
    profileCreationMenu_Requested = Signal()
    profileSelectionDialog_Requested = Signal()
    pushupCreationMenu_Requested = Signal()
    
    def __init__(self, athlete, pushups): 
        QMainWindow.__init__(self)
        self.setWindowTitle("Pushup app")       
        
        self.athlete = athlete
        self.pushups = pushups
        
        self._initWidth = 1000
        self._initHeight = 600
        self.resize(QSize(self._initWidth, self._initHeight))
        
        self.createGUI()
        self._centerWindow()        
            
    def createGUI(self):
        self.mainWidget = QWidget()
        self._createMenus()
        
        hLayout = QHBoxLayout()
        vLayout = QVBoxLayout()
        innerVLayout = QVBoxLayout()
        
        self.profileBox = Profile(self.athlete)
        self.addPushupBtn = QPushButton("Add Pushup")
        self.addPushupBtn.setMaximumWidth(100)
        
        self.pushupsListWidget = PushupList(self.pushups) 
        
        self.graphWidget = GraphWidget()
        #self.graphWidget.setMaximumSize(400, 300)
                
        vLayout.addWidget(self.profileBox)
        
        hLayout.addWidget(self.pushupsListWidget)
        innerVLayout.addWidget(self.graphWidget)
        hLayout.addLayout(innerVLayout)
        
        vLayout.addLayout(hLayout)
        
        vLayout.addWidget(self.addPushupBtn)
        
        self.mainWidget.setLayout(vLayout)
        self.setCentralWidget(self.mainWidget)
            
    def _createMenus(self):
        self._createActions()
        
        fileMenu = self.menuBar().addMenu("&File")
        profile = self.menuBar().addMenu("&Profile")
        about = self.menuBar().addMenu("&About")
        
        fileMenu.addAction(self.exit)
        profile.addAction(self._switchProfile)
        profile.addAction(self._createProfile)
        about.addAction(self.aboutQtAction)
        about.addAction(self.aboutApplicationAction)
    
    def _createActions(self):             
        # About Menu
        self.aboutQtAction = QAction("About PySide (Qt)", self)
        self.aboutApplicationAction = QAction("About Pushup App", self)
        
        # Profile Menu
        self._createProfile = QAction("Create new profile", self)
        self._switchProfile = QAction("Profile...", self)
        
        #File Menu
        self.exit = QAction("Exit", self)   
        
        self.exit.triggered.connect(self._actionExit)
        self._createProfile.triggered.connect(self._actionCreateProfile)
        self._switchProfile.triggered.connect(self._actionSwitchProfile)
        self.aboutQtAction.triggered.connect(self._actionAboutQt)
        self.aboutApplicationAction.triggered.connect(self._actionAboutApplication)  
        
    def _actionExit(self):
        self.close()
    
    def _actionCreateProfile(self): 
        self.profileCreationMenu_Requested.emit()        
    
    def _actionSwitchProfile(self):
        self.profileSelectionDialog_Requested.emit()
        
    def _actionAboutApplication(self):
        text = "Pushup app is a work in progress application.<br><br>\
                For development information look at the \
                <a href=\"https://github.com/davcri/Push-up-app\">Github Page</a> <br>"
        QMessageBox.about(self, "About Pushup app", text)   
    
    def _actionAboutQt(self):
        QMessageBox.aboutQt(self)
                        
    def _centerWindow(self):
        displayWidth = QApplication.desktop().width()
        displayHeight = QApplication.desktop().height()
        
        self.move(displayWidth/2.0 - self._initWidth/2.0, 
                  displayHeight/2.0 - self._initHeight/2.0 - 50)        
    
    def cleanUI(self):
        self.profileBox.ageLabel.setText("")
        self.profileBox.nameLabel.setText("")
        self.profileBox.surnameLabel.setText("")
        self.profileBox.bmiLabel.setText("")
        self.profileBox.heightLabel.setText("")
        self.profileBox.massLabel.setText("")
        
        self.pushupsListWidget.pushupsListWidget.clear()
        # the first pushupListWidget is the name of the PushupList instance
        # the second is the name of a property of the PushupList instance
        
        self.addPushupBtn.setDisabled(True)
        self.graphWidget.clear()
示例#5
0
class Dialog(QWidget):

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUI()
        self.setupConnection()
        self.threadPool = []
        self.totalUids = 0
        self.finishedThreadNum = 0
        self.realThreadNum = 0
        self.excel = Excel()
        #self.initSearchDb()

    def setupUI(self):

        self.pushButton = QPushButton(u"Search", self)
        #self.testButton = QPushButton(u"Test", self)
        self.lineEdit = QLineEdit(self)
        self.textEdit = QTextEdit(self)
        self.comboBox = QComboBox(self)
        self.label = QLabel(u"DB:", self)
        self.progressBar = QProgressBar(self)
        self.progressBar.setRange(0,1)
        
        self.textEdit.setReadOnly(True)

        self.layout = QVBoxLayout()
        self.topLayout = QHBoxLayout()
        
        self.topLayout.addWidget(self.label)
        self.topLayout.addWidget(self.comboBox)
        self.topLayout.addWidget(self.lineEdit)
        self.topLayout.addWidget(self.pushButton)
        #self.topLayout.addWidget(self.testButton)

        #self.testButton.clicked.connect(self.onTestButtonClicked)

        self.layout.addLayout(self.topLayout)
        self.layout.addWidget(self.textEdit)
        self.layout.addWidget(self.progressBar)

        self.setLayout(self.layout)

        self.resize(600, 700)
        self.setWindowTitle(u"Search Data for NCBI")

    def setupConnection(self):
        self.pushButton.clicked.connect(self.onButtonClicked)

    def onButtonClicked(self):
        if not self.lineEdit.text() or not self.comboBox.count():
            QtGui.QMessageBox.information(self, u"Warning", u"Please Set the Search Field")
            return
        # disable button
        self.pushButton.setDisabled(True)
        dbName = self.comboBox.currentText()
        fieldName = self.lineEdit.text()
        self.log("Start searching db: %s and field: %s" % (dbName, fieldName))
        # add use history to add all uids to the history server
        handle = self.entrez.esearch(db=dbName, term=fieldName, usehistory='y')
        record = self.entrez.read(handle)
        self.log("All result count %s" % record['Count'])
        self.totalUids = int(record['Count'])
        # to get onnly data less than the MAX_COUNT
        if self.totalUids > MAX_COUNT:
            ret = QtGui.QMessageBox.question(
                    self,
                    u'Warning',
                    u'result count %s is too large, will only get the %s result \
                            continue?' % (self.totalUids, MAX_COUNT),
                            QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel
                            )
            if ret == QtGui.QMessageBox.Ok:
                self.totalUids = MAX_COUNT
            else:
                return
        #handle = self.entrez.efetch(db=dbName, id=record['IdList'], rettype='gb')
        self.finishedThreadNum = 0
        WebEnv = record['WebEnv']
        QueryKey = record['QueryKey']
        global FINISHED_COUNT
        FINISHED_COUNT = 0
        self.progressBar.setValue(0)
        self.progressBar.setMaximum(self.totalUids)
        if self.totalUids / RET_MAX_SUMMARY >= MAX_THREAD:
            self.realThreadNum = MAX_THREAD
            each_count = self.totalUids/MAX_THREAD
            startIndex = 0
            for i in range(MAX_THREAD - 1):
                thread = MyThread(startIndex, each_count, dbName, fieldName, WebEnv, QueryKey)
                thread.finished.connect(self.onThreadFinished)
                thread.finishedCountChanged.connect(self.onFinishedCountChange)
                thread.start()
                self.threadPool.append(thread)
                startIndex = startIndex + each_count
            thread = MyThread(startIndex, (self.totalUids-startIndex+1), dbName, fieldName, WebEnv, QueryKey)
            thread.finished.connect(self.onThreadFinished)
            thread.finishedCountChanged.connect(self.onFinishedCountChange)
            self.threadPool.append(thread)
            thread.start()
        else:
            if self.totalUids == RET_MAX_SUMMARY:
                self.realThreadNum = 1
            else:
                self.realThreadNum = self.totalUids/RET_MAX_SUMMARY + 1
            startIndex = 0
            for i in range(self.realThreadNum):
                thread = MyThread(startIndex, RET_MAX_SUMMARY, dbName, fieldName, WebEnv, QueryKey)
                thread.finished.connect(self.onThreadFinished)
                thread.finishedCountChanged.connect(self.onFinishedCountChange)
                self.threadPool.append(thread)
                thread.start()
                startIndex = startIndex + RET_MAX_SUMMARY
        self.log("thread num: %s" % self.realThreadNum)
        self.log('reading data')
        self.filename = '%s_%s_output.xls' % (dbName, fieldName)
        self.excel.setFilename(self.filename)

    def log(self, context):
        self.textEdit.append(context)

    def initSearchDb(self):
        self.entrez = Entrez 
        self.entrez.email = email
        self.log("Connect to NCBI")
        try:
            handle = self.entrez.einfo()
        except:
            QtGui.QMessageBox.warning(self, u"Error", u"Error Connect the WebSite")
            self.close()
        record = self.entrez.read(handle)
        self.log("Get NCBI DataBases:")
        for name in record['DbList']:
            self.log('DBName:\t%s' % name)
        self.comboBox.addItems(record['DbList'])

    def onThreadFinished(self):
        self.finishedThreadNum = self.finishedThreadNum + 1
        self.log('finished thread %s ' % self.finishedThreadNum)
        if(self.finishedThreadNum == self.realThreadNum):
            global all_output
            heads = all_output[0][0].keys()
            self.excel.setHead(heads)
            for values in all_output:
                for value in values:
                    self.excel.addValues(value)
            self.excel.save()
            self.progressBar.setValue(int(self.totalUids))
            # clear all thread
            self.threadPool = []
            all_output = []
            self.excel.clearValues()
            self.pushButton.setDisabled(False)
            self.log("output to file: %s" % self.filename)

    def onFinishedCountChange(self, num):
        self.progressBar.setValue(num)

    def onTestButtonClicked(self):
        self.finishedThreadNum = 0
        self.realThreadNum = 1
        self.thread = MyThread(0, 10,"abd","123")
        self.thread.finished.connect(self.onThreadFinished)
        self.thread.startIndex()
示例#6
0
class ProfileSelection(QDialog):
    '''
    classdocs
    '''
    
    removeProfile = Signal(Athlete_Model)
    profileSelected = Signal(Athlete_Model)
    profileUpdate_request = Signal(Athlete_Model, Athlete_Model)
    lastProfileDeleted = Signal()
    
    def __init__(self, athletesList):
        '''
        Constructor
        '''  
        QDialog.__init__(self)
        self.setWindowTitle("Profile Selection")
        
        self.athletesList = athletesList
            
        self._initGUI()      
    
    def _initGUI(self):
        topHLayout = QHBoxLayout()
        hLayout = QHBoxLayout()
        vLayout = QVBoxLayout()
        
        # Label
        greeterText = QLabel("Welcome to <b>Pushup app</b>." + \
                             "<br><br> Select a profile:")
        vLayout.addWidget(greeterText)        
            
        # List 
        self.list = QListWidget()
        self.list.setMinimumWidth(150)
        self.list.setSelectionMode(QAbstractItemView.SingleSelection)
        # SingleSelection is the default value, but I prefer to be sure
        self.list.itemSelectionChanged.connect(self._activateButtons) 
        
        for athlete in self.athletesList:
            iconW = QIcon.fromTheme("user-available")
            # doens't work on Mac and Windows
            # http://qt-project.org/doc/qt-4.8/qicon.html#fromTheme
            
            listW = QListWidgetItem(iconW, athlete._name)
            listW.setData(Qt.UserRole, athlete)
            
            self.list.addItem(listW)
        
        topHLayout.addWidget(self.list)
        self.profileWidget = ProfileFormWidget()
        self.profileWidget.hide()
        
        topHLayout.addWidget(self.profileWidget)    
       
        vLayout.addLayout(topHLayout)        
        vLayout.addLayout(hLayout)
        
        # Buttons
        self.okBtn = QPushButton("Ok")
        self.okBtn.setDisabled(True)
        self.okBtn.setDefault(True)
        self.okBtn.clicked.connect(self._okButtonSlot)
        self.list.itemDoubleClicked.connect(self._okButtonSlot)
                
        cancelBtn = QPushButton("Cancel")      
        cancelBtn.clicked.connect(self._cancelButtonSlot)
        
        self.editBtn = QPushButton("Edit")
        self.editBtn.setDisabled(True)
        self.editBtn.setCheckable(True)
        self.editBtn.clicked.connect(self._toggleProfileEdit)
        
        self.saveBtn = QPushButton("Save changes") # Saves the changes made on the profile 
        self.saveBtn.hide()
        self.saveBtn.clicked.connect(self._saveButtonSlot)
    
        self.removeProfileBtn = QPushButton("Remove Profile")
        self.removeProfileBtn.setDisabled(True)
        self.removeProfileBtn.clicked.connect(self._removeProfile_Dialog)
        
        hLayout.addWidget(self.editBtn)
        hLayout.addWidget(self.removeProfileBtn)
        hLayout.addWidget(cancelBtn)
        hLayout.addWidget(self.okBtn)
        hLayout.addWidget(self.saveBtn)

        self.setLayout(vLayout)
    
    def getSelectedProfile(self):
        selectedListItem = self.list.selectedItems()[0]
        athleteProfile = selectedListItem.data(Qt.UserRole)
        
        return athleteProfile
    
    def updateList(self, athletes):
        self.list.clear()
        self.athletesList = athletes
        
        for athlete in self.athletesList:
            iconW = QIcon.fromTheme("user-available")
            # doens't work on Mac and Windows
            # http://qt-project.org/doc/qt-4.8/qicon.html#fromTheme
           
            listW = QListWidgetItem(iconW, athlete._name)
            listW.setData(Qt.UserRole, athlete)
           
            self.list.addItem(listW)
    
    def resetWidget(self):
        """ Resets the widget to the initial laoyout. 
        
        Should be used only in specific cases
        """
        self.editBtn.setChecked(False)
        self._toggleProfileEdit()
            
    def _removeProfile_Dialog(self):
        """Runs a prompt dialog.
        
        Ask the user if he really wants to remove the selected profile.
        """
        confirmationDialog = QMessageBox()
        confirmationDialog.setText("Do you really want to remove the selected profile ?")
        confirmationDialog.setInformativeText("Profile deletion can not be undone")
        confirmationDialog.setIcon(QMessageBox.Question)
        confirmationDialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        confirmationDialog.accepted.connect(self._emitRemoveProfile)
        ret = confirmationDialog.exec_()
        
        if ret==QMessageBox.Yes:
            self._emitRemoveProfile()
                
    def _emitRemoveProfile(self):
        athlete = self.getSelectedProfile()
        
        rowToDelete = 0
        for index, element in enumerate(self.athletesList):
            if element == athlete:
                rowToDelete = index
                
        self.list.takeItem(rowToDelete)
        self.athletesList.remove(athlete)        
        self.removeProfile.emit(athlete)
    
    def _okButtonSlot(self):
        athlete = self.list.selectedItems()[0].data(Qt.UserRole)
        
        self.accept() # is it correct ? Maybe self.close() is better ?
        # Or should I redefine the accept() method ?
        
        #athleteProfile = self.getSelectedProfile()
        
        self.profileSelected.emit(athlete)
    
    def _cancelButtonSlot(self):
        if len(self.athletesList) == 0:
            self.lastProfileDeleted.emit()
        
        self.reject()
    
    def _saveButtonSlot(self):
        selectedProfile = self.getSelectedProfile()
        updatedProfile = self.profileWidget.getProfile()
    
        self.profileUpdate_request.emit(selectedProfile, updatedProfile)
        
        #self._toggleProfileEdit()
        
    def _toggleProfileEdit(self):
        if self.editBtn.isChecked():
            self.profileWidget.setProfile(self.getSelectedProfile())
            self.profileWidget.show()
            self.saveBtn.show()
            self.okBtn.hide()
            self.removeProfileBtn.hide()
        else:
            self.saveBtn.hide()
            self.profileWidget.hide()
            self.okBtn.show()
            self.removeProfileBtn.show()
    
    def _activateButtons(self):
        selectedItems = self.list.selectedItems()
        
        if len(selectedItems)!=0 :
            self.okBtn.setDisabled(False)
            self.removeProfileBtn.setDisabled(False)
            self.editBtn.setDisabled(False)
        else :
            self.okBtn.setDisabled(True)
            self.removeProfileBtn.setDisabled(True)
            self.editBtn.setDisabled(True)
示例#7
0
文件: notes.py 项目: kliput/peanotes
class Note(QtGui.QWidget):
    
    def __init__(self, message, mainGui, parent=None):
        super(Note, self).__init__(parent)
        
        self.mainGui = mainGui
        
        self.NOTE_WIDTH = 240
        self.NOTE_HEIGHT = 240
        
        self.setFixedSize(self.NOTE_WIDTH, self.NOTE_HEIGHT)
        
        self.setObjectName("note")
        
        self.drag = False # czy karteczka jest w trakcie przenoszenia?
        self.dragPos = QPoint() # pozycja rozpoczecia przenoszenia
        
        assert message
         
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowTitle("Note") # FIXME
        
        
        # -- główne layouty --
                
        self.globalVLayout = QtGui.QVBoxLayout(self)
        self.globalVLayout.setObjectName("globalVLayout")
                
        self.upperHLayout = QtGui.QHBoxLayout()
        self.upperHLayout.setObjectName("upperHLayout")
        self.globalVLayout.addLayout(self.upperHLayout)
        
        self.fromToForm = QtGui.QFormLayout()
        self.upperHLayout.addLayout(self.fromToForm)
        
        # -- layout z nadawcą i adresatami --
        self.fromToForm.setSizeConstraint(QtGui.QLayout.SetFixedSize)
        self.fromToForm.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
        self.fromToForm.setObjectName("fromToForm")
        
        self.fromLabel = QtGui.QLabel("From:", self)
        self.fromLabel.setObjectName("fromLabel")
        self.fromToForm.setWidget(0, QtGui.QFormLayout.LabelRole, self.fromLabel)
        
        self.fromToFormUpRight = QtGui.QHBoxLayout()
        self.fromToForm.setLayout(0, QtGui.QFormLayout.FieldRole, self.fromToFormUpRight)
        
        self.toLabel = QtGui.QLabel("To:", self)
        self.toLabel.setObjectName("toLabel")
        self.fromToForm.setWidget(1, QtGui.QFormLayout.LabelRole, self.toLabel)
        
        self.fromToFormDownRight = QtGui.QHBoxLayout()
        self.fromToForm.setLayout(1, QtGui.QFormLayout.FieldRole, self.fromToFormDownRight)
        
        
        # -- przyciski funkcyjne --        
        iconButtonPolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
        iconButtonPolicy.setHorizontalStretch(0)
        iconButtonPolicy.setVerticalStretch(0)
                
        # -- przycisk wysłania --        
        self.sendButton = QPushButton(u"&Send")
        self.sendButton.setObjectName("sendButton")
        self.sendButton.setIcon(pea_app().send_icon)
        sendSizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
        self.sendButton.setSizePolicy(sendSizePolicy)
        
        # -- przycisk dodawania
        self.addButton = QtGui.QPushButton(self)
        self.addButton.setObjectName("addButton")
        self.addButton.setSizePolicy(iconButtonPolicy)
        self.addButton.setIcon(pea_app().add_icon)
        
        self.sendButton.clicked.connect(self.sendMessage)
        
        # -- przycisk do dat
        self.datesButton = QtGui.QPushButton(self)
        self.datesButton.setCheckable(True)
        self.datesButton.setObjectName("datesButton")
        self.datesButton.setSizePolicy(iconButtonPolicy)
        self.datesButton.setIcon(pea_app().calendar_icon)
        
        # -- przycisk zamykania
        self.closeButton = QtGui.QPushButton(self)
        self.closeButton.setObjectName("closeButton")
        self.closeButton.setSizePolicy(iconButtonPolicy)
        self.closeButton.setIcon(pea_app().close_icon)
        
        
        
        # --- górny prawy ---
        self.senderUserEntry = QtGui.QLabel('')
        self.senderUserEntry.setObjectName("senderUserEntry")
        self.fromToFormUpRight.addWidget(self.senderUserEntry)
        self.fromToFormUpRight.addStretch()
        self.fromToFormUpRight.addWidget(self.sendButton)
        self.fromToFormUpRight.addWidget(self.datesButton)
        self.fromToFormUpRight.addWidget(self.closeButton)
        # ---

        # --- dolny prawy ---
        self.recipientsBox = QtGui.QLabel()
        self.fromToFormDownRight.addWidget(self.recipientsBox)
        self.fromToFormDownRight.addStretch()
        self.fromToFormDownRight.addWidget(self.addButton)
        # ---
        

        # -- linia oddzielająca nagłówek od treści
        self.line = QtGui.QFrame(self)
        self.line.setFrameShape(QtGui.QFrame.HLine)
        self.line.setFrameShadow(QtGui.QFrame.Sunken)
        self.line.setObjectName("line")
        self.globalVLayout.addWidget(self.line)

        # -- DATES --

        # TODO: zmniejszyć czcionkę?
        self.datesForm = QtGui.QFormLayout()
        self.datesForm.setObjectName("datesForm")
        self.dateLabel = QtGui.QLabel("Date:", self)
        self.dateLabel.setObjectName("dateLabel")
        self.datesForm.setWidget(0, QtGui.QFormLayout.LabelRole, self.dateLabel)
        self.validLabel = QtGui.QLabel("Valid till:", self)
        self.validLabel.setObjectName("validLabel")
        self.datesForm.setWidget(1, QtGui.QFormLayout.LabelRole, self.validLabel)
        self.dateData = QtGui.QLabel(self)
        self.dateData.setObjectName("dateData")
        self.datesForm.setWidget(0, QtGui.QFormLayout.FieldRole, self.dateData)
        self.validData = QtGui.QLabel(self)
        self.validData.setObjectName("validData")
        self.datesForm.setWidget(1, QtGui.QFormLayout.FieldRole, self.validData)

        self.datesWidget = QtGui.QWidget()
        self.datesWidget.setLayout(self.datesForm)
        self.globalVLayout.addWidget(self.datesWidget)
        
        # -- obsługa chowania dat
        self.datesWidget.hide()
        self.datesButton.toggled.connect(self.toggleDatesWidget)
        
        # TODO:
        # -- obsługa dodawania adresata
        self.addButton.clicked.connect(self.selectRecipients)

        
        # -- pole treści
        self.noteContent = QtGui.QTextBrowser(self)
        self.noteContent.setEnabled(True)
        
        self.noteContent.setFrameShape(QtGui.QFrame.NoFrame)
        self.noteContent.setFrameShadow(QtGui.QFrame.Plain)
        self.noteContent.setReadOnly(True)
        self.noteContent.setObjectName("noteContent")
        self.globalVLayout.addWidget(self.noteContent)
        
        
        # -- obsługa zamykania        
        self.closeButton.setShortcut(QtGui.QApplication.translate("note", "Ctrl+Q", None, QtGui.QApplication.UnicodeUTF8))
        self.closeButton.clicked.connect(self.closeNote)

        # -- przyszłe okno wyboru adresatów 
        self.selectRecipentsWindow = None

        # -- ustawienie treści
        self.setMessage(message)
    
    
    def setRecipients(self, recipients):
        '''Ustawia listę nadawców
        Argument recipients: lista str [odbiorca1, odbiorca2, ...]'''
        self.recipients_ = recipients
                
        rec_join = ', '.join(recipients)
        self.recipientsBox.setText(trunc_str(rec_join, 21))
        self.recipientsBox.setToolTip(rec_join)
    
    def setSender(self, sender):
        '''Ustawia wysyłającego
        Argument sender: str nadawca'''
        self.sender_ = sender
    
    def mousePressEvent(self, event):
        self.raise_()
        if event.button() == Qt.LeftButton:
            self.drag = True
            self.dragPos = event.globalPos() - self.pos()
    
    def mouseReleaseEvent(self, event):
        self.drag = False
    
    def mouseMoveEvent(self, event):
        if self.drag:
            self.move(event.globalPos() - self.dragPos)
    
    def updateMessageState(self):
        s = self.__message__.state
        send_button = False
        if s == MsgState.GUI:
            self.noteContent.setReadOnly(False)
            send_button = True
            self.addButton.show()
        elif s == MsgState.TO_SEND:
            send_button = True
            self.addButton.setDisabled(True)
            self.sendButton.setDisabled(True)
            self.noteContent.setReadOnly(True)
        elif s == MsgState.DELETED:
            self.close()
        else:
            self.sendButton.hide()
            self.addButton.hide()
            self.noteContent.setReadOnly(True)
            
        if send_button:
            self.sendButton.show()
            self.senderUserEntry.setText(trunc_str(self.sender(), 6))
        else:
            self.senderUserEntry.setText(trunc_str(self.sender(), 16))
            
        self.senderUserEntry.setToolTip(self.sender())
    
    def setMessageState(self, state):
        self.__message__.state = state
        self.updateMessageState()
    
    def setMessage(self, message):
        assert message
        self.__message__ = message
        
        self.setSender(message.sender)
        self.setRecipients(message.recipients)
        self.dateData.setText(message.create_date.strftime(DATETIME_FORMAT))
        self.validData.setText(message.expire_date.strftime(DATETIME_FORMAT))
        self.noteContent.setHtml(message.content)
        
        self.updateMessageState()
    
    def sendMessage(self):
        # tylko dla całkiem nowych wiadomości (w sumie tylko powinny być)
        if self.__message__.state == MsgState.GUI:
            self.__message__.content = self.noteContent.toPlainText()
            self.__message__.sender = self.sender()
            self.__message__.recipients = self.recipients()
            self.setMessageState(MsgState.TO_SEND)
        self.mainGui.client.addMsg(self.__message__)
        self.mainGui.updateNotes()
    
    def getMessage(self):
        return self.__message__
    
    def sender(self):
        return self.sender_
    
    def recipients(self):
        '''Zwraca listę str adresatów'''
        return self.recipients_
    
    def knownUsers(self):
        '''Zwraca listę znanych użytkowników'''
        return self.mainGui.knownUsers()
    
    def addKnownUser(self, username):
        self.mainGui.addKnownUser(username)
    
    @Slot()
    def closeNote(self):
        '''Dla przycisku zamykania - tylko ustawia stan DELETED.
        Reszta działań jest obsługiwana przez zmianę stanu'''
        self.setMessageState(MsgState.DELETED)
        # TODO: do tego można zrobić inną metodę przesyłającą tylko nowy stan...
        self.mainGui.client.modMsg(self.__message__)
    
    @Slot()
    def toggleDatesWidget(self, visibility):
        '''Dla widgetu z datami - przełączanie widoczności'''
        if visibility:
            self.datesWidget.show()
        else:
            self.datesWidget.hide()
            
    @Slot()
    def selectRecipients(self):
        if not self.selectRecipentsWindow:
            self.selectRecipentsWindow = SelectRecipientsWindow(self)
        self.selectRecipentsWindow.show()
示例#8
0
class MainWindow(QMainWindow):
    def __init__(self, datta):
        QMainWindow.__init__(self)
        self.setWindowTitle('Project Parser')
        appIcon = QIcon('search.png')
        self.setWindowIcon(appIcon)
        self.viewPortBL = QDesktopWidget().availableGeometry().topLeft()
        self.viewPortTR = QDesktopWidget().availableGeometry().bottomRight()
        self.margin = int(QDesktopWidget().availableGeometry().width()*0.1/2)
        self.shirina = QDesktopWidget().availableGeometry().width() - self.margin*2
        self.visota = QDesktopWidget().availableGeometry().height() - self.margin*2
        self.setGeometry(self.viewPortBL.x() + self.margin, self.viewPortBL.y() + self.margin,
                         self.shirina, self.visota)
        # statusbar
        self.myStatusBar = QStatusBar()
        self.setStatusBar(self.myStatusBar)
        
        #lower long layout
        self.lowerLong = QFrame()
        self.detailsLabel = QLabel()
        self.skillsLabel = QLabel()
        self.urlLabel = QLabel()
        self.locationLabel = QLabel()
        self.skillsLabel.setText('skills')
        self.detailsLabel.setWordWrap(True)
        self.la = QVBoxLayout()
        self.la.addWidget(self.detailsLabel)
        self.la.addWidget(self.skillsLabel)
        self.la.addWidget(self.urlLabel)
        self.la.addWidget(self.locationLabel)
        self.lowerLong.setLayout(self.la)

        # table
        self.source_model = MyTableModel(self, datta, ['Id', 'Date', 'Title'])
        self.proxy_model = myTableProxy(self)
        self.proxy_model.setSourceModel(self.source_model)
        self.proxy_model.setDynamicSortFilter(True)
        self.table_view = QTableView()
        self.table_view.setModel(self.proxy_model)
        self.table_view.setAlternatingRowColors(True)
        self.table_view.resizeColumnsToContents()
        self.table_view.resizeRowsToContents()
        self.table_view.horizontalHeader().setStretchLastSection(True)
        self.table_view.setSortingEnabled(True)
        self.table_view.sortByColumn(2, Qt.AscendingOrder)

        # events
        self.selection = self.table_view.selectionModel()
        self.selection.selectionChanged.connect(self.handleSelectionChanged)
        #DO NOT use CreateIndex() method, use index()
        index = self.proxy_model.index(0,0)
        self.selection.select(index, QItemSelectionModel.Select)
        
        self.upperLong = self.table_view  

        # right side widgets
        self.right = QFrame()
        self.la1 = QVBoxLayout()
        self.btnDownload = QPushButton('Download data')
        self.btnDownload.clicked.connect(self.download)
        self.myButton = QPushButton('Show Skillls')
        self.myButton.clicked.connect(self.showAllSkills)
        self.btnSearchByWord = QPushButton('Search by word(s)')
        self.btnSearchByWord.clicked.connect(self.onSearchByWord)
        self.btnResetFilter= QPushButton('Discard Filter')
        self.btnResetFilter.clicked.connect(self.discardFilter)
        self.btnCopyURL = QPushButton('URL to Clipboard')
        self.btnCopyURL.clicked.connect(self.copyToClipboard)
        self.btnExit = QPushButton('Exit')
        self.btnExit.clicked.connect(lambda: sys.exit())
        self.dateTimeStamp = QLabel()
        self.la1.addWidget(self.btnDownload)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.myButton)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.btnSearchByWord)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.btnResetFilter)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.btnCopyURL)
        self.la1.addSpacing(70)
        self.la1.addWidget(self.btnExit)
        self.la1.addStretch(stretch=0)
        self.la1.addWidget(self.dateTimeStamp)
        self.right.setLayout(self.la1)
        self.right.setFrameShape(QFrame.StyledPanel)

        # splitters
        self.horiSplit = QSplitter(Qt.Vertical)
        self.horiSplit.addWidget(self.upperLong)
        self.horiSplit.addWidget(self.lowerLong)
        self.horiSplit.setSizes([self.visota/2, self.visota/2])
        self.vertiSplit = QSplitter(Qt.Horizontal)
        self.vertiSplit.addWidget(self.horiSplit)
        self.vertiSplit.addWidget(self.right)
        self.vertiSplit.setSizes([self.shirina*3/4, self.shirina*1/4])
        self.setCentralWidget(self.vertiSplit)
        
        self.settings = QSettings('elance.ini', QSettings.IniFormat)
        self.settings.beginGroup('DATE_STAMP')
        self.dateTimeStamp.setText('Data actuality: %s' % self.settings.value('date/time'))
        self.settings.endGroup()
        self.statusText = ''

    def handleSelectionChanged(self, selected, deselected):
        for index in selected.first().indexes():
            #print('Row %d is selected' % index.row())
            ind = index.model().mapToSource(index)
            desc = ind.model().mylist[ind.row()]['Description']
            self.detailsLabel.setText(desc)
            skills = ', '.join(ind.model().mylist[ind.row()]['Skills']).strip()
            self.skillsLabel.setText(skills)
            url = ind.model().mylist[ind.row()]['URL']
            self.urlLabel.setText(url)
            location = ind.model().mylist[ind.row()]['Location']
            self.locationLabel.setText(location)
    
    def showAllSkills(self):
        listSkills = []
        for elem in self.source_model.mylist:
            listSkills += elem['Skills']
        allSkills = Counter(listSkills)
        tbl = MyTableModel(self, allSkills.items(), ['Skill', 'Freq'])
        win = skillsWindow(tbl, self.table_view)
        win.exec_()
    
    def discardFilter(self):
        self.table_view.model().emit(SIGNAL("modelAboutToBeReset()"))
        self.table_view.model().criteria = {}
        self.table_view.model().emit(SIGNAL("modelReset()"))
        self.table_view.resizeRowsToContents()
        
    def download(self):
        self.btnDownload.setDisabled(True)
        self.statusLabel = QLabel('Connecting')
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.myStatusBar.addWidget(self.statusLabel, 2)
        self.myStatusBar.addWidget(self.progressBar, 1)
        self.progressBar.setValue(1)
        self.settings.beginGroup('URLS')
        initialLink = self.settings.value('CategoriesDetailed/VahaSelected/InitialLink')
        pagingLink = self.settings.value('CategoriesDetailed/VahaSelected/PagingLink')
        self.settings.endGroup()
        downloader = Downloader(initialLink, pagingLink, 25, 5)
        downloader.messenger.downloadProgressChanged.connect(self.onDownloadProgressChanged)
        downloader.messenger.downloadComplete.connect(self.onDownloadComplete)
        downloader.download()
    
    def onDownloadComplete(self):
        #QMessageBox.information(self, 'Download complete', 'Download complete!', QMessageBox.Ok)
        self.table_view.model().emit(SIGNAL("modelAboutToBeReset()"))
        self.settings.beginGroup('DATE_STAMP')
        self.settings.setValue('date/time', time.strftime('%d-%b-%Y, %H:%M:%S'))
        self.dateTimeStamp.setText('Data actuality: %s' % self.settings.value('date/time'))
        self.settings.endGroup()
        with open("elance.json") as json_file:
            jobDB = json.load(json_file)
        for elem in jobDB:
            words = nltk.tokenize.regexp_tokenize(elem['Title'].lower(), r'\w+')
            elem['Tokens'] = words
            elem['Skills'] = [t.strip() for t in elem['Skills'].split(',')]
        self.source_model.mylist = jobDB
        self.table_view.model().emit(SIGNAL("modelReset()"))
        self.btnDownload.setEnabled(True)
        self.myStatusBar.removeWidget(self.statusLabel)
        self.myStatusBar.removeWidget(self.progressBar)
        self.myStatusBar.showMessage(self.statusText, timeout = 5000)
                
    
    def onDownloadProgressChanged(self, stata):
        self.progressBar.setValue(stata[2])
        #text = 'Processed records{:5d} of{:5d}'.format(percentage[0], percentage[1])
        bajtikov = '{:,}'.format(stata[5])
        self.statusText = 'Processed page{:4d} of{:4d}. \
               Job entries{:5d} of{:5d}. \
               Downloaded{:>12s} Bytes'.format(stata[3], stata[4],
                                              stata[0], stata[1],
                                              bajtikov)
        self.statusLabel.setText(self.statusText)
        
    def copyToClipboard(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.urlLabel.text())
        self.myStatusBar.showMessage(self.urlLabel.text(), timeout = 3000)
    
    def onSearchByWord(self):
        text, ok = QInputDialog.getText(self, 'Search the base by word(s)', 'Enter your keyword/phrase to search for:')
        if ok:
            words = [t.strip() for t in nltk.tokenize.regexp_tokenize(text.lower(), r'\w+')]
            self.table_view.model().emit(SIGNAL("modelAboutToBeReset()"))
            self.table_view.model().criteria = {'Description' : words}
            self.table_view.model().emit(SIGNAL("modelReset()"))