Ответы пользователя по тегу PyQt
  • Множественное наследований Python?

    @Sergey6661313
    в python и в qt наследованием обозначаются разные вещи...
    в python имеется в виду что потомки порождаются с такими же методами что и родители, а в qt имеется в виду просто ссылка у потомков о том кто их породил. и у родителей просто список их детей..
    В связи с тем что я не вижу в вашем случае смысла объекту ConnectionClass иметь методы ProfilerAppClass то предположу что вам нужны просто ссылки на детей и родителей.

    class MainWindowClass(QMainWindow):
        def __init__(self, parent)
        super().__init__(parent)
        self.parent = parent  # - просто создаём себе переменную где указываем родителя. Который передаётся при создании экземпляра. 
    
    
    class LoginWindowClass(QWidget):
        def __init__(self, parent)
            super().__init__(parent)
            self.parent = parent
    
    class ConnectionClass(QTcpServer):
        def __init__(self, parent)
            super().__init__(parent)
            self.parent = parent
    
    class ProfilerAppClass():
        def __init__():
            self.childs = {  # и список чайлдов...  хотя QT по идее сам должен был составить подобный список, и вообще не понятно зачем отдельный клас, можно сразу использовать словарь...
                "MainWindow": MainWindowClass(self)
                "LoginWindow": LoginWindowClass(self)
                "Connection": ConnectionClass(self)
            }
            
    ProfilerApp = ProfilerAppClass()
    ProfilerApp.childs.get("MainWindow").show()
    Ответ написан
  • Как правильно пользоваться таймером в PyQt?

    @Sergey6661313
    Ваш код делает именно то что вы и написали.
    timer.start(1000) - запускает таймер
    timer.stop() - останавливает таймер. При чём в нашем случае ещё до реального запуска таймера т.к. app.exec() ещё даже не запущен.
    Каких действий вы от него ожидаете если вы его остановили???
    Ответ написан
  • Как прикрутить GUI к скрипту Python?

    @Sergey6661313
    В общем в крастце
    Вам надо создать обьект класса QApplication
    и в конце кода заместо app.start выполнять QApplication.exec([])
    естественно вам придётся так же создать qwidget и назначить eму setupUi из Ui_Dialog

    и конечно привязать кнопочку к вашей комманде start
    можно так:
    pbStart.clicked.connect(app.start)
    или как написал товарищ tsarevfs

    значения ptt_key присваиваются так:
    hex_str = uidialog.leButtonCode.text() # получаем текст из окошка
    hex_int = int(hex_str, 16) # превращяем в число
    hex_key = hex(hex_int) # обратно в hex
    self.set_ptt_key(hex_int) # И... получите распишитесь.

    Я немного пописал код вы можете глянуть на github

    Ответ написан
  • Почему кнопка не срабатывает?

    @Sergey6661313
    Ну про глобальную - это я погорячился.... потому что вы её уже сделали дочкой root при создании. (и этого типо хватает)

    Как временное решение могу лишь предложить вызывать show() после создания и указания координат.
    newLabel.show() - это заставит его в любом случае появиться.... но я не знаю является ли это "совсем точно "правильным решением...
    Ответ написан
  • PyQT браузер и встроенный внутри yandex iframe. Как "починить" кнопку внутри iframe для принятия платежей?

    @Sergey6661313
    Этот вариант на pyqt5 работает. Проверено.

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import webbrowser
    from PyQt5.QtWidgets import *
    from PyQt5.QtWebEngineWidgets import *
    
    s = str("""<!DOCTYPE html>
             <html>
            <head></head>
             <div style="text-align: center;">
             <iframe frameborder="0" allowtransparency="true" scrolling="no" src="https://money.yandex.ru/quickpay/shop-widget?account=410013878567203&quickpay=shop&payment-type-choice=on&mobile-payment-type-choice=on&writer=seller&targets=asdf&targets-hint=&default-sum=&button-text=01&successURL="" width="450" height="200"></iframe>
             </div>
              <div>
            <a href="http://google.com">TEST LINK</a>
             </div>
             </body>
             </html>""")
    
    
    class MainWindow(QWidget):
        def __init__(self, parent=None):
            QWidget.__init__(self, parent)
            self.resize(700, 400)
            self.view = QWebEngineView(self)
    
            mypage = MyPage(self.view)
            self.view.setPage(mypage)
            mypage.setHtml(s)
    
            grid = QGridLayout()
            grid.addWidget(self.view, 0, 0)
            self.setLayout(grid)
            self.show()
    
    class MyPage(QWebEnginePage):
        def __init__(self, parent):
            super().__init__(parent)
            self.in_window = False      # придумал переменную
    
        def createWindow(self, type):   # которую мы
            self.in_window = True       # тутже изменяем если просится
            return self                 # открытие в новом окне
    
        def acceptNavigationRequest(self, QUrl, type, isMainFrame):
            url_string = QUrl.toString()
            print(type, isMainFrame, QUrl)
            if  self.in_window and type==2 and url_string != "https://money.yandex.ru/quickpay/confirm.xml":
                webbrowser.open(url_string)
                self.in_window = False
                self.setHtml(s)
            return True
    
    
    
    
    if __name__ == '__main__':
        app = None
        if not QApplication.instance():
            app = QApplication([])
        dlg = MainWindow()
        if app: app.exec_()
    Ответ написан
  • PyQt5 - почему не определяет размер шрифта?

    @Sergey6661313
    в pyqt5 Qstring выпилили и считают что str лучше подходит для этого дела.... toPlainText() возвращает str да ещё и без формата (т.е. просто выводит то что видно на экране):
    print (type(text))
    <class 'str'>.

    из которого узнавать шрифт бессмысленно.

    Я вижу выход только - использовать toHtml()
    как то так:

    from PyQt5 import Qt
    app = Qt.QApplication([])
    
    textEdit = Qt.QTextEdit()
    textEdit.show()
    
    secret = "<H4>test<H2>L, <H3>L"
    textEdit.setText(secret)
    
    html = textEdit.toHtml()
    td = Qt.QTextDocument()
    td.setHtml(html)
    
    formats = td.allFormats()
    print(formats)
    
    app.exec_()
    Ответ написан
  • Почему QKeyEvent не работает без окна?

    @Sergey6661313
    События в pyqt могут получать только унаследованные от QObject обьекты. Потому что внутри их кода и кода в библиотеках qt есть код который "посылает" сообщения и вызывает в объектах метод keyPressEvent . Вы же создаёте новый класс Frame и не унаследуете для него никакие Qt-шные функции. Поэтому функция keyPressEvent не будет в нём вызвана никогда.
    Это ответ на вопрос "почему"... а вот ответить как сделать правильно на Qt я не могу...

    Однако могу посоветовать копать в сторону сторонней библиотеке keyboard которая в принципе может и без Qt:
    import keyboard
    
    while True:
        print(keyboard.is_pressed("space"))   # printed True or False
    Ответ написан
  • Как исправить ошибку с PyQT5?

    @Sergey6661313
    там на семёрке случаем не 32-битная система?
    Я везде таскаю с собой только 32-битную сборку python-а с предустановленным в него pyqt и
    библиотеку Microsoft Visual C++ 2010 x86 (он маленький 5 мб всего).

    Ещё возможно проблема в правах к самой папки... Если вы не являетесь владельцем папки, то винда может устраивать такие подлянки...
    Ответ написан
  • Как переменной присвоить значения введённые в QLineEdit?

    @Sergey6661313
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    # вообще достаточно просто преобразовывать текст в число и работать с ним:
    def prostoe_preobrazovanie_texta_v_chislo(text):
        try:                    # а вдруг там не число, а хрен пойми что?
            chislo = int(text)  # собственно вот нужная нам строчка...
            return chislo
        except Exception:
            return False
    
    # но иногда приходится выковыривать число из текста:
    def slojnoe_raspoznovanie_chisla(text):
        try:                    # а вдруг там число всё же где то есть?
            import re
            chislo = int(re.findall('(\d+)', text)[0])  # магия!
            return chislo
        except Exception:
            return False
    
    # ну и конечно обратное действие:
    def preobrazovanie_chisla_v_text(i):
        return str(i)
    
    
    
    # вообще для чисел был специально придуман QSpinBox и QDoubleSpinBox
    
    # но отвечая на Ваш вопрос мы всё же сделаем и вариант с QLineEdit
    from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, QApplication, QPushButton, QBoxLayout, QDoubleSpinBox)
    from PyQt5.Qt import Qt
    
    class Example(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            layout = QBoxLayout(QBoxLayout.Down, self)  # - это для компоновки
    
            self.qle = QLineEdit("", self)              # почему lbl в локальной видимости а qle нет?
            # self - тут очень важно иначе как вы будете обращятся к своему qle?
    
            self.qle.setPlaceholderText("Например: 56") #  - самая крутая killer фича...
            layout.addWidget(self.qle)                  #  - ну и отдаём его компоновщику...
    
            button = QPushButton("математика!")         #  - вы же хотели ещё и кнопку да?
            button.pressed.connect(self.my_super_puper_function)  # вот так соединяем нажатие с методом
            layout.addWidget(button)                    #  - уж попроще всяких button.move(60, 40)
    
            self.spinbox = QDoubleSpinBox()             #  - пример виджета который изначально под это заточен
            self.spinbox.setRange(0, 99999999)          # к сожелению по умолчанию там стоят жёсткие ограничения
            layout.addWidget(self.spinbox)
    
            self.lbl = QLabel("\n\n\n")                 #  - это ведь label - я угадал?
            layout.addWidget(self.lbl)
    
            self.setWindowTitle('Простой пример')
            self.show()
    
        def keyPressEvent(self, e):
            if e.key() == Qt.Key_Enter:
                self.my_super_puper_function()          # а что мешало прямо тут реализовывать математику?
                                                        # ну мы же ещё и кнопку хотим подключить на то же самое...
    
        def my_super_puper_function(self):              # та самя функция...
            # в большинстве случаев математика не работает потому что в qlineedit изначально распологаются не числа,
            # а текст. Ну и как вы к "абвгд" прибавите 10 ?
            # никак... сначало нам нужно убедится что там действительно число:
            i = self.proverki_na_chislo()               # вообщемто просто: я вынес всю магию в отдельный метод...
            # и этот метод возвращяет число именно числом а не текстом.
    
            if i:                                       # если там вообще число, тогда:
                self.matematika(i)                      #   математику в студию!
    
    
        def matematika(self, a):  #  я думаю в комментариях не нуждается...
            b = a * 7 * 1443      #  моя любимая математика: она утраивает двухзначное число :)
    
            # со spinbox-м просто:
            self.spinbox.setValue(b / 11111 * 12345 / 54321 * 5)  # будет работать, я гарантирую...
    
            # а вот для qlineedit тяжелее:
            b_text = preobrazovanie_chisla_v_text(b) # число нужно сначало сделать текстом.
            self.qle.setText(b_text)                 # и лишь потом выводить.
    
    
            #  ну и всякие смехуёчки..., куда же без них?
            if b < 10**10:
                self.lbl.setText("Конкретная математика - для реальныйх пацанов!")
            else:
                self.lbl.setText("ОЛОЛОЛО!!!!")
    
    
        # а этом вообщем то следовало бы остановится...
        # но мой qt вылетает без предупреждений если в lineEdit вписать хоть одну букву...
        # и тут меня понесло:
        def proverki_na_chislo(self):
            text = self.qle.text()
            if text != "":                                      # если наше поле не пустое
                i = prostoe_preobrazovanie_texta_v_chislo(text) #   пробуем простое преобразование
                if i:                                           #   ну и если удечно:
                    return i                                    #       выходим из этой функции уже с числом.
    
                i = slojnoe_raspoznovanie_chisla(text)          #   а если так и не вышли то пробуем более сложное.
                if i:
                    self.lbl.setText(text + " - разве это число?\n" + "тут конечно есть число: " + str(i) + "\nно я с ним ничего решать не буду!")
                    return i
    
                self.lbl.setText("Пожалуйста не материтесь...") # в противном случае скорее всего число вообще не написано:
                return False
            else:
                self.lbl.setText("нужно вписать число!")
                return False
    
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        ex = Example()
        ex.show()
        sys.exit(app.exec_())  # без этого ничего не запустится...
    
    
    # как то-так... ну вы держитесь там. Всего вам доброго!
    Ответ написан
  • PyQt4. Как свернуть окно при нажатии на кнопку?

    @Sergey6661313
    # кнопка: http://pyqt.sourceforge.net/Docs/PyQt4/qpushbutton.html
    min = QPushButton()
    
    # минимизация:  http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html#showMinimized
    def minimization():
        min.showMinimized()
    
    # связывание с нажатием: http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html
    min.pressed.connect(minimization)
    Ответ написан
  • Python - как реализовать ООП с PyQt (connect)?

    @Sergey6661313
    # у меня python версии 3.5
    # pyqt - 5-ой версии.
    
    ## Минимальная затравка для запуска кода  :
    # coding=UTF8
    # это чтобы можно было переменные по русски называть.
    #  обязательно при этом сохранять py фаил в UTF
    
    # импорты:
    import sys
    from PyQt5.Qt import QApplication, QPushButton, QFileDialog,\
        QTableWidget, QTableWidgetItem, QGridLayout, QWidget, pyqtSignal
    app = QApplication([])
    
    # ну а теперь будем мудрить. Честно говоря ваш уровень
    #  владения python-м совсем не ясен. Потому начнём с супер нуля.
    # None и pass - обозначают пустату (т.е. ничто).
    #  Она нам понадобится в дальнейшем :).
    
    кнопка = None       # надеюсь понятия переменные
    #  обьяснять не надо. Кнопку назовём кнопка.
    # КЭП уплывёт, а кнопка останется в памяти интерпретатора.
    
    # для начало нам нужно знать что всё что отображается
    #  на экране это какие то объекты, а не их описание.
    class open_kn(QPushButton): pass    # - это описание.
    #  Оно как ДНК для будущего ребёнка,
    #  но при этом само ребёнком не является.
    
    # детки создаются как-то так:
    open_kn()           # - это создание экземпляра класса.
    # Мы как бы говорим интерпретатору что хотим "породить"
    #  один экземпляр всего того что описано в "ДНК" open_kn.
    # при этом обычно выполняются все инструкции в нутри
    #  конструктора класса (это тот который def __init__)
    # но у нас пока что такой метод не назначен поэтому
    #  "ребёнок" просто унаследует всё что есть в QPushButton
    
    # но созданный экземпляр как и КЭП появившись и
    # пояснив компьютеру что мы от него хотим сразу самовыпиливается.
    # поэтому нам нужна переменная для его хранения:
    кнопка = open_kn()      # кнопка - наш ребёнок, а  open_kn - наше ДНК.
    
    # так нам надо ещё сделать на ней текст и заставить отрисовыватся на экране:
    # вообще эти два метода могли быть и в конструкторе :
    class open_kn(QPushButton):
        def __init__(self):
            # а кстати да - методы создаются именно через
            #  def %название_метода%(аргументы):
            self.setText('Open')    # устанавливаем текст на кнопке
    
    # но всё это нафиг не нужно если в вашем классе всего
    #  один метод, и тот конструктор -
    # тогда зачем вам вообще такой класс?
    кнопка = QPushButton()
    кнопка.setText('Open')
    
    def всё_что_будет_происходить_при_нажатии_на_кнопку():
        # аналогично не обязательно переопределять целый класс FileDialog всего для одного метода...
        # так с кнопкой разобрались. Теперь нам нужен диалог и таблица.
        fileName = QFileDialog.getOpenFileName \
            (кнопка, 'Простой пример', 'd:\\',"Текст (*.txt)")[0] # ваш код, не буду его коментировать.
        f = open(fileName, 'r', encoding="utf8")
        # я добавил encoding="utf8" потому что мои txt именно в таком формате
        # кстати говоря именно ваши "try, except" и скрывают от вас настоящию ошибку.
        # "Неожиданная ошибка:" - очень информативно...
    
        # тут пока без изменеинй.
        data = []
        with f as f:
            for i in f.readlines():
                data.append(i)
    
        # TableWidget.data = data # ага какой нафиг TableWidget когда мы его ещё не определили?
        #  впрочем х*@ с ним...
        # вы же сами сказали что ваш table в HBox4 ? значит путь бедет примерно такой:
        экземпляр_класса_HBox4.table.update(data) # мы просто напрямую вызываем нужный нам метод
    
    # РИСУЕМ!
    
    class TableWidget(QTableWidget):
        #  я немного переделал: сразу перенёс всю настройку таблици в метод update
    
        def __init__(self, parent=None, data=[]):
            super(TableWidget, self).__init__(parent)
            self.update() # ну и чтобы не повторятся просто вызываю этот метод
    
        def update(self, data=[]):
            self.setColumnCount(1)
            self.setRowCount(len(data))
            for i, entry in enumerate(data, start=1): # у вас "нулевая" строка в txt
                #  - комментарий?
                self.setRowCount(i)
                item = QTableWidgetItem()
                item.setText(str(entry))
                self.setItem(i-1, 0, item) #  - либо тут "-1" либо начинать с нулевого элемента,
                #  либо в setRowCount делать +1...
            print(data) # - для отладки посмотрим: а вдруг данные всё таки передаются,
            #  а в таблицу не пишутся?
    
    class HBox4(QGridLayout):
        def __init__(self, parent=None):
            super(HBox4, self).__init__(parent)
            table = TableWidget()       # - так не правильно.
            # поясню: Вы  только что создали переменную внутри метода.
            #  фишка в том что python по окончании метода
            #  забывает напроч обо всех созданных внутри него переменных. так-то.
            self.table = TableWidget()  # - так правильно. + мы сможем к нему обращятся.
            self.addWidget(кнопка, 0, 0)
            self.addWidget(self.table, 1, 0)
    
    экземпляр_класса_HBox4 = HBox4()
    
    # сам QGridLayout отображатся не умеет вне виджета
    #  я создам для него виджет.
    widget = QWidget()
    widget.setLayout(экземпляр_класса_HBox4)
    widget.show()       # пуф!..
    
    # да мы забыли связать события нажатия на кнопку и наш метод:
    кнопка.pressed.connect(всё_что_будет_происходить_при_нажатии_на_кнопку)
    
    
    
    
    #В принципе на этом можно было бы и остановится,
    #  но в идеале было бы пользоватся сигналами и слотами:
    #  они вам понадобятся позже когда вы начнёте вызывать методы одновременно
    #  или например из потоков.
    class TableWidget(QTableWidget):
        my_signal_update = pyqtSignal(list) # придумываем сигнал my_signal_update
        # (в качесте параметров он принимать будет list (там могло быть что угодно: int, str)
    
        def __init__(self, parent=None, data=[]):
            super(TableWidget, self).__init__(parent)
            self.update()
            self.my_signal_update.connect(self.update) # добавлено
    
        def my_slot_update(self, data):     # добавлено
            print(data, flush=True)         # добавлено
            self.update()                   # добавлено
    
        # ну а дальше без изменений.
        def update(self, data=[]):
            self.setColumnCount(1)
            self.setRowCount(len(data))
            for i, entry in enumerate(data, start=1):
                self.setRowCount(i)
                item = QTableWidgetItem()
                item.setText(str(entry))
                self.setItem(i-1, 0, item)
    
    def всё_что_будет_происходить_при_нажатии_на_кнопку():
        fileName = QFileDialog.getOpenFileName \
            (кнопка, 'Пример с сигналом и слотом', 'd:\\', "Текст (*.txt)")[0]
        f = open(fileName, 'r',  encoding="utf8")
        data = []
        with f as f:
            for i in f.readlines():
                data.append(i)
        table.my_signal_update.emit(data)  # мы просто НЕ напрямую вызываем нужный нам метод...
    
    кнопка.pressed.connect(всё_что_будет_происходить_при_нажатии_на_кнопку)
    
    table = TableWidget()
    экземпляр_класса_HBox4.addWidget(table, 2, 0)
    
    
    
    
    # ну и последний кусочек для минимальнно рабочего приложения на pyqt
    app.exec_() # без этого ничего не запустится...
    Ответ написан
  • Почему при компиляции и запуска кода ничего не выводит на экран?

    @Sergey6661313
    Вообще как вы используете uic?
    чтобы создать запускаемый фаил надо использовать ключ "-x"
    например так:
    pyuic4.bat -x other.ui -o other.py

    и тогда к вашему коду будет добавлено что-то вроде:
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        Form = QtGui.QWidget()
        ui = Ui_Form()
        ui.setupUi(Form)
        Form.show()
        sys.exit(app.exec_())


    Посмотрите на ваш код без куска выше - глазами транслятора:
    1) импортируем что-то...
    2) пробуем назначить переменную _fromUtf8 и метод для неё. Выделяем под них память
    3) пробуем назначить переменную _encoding и метод для неё. Выделяем под них память
    4) какой то непонятный класс Ui_Form - выделяем под него память
    4.5) ага там ещё и 2 метода. Мы под них в памяти место выделим, а использовать потом будет если его конечно вызовут...
    5) код кончился.
    Эй программист! Код кончился, что мне делать дальше !?. А завершусь ка я...
    Process finished...

    Как ответил abcd0x00 вам необходимо либо наследовать эту форму, либо вызвать её.
    Почитайте вводные курсы по pyqt например от Прохоренока Н.А. - самое начало:
    для запуска pyqt приложений должно быть инициализировано PyQt4.QtGui.QApplication
    затем инициировать все ваши формы и потом чтобы приложение вдруг не завершилось (потому что на этом код и кончится) выполнить QApplication.exec(), который заставить python интерпретатор бесконечно перерисовывать и обновлять состояние ваших форм.
    Да-да именно так и работают все программы (не только на pyqt).
    Ответ написан
  • Как заполнить таблицу в PyQt5? Почему не работает так?

    @Sergey6661313
    Супер просто: строка table.setRowCount(i) обозначает дословно: установить количество строчек. Дальше сами догадаетесь?

    Если всё ещё не догадались:
    Если в цикле указкать print(i) станет понятно почему не получается.

    Всё ещё нет? enumerate начинает итерации с нуля. т.е. в первой итерации получится так: "установить количество строк равное нулю, и поставить в первую строку entry."
    во второй итерации: "установить колличество строк равное 1, и пытаться поставить во вторую из них entry".
    и т.д.

    Короче ответ надо заместо table.setRowCount(i) установить table.setRowCount(i+1)

    и я бы на вашем месте делал не:
    entry = str(entry)
    item = QTableWidgetItem(entry)

    а:
    item = QTableWidgetItem()
    item.setText(str(entry))

    Потому что явное лучше не явного. Ну это так мелочи.....................................................ж
    Ответ написан
  • Управления временем в Python?

    @Sergey6661313
    в __init__:
    self.timer = QtCore.QBasicTimer()
    self.timer.start(1000, self) # 1000 - наша задержка (должна быть в миллисекундах помоему)

    и определите метод:
    def timerEvent(self, event)
    self.follow.setValue(self.follow.value() - 1)

    и да переменная hp не нужна. follow уже содержит переменную доступ к которой осуществляется через value() и setValue(), поэтому плодить сущности незачем.

    В кратце QBasicTimer это что-то вроде Qthread котороый каждые обозначенные миллисекунды вызывает событие timerEvent обозначенного обьекта.
    Ответ написан
  • PyQt5 вывод результата функции в окно виджета?

    @Sergey6661313
    1) для кода есть специальная кнопочка при оформлении вопроса (3 точки и выбрать code)
    2) написали бы хотябы как именно пытались установить в форму текст. Ну например хотябы так:
    def buttonClicked(self):
            print((a[9:]))
            window.tree.setText(str(a[9:]))
            sender = self.sender()

    А потом уже код ошибки или на что он у вас там ругается...
    Ответ написан
  • PyQt Как проставить connect для неизвестного количества кнопок на форме?

    @Sergey6661313
    Наверное больше никогда не буду пользоваться лямбдами. Не ожидал такого подвоха от них.

    # coding=utf-8
    
    import sys
    from PyQt4 import QtGui
    from PyQt4.QtGui import QPushButton, QTableWidget
    from PyQt4.Qt import QApplication
    window = QApplication(sys.argv)
    
    class myTable(QTableWidget):
        class MyCustomEditButton(QPushButton):
            def __init__(self, i, name):
                self.i = i
                super().__init__(name)
                self.clicked.connect(self.slot_pressed)
    
            def slot_pressed(self):
                window.tableWidget.StartStop(self.i)
    
    
        def __init__(self):
            super().__init__()
            self.data = [
                ["1 строка"],
                ["2 строка"],
                ["3 строка"],
                ["4 строка"],
                ["5 строка"]
            ]
            self.datacount = len(self.data)
            self.setColumnCount(len(self.data[0])+1)
            self.setRowCount(self.datacount)
    
            for i in range(self.datacount):
                btn = self.MyCustomEditButton(i, "Edit")
    
                self.data0 = str(self.data[i][0])
                self.setItem(i, 0, QtGui.QTableWidgetItem(self.data0))
                self.setCellWidget(i, 1, btn)
    
        def StartStop(self, bb):
            print(bb)
    
    
    window.tableWidget = myTable()
    window.tableWidget.show()
    window.exec()


    Пробуйте, разбирайте. Вообще странное поведение питона. Как то не инстинктивно.
    Ответ написан
  • Почему при вызове setHtml программа вылетает?

    @Sergey6661313
    res = requests.get('http://URL/'+trek+".html")
    orly?
    ну ей богу написали хотя бы "yandex.ru/index.html" для примера.

    без объяснения причин
    ну пожалуйста пользуйтесь pycharm - есть бесплатная редакция. Он честно открывает консоль для каждой запущенной программы. В которую честно пишется причина. И которая, Самое главное, не закрывается после ошибки.

    куски кода надо делать минимальными, НО запускаемыми. например такими:
    import sys
    import requests
    import os
    from PyQt5.QtWidgets import QTextBrowser
    from PyQt5.Qt import QApplication
    from PyQt5.Qt import QThread
    
    trek = "index"
    myapp = QApplication(sys.argv)
    myapp.textBrowser = QTextBrowser()
    
    class ExperementalThread(QThread):
        def run(self):
            if os.path.exists("temp/"+trek+".html"):  # Если страница уже была ранее загружена
                with open("temp/"+trek+".html") as w:
                    myapp.textBrowser.setHtml(w.read())  # ни разу не вылетело
            else:
                res = requests.get('http://yandex.ru/'+trek+".html")
                res.encoding = 'utf-8'
                with open("temp/"+trek+".html", "w") as ri:
                    ri.write(res.text)
                myapp.textBrowser.setHtml(res.text)  # И здесь
    
    thread = ExperementalThread()
    myapp.textBrowser.show()
    thread.start()
    myapp.exec()


    и ошибка соотв. будет QObject: Cannot create children for a parent that is in a different thread.
    что значит что метод setHtml пытается для себя создать отдельный поток. А потоки из потоков создавать запретил сам батюшка Ленин ( цитата от ██.██.19██г. ).

    Значит придётся использовать сигналы и слоты.
    я создал свой класс MyQTextBrowser с наследованием QTextBrowser и сигналом signal_load_html. Который в свою очередь связал с setHTML.

    # coding=utf-8
    
    import sys, requests, os                            # импортировали,
    from PyQt5.Qt        import QApplication, QThread   # импортировали,
    from PyQt5.QtCore    import pyqtSignal              # да не
    from PyQt5.QtWidgets import QTextBrowser            # выпереимпортировали.
    
    trek = "index"                                      # ну в самом деле надо же указать чему равна ваша переменная.
    myapp = QApplication(sys.argv)                      # я угадал?
                                                        # обязательно делаем отступы перед каждым классом
    class MyQTextBrowser(QTextBrowser):                 # создаём класс и наследуем QTextBrowser
        signal_load_html = pyqtSignal(str)              # назначаем сигнал (сигнал принимает значение str (строки) )
                                                        # тут тоже отступ
        def __init__(self):                             # переназначаем метод создания объектов
            super().__init__()                          # наследуем/выполняем QTextBrowser.__init__(self)
            self.signal_load_html.connect(self.setHtml) # тут связываем наш сигнал с setHtml
    myapp.textBrowser = MyQTextBrowser()                # ну и создаём вообщемто обьект нашего класса MyQTextBrowser
                                                        # обязательно делаем отступы после каджого класса.
                                                        # обязательно делаем отступы перед каждым классом
    class ExperementalThread(QThread):                  # названия придумываем на ходу
        def run(self):                                  # init не нужен сразу run
            if os.path.exists("temp/"+trek+".html"):    # Если страница уже была ранее загружена
                with open("temp/"+trek+".html") as w:   # открываем наш фаил в папке temp
                    # myapp.textBrowser.setHtml(w.read())  # вылетает? у меня кстати нет, но я читер :)
                    myapp.textBrowser.signal_load_html.emit(w.read())  # ни разу не вылетело.
            else:                                       # люблю когда много коментариев в коде
                res = requests.get('http://yandex.ru/'+trek+".html") # "Люблю говорить - это помогает думать."
                res.encoding = 'utf-8'                  # -- Томас Стернз Элиот
                with open("temp/"+trek+".html", "w") as ri: # когда этот код уже кончится?
                    ri.write(res.text)                  # тут пусто потому что в оригинале у вас был "URL" а не yandex
                # myapp.textBrowser.setHtml(res.text)   # И здесь
                myapp.textBrowser.signal_load_html.emit(res.text)  # ни разу не вылетело
                                                        # обязательно делаем отступы после каждого класса.
    thread = ExperementalThread()                       # создаём наш поток
    myapp.textBrowser.show()                            # ах да - самое главное показать окно. Иначе ничего не произойдёт
    thread.start()                                      # запускаем поток
    myapp.exec()                                        # Ой, всё!()


    p.s.
    Вообще setHtml не метод QTextBrowser. Это метод из QTextEdit (который QTextBrowser наслеует. ) Сам же QTextBrowser создан для того чтобы самостоятельно загружать и показывать страницы с интернета. (по урлу.)
    Ответ написан
  • Питон добавление в ComboBox?

    @Sergey6661313
    бла-бла-бла создавать comboBox как переменную создаваемого объекта OpenFile:
    class OpenFile(QtGui.QMainWindow):
        def __init__(self, parent=None):
          ...   ...   ...
          self.comboBox = QtGui.QComboBox(self)
          self.comboBox.setGeometry(QtCore.QRect(25, 55, 125, 25))
          self.comboBox.setObjectName(self.trUtf8("comboBox"))

    тогда в методе showDialog можно обратится к self.comboBox:

    for sName in wbr.sheet_names():
            sheetName.append(wbr.sheet_by_name(sName))
            self.comboBox.addItem(str(sName))


    бла-бла-бла узнать его индекс можно методом currentIndex()
    sheet = wbr.sheet_by_index(self.comboBox.currentIndex())


    бла-бла-бал отдельным методом бла-бла-бла.
    ____________________________________________________________________________________________
    дополнение к ответу:
    подытожим: мы уже заменили все comboBox на self.comboBox (вы ведь так сделали ?)
    убрали к (недружелюбное слово) sheetName и цикл его заполнения. (зачем он вам если у вас есть отличный comboBox?)
    так же сам wbr нам тоже придётся сделать "долгоиграющей" переменной (мы его будем использовать в нашем "отдельном" методе, поэтому потерять его будет катастрофой. )

    т.е довели метод def showDialog(self):
    до след. 3-х строчек:
    filename = QtGui.QFileDialog.getOpenFileName(self, 'Выбор файла', '*xls')
    self.wbr = xlrd.open_workbook(filename, formatting_info=True)
    self.comboBox.addItems(self.wbr.sheet_names())

    Что же делать со всем этим кодом ниже?
    ну можно сделать ещё одну кнопочку "писать_в_csv" и метод-слот для вашего кода.
    пример для связи кнопки и метода уже есть в вашем примере. нужно просто перед вашим кодом написать def вставте_суда_любое_название(self): и кнопку продублировать просто указать другое имя и другие координаты и там где connect поменять всё соответственно. И просто нажимать на кнопку после того как выберете лист.
    class OpenFile(QtGui.QMainWindow):
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self, parent)
            ...  ...  ...
    
            pButton2 = QtGui.QPushButton('записать в csv', self)
            pButton2.setGeometry(175, 55, 125, 25)
            self.connect(pButton2, QtCore.SIGNAL('clicked()'), self.slot_list_selected)
    
        def showDialog(self):
            filename = QtGui.QFileDialog.getOpenFileName(self, 'Выбор файла', '*xls')
            self.wbr = xlrd.open_workbook(filename, formatting_info=True)
            self.comboBox.addItems(self.wbr.sheet_names())
    
        def slot_list_selected(self):
            # //////////////////Индекс листа///////////////////////
            sheet = self.wbr.sheet_by_index(self.comboBox.currentIndex())
    
            ... ... ...


    Но мы же не ищем легких путей ведь так?
    + мы хотим познакомится с QT поближе.
    наш тру вариант без участия дополнительной кнопки:
    метод я назвал slot_list_selected. и мы его соединим непосредственно с сигналом изменения combobox-а так:
    self.comboBox.currentIndexChanged.connect(self.slot_list_selected) - это альтернативный более коротки метод связывания сигналов и слотов (чем self.connect(self.comboBox, QtCore.SIGNAL('currentIndexChanged(int)'), self.slot_list_selected) )
    но есть запарка - сигнал не только вызывает метод но и передает ему int (выбранный индекс). Значит наш слот-метод должен его принимать.
    def slot_list_selected(self, list_index):
    ну и так как он нам всё равно передается мы могли бы его сразу использовать.
    заместо sheet = self.wbr.sheet_by_index(self.comboBox.currentIndex())
    sheet = self.wbr.sheet_by_index(list_index)
    в принципе дальше ваш магический код вроде прекрасно работает. но он будет вызыватся в момент когда мы заполняем наш comboBox (изначально пустой combo показывает "-1", а когда заполняем его значение становится "0" что вызывает сигнал currentIndexChanged)
    это решается выключением сигналов коммандой self.comboBox.blockSignals(True)
    Но и тут вылезут подводные камни: в частности по умолчанию выберется первый элемент(с индексом 0) и попытавшись его выбрать индекс не изменится.
    тут опять 2 выхода:
    1) сделать первым итемом не имя листа а свой собственный. (если его ещё и назвать "выберите лист", то это будет служить дополнительной подсказкой для пользователя.)

    переписываем self.comboBox.addItems(self.wbr.sheet_names()) на
    self.comboBox.addItems(["выберите лист"] + self.wbr.sheet_names())
    т.к. индексы сместились то и sheet вычисляем с индексом -1:
    sheet = self.wbr.sheet_by_index(list_index-1)
    и придется делать проверку на то что list_index больше нуля. (мы же не хотим читать лист под номером "-1")
    if list_index:
    ваш код.

    вдоволь наигравшись с вашей программой замечаем что comboBox при выборе фаила заполняется но при этом не стирает предыдущие значения.
    исправляем добавляя перед additems
    self.comboBox.clear()

    вроде бы всё хорошо.

    2) более простой способ:
    просто использовать сигнал activated вместо currentIndexChanged тогда оно будет реагировать даже на выбор уже выбранного. Но я всё равно рекомендую проделать операции из первого способа.

    Суммарный код:
    class OpenFile(QtGui.QMainWindow):
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self, parent)
            self.setGeometry(300, 300, 325, 100)
            self.setWindowTitle(self.trUtf8('Выбор файла'))
            self.setWindowIcon(QtGui.QIcon('imageformats\icon.jpeg'))
    
            pButton = QtGui.QPushButton('Открыть файл', self)
            pButton.setGeometry(25, 15, 125, 25)
            self.connect(pButton, QtCore.SIGNAL('clicked()'), self.showDialog)
    
            quit = QtGui.QPushButton('Выход', self)
            quit.setGeometry(175, 15, 125, 25)
            self.connect(quit, QtCore.SIGNAL('clicked()'),
                         QtGui.qApp, QtCore.SLOT('quit()'))
    
            self.comboBox = QtGui.QComboBox(self)
            self.comboBox.setGeometry(QtCore.QRect(25, 55, 125, 25))
            self.comboBox.setObjectName(self.trUtf8("comboBox"))
            self.comboBox.activated.connect(self.slot_list_selected)
    
        def showDialog(self):
            filename = QtGui.QFileDialog.getOpenFileName(self, 'Выбор файла', '*xls')
            self.wbr = xlrd.open_workbook(filename, formatting_info=True)
            self.comboBox.blockSignals(True)
            self.comboBox.clear()
            self.comboBox.addItems(["выберите лист"] + self.wbr.sheet_names())
            self.comboBox.blockSignals(False)
    
    
        def slot_list_selected(self, list_index):
            if list_index:
                # //////////////////Индекс листа///////////////////////
                sheet = self.wbr.sheet_by_index(list_index-1)
                print(list_index)
        
                vals = []
                i = 0
                a = 0
        
                for rows in range(sheet.nrows):
                    vals.append(sheet.row_values(rows))
        
                # /////////////Удаляем из массива шапку Промоактивности//////////////
                for a in range(4):
                    del vals[0]
                    a = +1
        
                file_csv = open('C:\promo.csv', 'w')
        
                for i in range(sheet.nrows - 4):
                    stroka_0 = str(vals[i]).replace('[', '')
                    stroka_1 = stroka_0.replace(',', ';')
                    stroka_2 = stroka_1.replace(']', '')
                    stroka_3 = stroka_2.replace(' ', '')
                    stroka_4 = stroka_3.replace("'", '')
                    stroka_5 = stroka_4.replace(".0", '')
                    file_csv.write(stroka_5 + "\n")
                    i = +1
        
                file_csv.close()
    Ответ написан
  • PyQt4 + Win7 - не убирается иконка приложения из таскбара при hide()?

    @Sergey6661313
    мне кажется что после получения сигнала hide() вызывается hideEvent который вы переопределили на действие hide() - таким образом образуется бесконечный цикл. И получается что иконка не пропадает потому что приложение вообще зависло.

    def hideEvent(self, event):
        QtGui.QMainWindow.hideEvent(self, event)  # или без self уже не помню.
        self.trayIcon = QtGui.QSystemTrayIcon(QtGui.QIcon(“myicon.png”),self) # где myicon.png картинка вашей иконки...
        self.trayIcon.show()



    готовые примеры уже есть в вашей системе:
    Python\Lib\site-packages\PyQt4\examples
    Python\Lib\site-packages\PyQt4\docs
    Ответ написан
  • PyQt QCalendarWidget — почему метод не возвращает значение?

    @Sergey6661313
    Проблема: вы не читаете документацию.
    Решение: Я тоже :)
    Настоящая проблема: у вас не метод не возвращяет, а сигнал неправильно связан.

    в строчке SIGNAL('currentPageChanged(int, int)') - надпись (int, int) говорит о том что сигнал будет посылать 2 значения в функцию с которой вы его соединяете. Соответственно функция должна их получать. А значит что объявлять функцию необходимо с указанием того под каким именем вы будете получать эти два значения:
    def __init__(self):
            QtGui.QCalendarWidget.__init__(self)
            self.resize(300, 300)
            self.connect(self, QtCore.SIGNAL('currentPageChanged(int, int)'), self.anotherGetCurrentDate)
    
    def anotherGetCurrentDate(self, i1, i2):
        print(i1, i2)
        return self.monthShown()

    Данный код показывает что сигнал УЖЕ сам изначально возвращает год и месяц.
    кстати рекомендую соединять сигналы в новом стиле (всё равно когда нить придётся переписывать под QT5) так:
    self.currentPageChanged.connect(self.anotherGetCurrentDate)
    Ответ написан