Найти - Пользователи
Полная версия: Помогите c эмуляцией выбора в ListWidget PyQt
Начало » Python для новичков » Помогите c эмуляцией выбора в ListWidget PyQt
1
seregka174
Подсобите, в гугл с яндексом забегал там все на инглишь а я в нем просто пока ни какой

Есть заполненный списком ListWidget
Как решить следующее при нажатии на кнопу сэмулировать двойной клик по индексу в данном списке ListWidget при нажатии на кнопку?

Учусь PYthon пробую силы в Mp3 проигрывателе в ListWidget список песен нужно чтобы при нажатии на кнопку Next эмулировался двойной клик на следующую песню
вот код, прошу сильно не пинайте я только учусь


 import vlc #подключение самого плеера
import sys  # sys нужен для передачи argv в QApplication
import os  # Отсюда нам понадобятся методы для отображения содержимого директорий
import design  # Это наш конвертированный файл дизайна
from PyQt5 import QtWidgets
class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        self.player = None 
		# Это здесь нужно для доступа к переменным, методам
		# и т.д. в файле design.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна
        self.btnBrowse.clicked.connect(self.browse_folder)  # Выполнить функцию browse_folder при нажатии кнопки
        self.pushButtonPause.clicked.connect(self.pause_player)  # Выполнить функцию pause_plauer при нажатии кнопки Pause
        self.pushButtonNext.clicked.connect(self.next_player)  # Выполнить функцию next_player при нажатии кнопки Next
        self.listWidget.itemDoubleClicked.connect(self.play) #при двойном клике запустить функцию воспроизведения
        
    #событие нажатие на кнопку Выберите папку
    def browse_folder(self):
        global directory#объявляем переменную глобальной
        self.listWidget.clear()  # На случай, если в списке уже есть элементы
        directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку",'/home/seregka/Музыка')
        # открыть диалог выбора директории и установить значение переменной
        # равной пути к выбранной директории
        if directory:  # не продолжать выполнение, если пользователь не выбрал директорию
            for file_name in os.listdir(directory):  # для каждого файла в директории
                self.listWidget.addItem(file_name)   # добавить файл в listWidget
                
     #событие нажатия на кнопку Pause
    def pause_player(self):
        self.player.pause()
        
    #событие нажания на кнопку Next
    def next_player(self):
        print ('Next')
  
    #функция воспроизведения              
    def play(self):
        fil = (os.listdir(directory))
        sel = self.listWidget.selectedIndexes()[0]
        fil_row = (sel.row())
        #тут воспроизводим выбранный файл files из выбранной directory
        if self.player:
             self.player.stop() 
        self.player = vlc.MediaPlayer(directory+"/"+fil[fil_row])
        self.player.play()
def main():
    app = QtWidgets.QApplication(sys.argv)  # Новый экземпляр QApplication
    window = ExampleApp()  # Создаём объект класса ExampleApp
    window.show()  # Показываем окно
    app.exec_()  # и запускаем приложение
if __name__ == '__main__':  # Если мы запускаем файл напрямую, а не импортируем
    main()  # то запускаем функцию main()
PEHDOM
А зачем эмулирвать?,вы же знаете что сейчас проигрываеться, тоесть у вас есть индекс строки которую проигрываете в листвиджете(есди нету то нужно гдето хранить), меняете его на следующий, можно чтото типа setCurrentRow(), берете оттуда название/путь и запускаете воспроизведение.
Можно конечно получить индекс через сurrentRow(), но может выйти конфуз, потому как пока мелодия играет, пользователь может выбрать текущим другой пункт виджета, но play не нажать, и выйдет что играет одна песня, а текушая в листвиджете другая.
seregka174
PEHDOM
А зачем эмулирвать?,вы же знаете что сейчас проигрываеться, тоесть у вас есть индекс строки которую проигрываете в листвиджете(есди нету то нужно гдето хранить), меняете его на следующий, можно чтото типа setCurrentRow(), берете оттуда название/путь и запускаете воспроизведение.Можно конечно получить индекс через сurrentRow(), но может выйти конфуз, потому как пока мелодия играет, пользователь может выбрать текущим другой пункт виджета, но play не нажать, и выйдет что играет одна песня, а текушая в листвиджете другая.
Да с индексом я тоже сразу про это подумал и сразу приступил подгонять под воспроизведение по индексу но на пол дороги понял что тогда в listwidget не будет выделена та песня которая играет то есть если я двоным кликом выбрал одну она заиграла и потом нажмут Next то будет играть следующая а выделение останется на старой чего мне крайне не хочется.
Сейчас попробую наблындить как менять фокус по setCurrentRow() может что получится, спасибо за наводку!
Получилось следующее:
 import vlc #подключение самого плеера
