【问题标题】:How to connect a QSlider to QDoubleSpinBox如何将 QSlider 连接到 QDoubleSpinBox
【发布时间】:2012-02-06 04:14:35
【问题描述】:

我想将 QSlider 连接到 QDoubleSpinBox,但是虽然代码可以正常编译并针对简单的 QSpinBox 运行,但它不适用于 QDoubleSpinBox

QSlider *horizontalSlider1 = new QSlider();
QDoubleSpinBox *spinBox1 = new QDoubleSpinBox();

connect(spinBox1, SIGNAL(valueChanged(double)),horizontalSlider1,SLOT(setValue(double)) );
connect(horizontalSlider1,SIGNAL(valueChanged(double)),spinBox1,SLOT(setValue(double)) );

【问题讨论】:

    标签: qt connect signals-slots qslider


    【解决方案1】:

    QSlider 和 QDoubleSpinBox 在 valueChanged/setValue 中采用不同类型的参数(当然,QSlider 使用整数,QDoubleSpinBox 使用双精度)。更改滑块信号和槽的参数类型可能会有所帮助:

    connect(spinBox1, SIGNAL(valueChanged(double)),horizontalSlider1,SLOT(setValue(int)) );
    connect(horizontalSlider1,SIGNAL(valueChanged(int)),spinBox1,SLOT(setValue(double)) );
    

    我不确定 Qt 是否可以自动为您处理这种类型转换;如果没有,您必须定义自己的插槽才能在正确的对象上调用 setValue()

    【讨论】:

    • 它没有,不可能有合理的双向转换(滑块->旋转框,旋转框->滑块)。它需要自定义插槽来正确映射值。
    【解决方案2】:

    您必须添加自己的插槽,它可以转换参数类型并发出信号或直接更新滑块。

    【讨论】:

    • 谢谢,我会试试的,不过好像还没人做过,好像很奇怪...我觉得是很常见的事情...
    【解决方案3】:

    正如 Dave Kilian 回答的那样,QSlider 的信号和插槽不使用双精度。此外,Qt 4 不会自动转换类型;它不允许您连接它们。因此,您必须编写自己的转换槽来更新其他项目的值。

    【讨论】:

      【解决方案4】:

      希望这对你有帮助。

      #include <QApplication>
      #include <QtGui>
      #include <QVBoxLayout>
      #include <QSlider>
      #include <QLabel>
      
      class DoubleSlider : public QSlider {
          Q_OBJECT
      
      public:
          DoubleSlider(QWidget *parent = 0) : QSlider(parent) {
              connect(this, SIGNAL(valueChanged(int)),
                  this, SLOT(notifyValueChanged(int)));
          }
      
      signals:
          void doubleValueChanged(double value);
      
      public slots:
          void notifyValueChanged(int value) {
              double doubleValue = value / 10.0;
              emit doubleValueChanged(doubleValue);
          }
      };
      
      class Test : public QWidget {
          Q_OBJECT
      public:
          Test(QWidget *parent = 0) : QWidget(parent),
              m_slider(new DoubleSlider()),
              m_label(new QLabel())
          {
              m_slider->setOrientation(Qt::Horizontal);
              m_slider->setRange(0, 100);
              QVBoxLayout *layout = new QVBoxLayout(this);
              layout->addWidget(m_slider);
              layout->addWidget(m_label);
              connect(m_slider, SIGNAL(doubleValueChanged(double)),
                  this, SLOT(updateLabelValue(double)));
              updateLabelValue(m_slider->value());
          }
      
      public slots:
          void updateLabelValue(double value) {
              m_label->setText(QString::number(value, 'f', 2));
          }
      
      private:
          QSlider *m_slider;
          QLabel *m_label;
      };
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          Test *wid = new Test();
          wid->show();
      
          return a.exec();
      }
      
      #include "main.moc"
      

      【讨论】:

        【解决方案5】:

        将 QSlider 或 QDial 同步到 QDoubleSpinBox 的一个问题是,当 QDoubleSpinBox 更新 QDial 或 QSlider 时,将触发 QDial 或 QSlider valueChanged 信号,从而导致它们更新 QDoubleSpinBox 作为回报。这会导致您无法在 QDoubleSpinBox 中输入十进制值的问题,因为当您输入小数“.”时,QDial/Slider 更新会覆盖小数,从而阻止您输入其余的十进制值。

        要解决此问题,请让每个输入小部件检查它们的值是否已经与它们正在写入的小部件中的值匹配,如果匹配,则不要更新该值。下面是一个允许 QDial 和 QDoubleSpinBox 相互更新的函数示例:

            def syncDialAndSpinbox(self, widget_in, widget_out):
                if isinstance(widget_in, QtWidgets.QDial):
                    value =  float(widget_in.value())*100.0/float(widget_in.maximum())
                    out_value = widget_out.value()
                else:
                    value = round(widget_in.value()*widget_out.maximum()/100)
                    out_value = widget_out.value()
        
                if value != out_value:
                    widget_out.setValue(value)
        

        在本例中,QDoubleSpinBox 是一个百分比 (0.0-100.0),而 QDial 有 100,000 步以支持将百分比浮点输出到小数点后三位(0.000% 到 100.000%)。

        【讨论】:

          【解决方案6】:

          在这个非常相似的问题中有一些关于如何创建自己的插槽并发出信号的示例代码:

          use a created vector as range for QDoubleSpinBox and QSlider

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-12-13
            • 2021-06-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-23
            • 2011-04-06
            • 2021-12-27
            相关资源
            最近更新 更多