微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

动态更新 PYQT 菜单项

如何解决动态更新 PYQT 菜单项

我使用以下构造构造了一个 Qmenu 项目,其中包含最近打开的文件列表。我想实时更新菜单栏,这样我就不必等到下次运行应用程序时才能更新菜单栏。

import sys
from PyQt5 import QtCore,QtWidgets,QtGui
from PyQt5.QtGui import Qpixmap


class Application(QtWidgets.QMainWindow):

    def __init__(self,*args,**kwargs):
        super(Application,self).__init__(*args,**kwargs)

        self.settings = {}
        self.settings['recent files'] = ['filename1','filename2','filename3']

        QtWidgets.QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.menu_bar()

    def menu_bar(self):
        file_menu = QtWidgets.QMenu('&File',self)
        self.recent = file_menu.addMenu('&Open Recent')

        for filename in self.settings['recent files']:
            self.recent.addAction(f'{filename}',lambda source=filename: self.dialog_open_file(file_name=source))

        self.menuBar().addMenu(file_menu)

    def dialog_open_file(self):
        
        self.settings['recent files'] = ['filename 4','filename1','filename3']

        self.update_recent_files()

        # do lots more stuff

    def update_recent_files(self):

        # Update list of recent files in Open Recent menubar  <---- 

qApp = QtWidgets.QApplication(sys.argv)
application_window = Application()
application_window.setwindowTitle(f"My App")
application_window.show()
sys.exit(qApp.exec_())

我的实际代码运行良好(实时更新菜单除外)。它将最近的文件列表写入磁盘上的持久 json(示例代码不包含该位)。当用户打开一个文件时,文件名被成功插入到最近使用的文件列表中。下次运行该应用时,“最近使用的文件菜单显示更新的列表。

但是,我希望最近文件菜单列表是动态的。我如何最好地调用实时重建“最近的文件菜单

EDIT -- 我试图澄清这个问题,以专注于菜单项的动态更新,而不是持续维护 文件列表。

解决方法

如果要持久保存信息,则必须将该信息保存在硬盘驱动器上(在文件中),python 和 Qt 中有许多替代方法,例如 QSettings。其逻辑是在创建窗口时加载信息,并在需要时保存(例如当窗口关闭时)。

export default function App() {
  const [value,setValue] = useState(0);
  const [price,setPrice] = useState(8);
  const [plan,setPlan] = useState("10k");
  const [toggle,setToggle] = useState(false);

  const handleDiscount = () => {
    setToggle((toggle) => !toggle);
  };

  const handlePriceChange = (e) => {
    const valueChange = e.target.value;
    setValue(valueChange);
    let pricing = 8;
    if ((value > 0) & (value <= 20)) {
      setPlan("10k");
      pricing = 8;
    } else if (value > 20 && value <= 40) {
      setPlan("50k");
      pricing = 12;
    } else if (value > 40 && value <= 60) {
      setPlan("100k");
      pricing = 16;
    } else if (value > 60 && value <= 80) {
      setPlan("500k");
      pricing = 24;
    } else if (value > 80 && value <= 100) {
      setPlan("1M");
      pricing = 36;
    }

    if (toggle === true) {
      setPrice(pricing - pricing * 0.25);
    } else {
      setPrice(pricing);
    }
  };

  return (
    <div className="App">
      <input
        type="range"
        name="range"
        value={value}
        min="0"
        max="100"
        className="slider"
        id="range"
        onChange={handlePriceChange}
      />
      <input
        type="checkbox"
        name="discount"
        className="discount"
        id="discount"
        onClick={handleDiscount}
        onChange={handlePriceChange}
      />
      <> {price} </>
      <hr />
      <> {plan} Pageviews </>
    </div>
  );
}
,

当菜单的内容是动态的时,我通常更喜欢使用 QMenu 的 aboutToShow 信号,它在它即将被打开之前被触发,并连接到一个清除它并更新其内容的函数.

我也使用QAction.setData来存储文件名,它允许显示自定义文本(例如,如果路径太长,我们可以省略它,或者只显示文件名而不是完整的路径)。

class Application(QtWidgets.QMainWindow):

    def __init__(self,*args,**kwargs):
        super(Application,self).__init__(*args,**kwargs)

        file_menu = self.menuBar().addMenu('&File')
        self.recent_menu = file_menu.addMenu('&Open recent')

        self.recent_menu.aboutToShow.connect(self.update_recent_menu)
        self.recent_menu.triggered.connect(self.open_file_from_recent)
        self.settings = {}

    def update_recent_menu(self):
        self.recent_menu.clear()
        for row,filename in enumerate(self.get_recent_files(),1):
            recent_action = self.recent_menu.addAction('&{}. {}'.format(
                row,filename))
            recent_action.setData(filename)

    def get_recent_files(self):
        recent = self.settings.get('recent files')
        if not recent:
            # just for testing purposes
            recent = self.settings['recent files'] = ['filename 4','filename1','filename2','filename3']
        return recent

    def open_file_from_recent(self,action):
        self.open_file(action.data())

    def open_file(self,filename):
        recent = self.get_recent_files()
        if filename in recent:
            recent.remove(filename)
        recent.insert(0,filename)
        
        print(filename)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。