import sys  # sys нужен для передачи argv в QApplication
import os  # Отсюда нам понадобятся методы для отображения содержимого директорий
import design  # Это наш конвертированный файл дизайна
from PyQt5 import QtWidgets
class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        self.player = None 
		# Это здесь нужно для доступа к переменным, методам
		# и т.д. в файле design.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна
        self.btnBrowse.clicked.connect(self.browse_folder)  # Выполнить функцию browse_folder при нажатии кнопки
        self.pushButtonPause.clicked.connect(self.pause_player)  # Выполнить функцию pause_plauer при нажатии кнопки Pause
        self.pushButtonNext.clicked.connect(self.next_player)  # Выполнить функцию next_player при нажатии кнопки Next
        self.pushButtonSkip.clicked.connect(self.skip_player)  # Выполнить функцию skip_player при нажатии кнопки Next
        self.listWidget.itemDoubleClicked.connect(self.play) #при двойном клике запустить функцию воспроизведения
        
    #событие нажатие на кнопку Выберите папку
    def browse_folder(self):
        global directory#объявляем переменную глобальной
        self.listWidget.clear()  # На случай, если в списке уже есть элементы
        directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку",'/home/seregka/Музыка')
        # открыть диалог выбора директории и установить значение переменной
        # равной пути к выбранной директории
        if directory:  # не продолжать выполнение, если пользователь не выбрал директорию
            for file_name in os.listdir(directory):  # для каждого файла в директории
                self.listWidget.addItem(file_name)   # добавить файл в listWidget
                
     #событие нажатия на кнопку Pause
    def pause_player(self):
        self.player.pause()
        
    #событие нажания на кнопку Next
    def next_player(self):
        fil_row=fil_row+1
        self.listWidget.setCurrentRow(fil_row)
        self.play()
        
    #событие нажания на кнопку Skip
    def skip_player(self):
        fil_row=fil_row-1
        self.listWidget.setCurrentRow(fil_row)
        self.play()
  
    #функция воспроизведения              
    def play(self):
        global fil_row
        fil = (os.listdir(directory))
        sel = self.listWidget.selectedIndexes()[0]
        fil_row = (sel.row())
        #тут воспроизводим выбранный файл files из выбранной directory
        if self.player:
             self.player.stop() 
        self.player = vlc.MediaPlayer(directory+"/"+fil[fil_row])
        self.player.play()
def main():
    app = QtWidgets.QApplication(sys.argv)  # Новый экземпляр QApplication
    window = ExampleApp()  # Создаём объект класса ExampleApp
    window.show()  # Показываем окно
    app.exec_()  # и запускаем приложение
if __name__ == '__main__':  # Если мы запускаем файл напрямую, а не импортируем
    main()  # то запускаем функцию main()
И какая то беда с областью видемости переменной fil_row
при нажатии на кнопку Next вот такая ошибка:
UnboundLocalError: local variable ‘fil_row’ referenced before assignment
PEHDOM
ну так у вас же fil_row глобальная переменная:
  
...
  def play(self):
        global fil_row
...
а тут она уже локальная
 ...
    def next_player(self):
        fil_row=fil_row+1
...
И вообще накой вам глобальная переменная? сделайте fil_row атрибутом класса.
seregka174
PEHDOM
ну так у вас же fil_row глобальная переменная:
так и не разобрался с этими переменными, и как сделать переменную видемую во всех функциях, надо читать, а тем более атрибут класса это вообще для меня дебри
пока сделал так работает:
 import vlc #подключение самого плеера
import sys  # sys нужен для передачи argv в QApplication
import os  # Отсюда нам понадобятся методы для отображения содержимого директорий
import design  # Это наш конвертированный файл дизайна
from PyQt5 import QtWidgets
class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        self.player = None 
		# Это здесь нужно для доступа к переменным, методам
		# и т.д. в файле design.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна
        self.btnBrowse.clicked.connect(self.browse_folder)  # Выполнить функцию browse_folder при нажатии кнопки
        self.pushButtonPause.clicked.connect(self.pause_player)  # Выполнить функцию pause_plauer при нажатии кнопки Pause
        self.pushButtonNext.clicked.connect(self.next_player)  # Выполнить функцию next_player при нажатии кнопки Next
        self.pushButtonSkip.clicked.connect(self.skip_player)  # Выполнить функцию skip_player при нажатии кнопки Next
        self.listWidget.itemDoubleClicked.connect(self.play) #при двойном клике запустить функцию воспроизведения
        
    #событие нажатие на кнопку Выберите папку
    def browse_folder(self):
        global directory#объявляем переменную глобальной
        self.listWidget.clear()  # На случай, если в списке уже есть элементы
        directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку",'/home/seregka/Музыка')
        # открыть диалог выбора директории и установить значение переменной
        # равной пути к выбранной директории
        if directory:  # не продолжать выполнение, если пользователь не выбрал директорию
            for file_name in os.listdir(directory):  # для каждого файла в директории
                self.listWidget.addItem(file_name)   # добавить файл в listWidget
                
     #событие нажатия на кнопку Pause
    def pause_player(self):
        self.player.pause()
        
    #событие нажания на кнопку Next
    def next_player(self):
        sel = self.listWidget.selectedIndexes()[0]
        fil_row = (sel.row())
        if fil_row!=(len (self.listWidget))-1:
            fil_row=fil_row+1
        else: fil_row=0
        self.listWidget.setCurrentRow(fil_row)
        self.play()
        
    #событие нажания на кнопку Skip
    def skip_player(self):
        sel = self.listWidget.selectedIndexes()[0]
        fil_row = (sel.row())
        if fil_row>0:
            fil_row=fil_row-1
        self.listWidget.setCurrentRow(fil_row)
        self.play()
  
    #функция воспроизведения              
    def play(self):
        fil = (os.listdir(directory))
        sel = self.listWidget.selectedIndexes()[0]
        fil_row = (sel.row())
        #тут воспроизводим выбранный файл files из выбранной directory
        if self.player:
             self.player.stop() 
        self.player = vlc.MediaPlayer(directory+"/"+fil[fil_row])
        self.player.play()
def main():
    app = QtWidgets.QApplication(sys.argv)  # Новый экземпляр QApplication
    window = ExampleApp()  # Создаём объект класса ExampleApp
    window.show()  # Показываем окно
    app.exec_()  # и запускаем приложение
if __name__ == '__main__':  # Если мы запускаем файл напрямую, а не импортируем
    main()  # то запускаем функцию main()
PEHDOM
seregka174
как сделать переменную видемую во всех функциях, надо читать,
Ну у вас всеже не функции а методы класса, следовательно чтобы переменную видели все методы класса, ее нужно сделать атрибутом класса, тоесть fil_row заменить на self.fil_row
seregka174
PEHDOM
Сделал как вы сказали с заменой на self.fil_row все супер РАБОТАЕТ УРААА!!!
Сейчас вот ломаю голову как сделать что бы после того как песня доиграла заиграла следующая.
PEHDOM
seregka174
Сейчас вот ломаю голову как сделать что бы после того как песня доиграла заиграла следующая.
а чего тут ломать? нужно вешать калбек функцию на евент плеера MediaPlayerEndReached, както так:
https://stackoverflow.com/questions/3595649/vlc-python-eventmanager-callback-type
только вам бы не создавать экземпляр self.player = vlc.MediaPlayer() каждый раз как срабатывает play(), а создать его один раз, и потом просто скармливать разные файлы, self.player.load(), если я не ошибаюсь. Иначе вам придеться каждый раз после play() заново вешать калбеки.
seregka174
PEHDOM
Мда уж что то забрел я уже очень и очень далеко и уже ничего не понимаю я даже не знаю что такое класс, атрибут, метод
По книжке Майкл Доусон Программируем на Python дошел только до функций :-) и блин затягивает так интересно.
Пока уже хорошо что такое получилось с помощью Вас и google
Спасибо Вам огромное за то что потратили на меня свое время и помогли мне!
Благодаря Вам у меня еще большее желание изучать Python!!!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB