I'm using Qt5.6.1 and QCustomPlot 2.00-beta. And I set a new widget called "widget". But when I code
ui->widget->xAxis->setAutoTickStep(false);
it says
error: C2039: 'setAutoTickStep' : is not a member of 'QCPAxis'
how to solve it?
use:
QSharedPointer<QCPAxisTickerFixed> fixedTicker(new QCPAxisTickerFixed);
customPlot->xAxis->setTicker(fixedTicker);
fixedTicker->setTickStep(1.0); // tick step shall be 1.0
fixedTicker->setScaleStrategy(QCPAxisTickerFixed::ssNone); // and no scaling of the tickstep (like multiples or powers) is allowed
from: http://www.qcustomplot.com/documentation/classQCPAxisTickerFixed.html#details
You will need to create an object of type QCustomPlot, do a customPlot->addGraph(), and then access its settings like customPlot->xAxis->QCPAxisTicker(...).
It appears you are trying to access a member of an object of type QWidget, which knows nothing about custom plots, until overridden. Neither the old nor the new method will work on an object of QWidget. You should use a new method of QCPAxis instead; perhaps
ui->customPlot->xAxis->ticker()->setTickCount(0);
If your problem is that you are trying to create a plot in QtCreator, you can create a QWidget in it, and then right-click on it, and do a "Promote to ...". Make sure the QCustomPlot headers are already in your project first, and then specify the one which defines QCustomPlot when promoting. When you say, "rename it as widget and remote it to a QCustomPlot", did you mean "promote it to"?
Related
I have an application with many windows (QWidgets).
I didn't save a list of open windows, though, so everytime I want to close a window, I have to retrieve it.
Particularly, each of these windows is called here SubWindow.
Every SubWindow class contains a layout with a MultiEditor *sEditors, which has a menu with an action that closes the current window.
Every SubWindow is created within the MainWindow.
I have two plans.
1) destroying the SubWindow from within itself, by adding in the SubWindow constructor
connect(sEditors, SIGNAL(closeWindow()),
this, closeWindow()));
or
2) destroying the SubWindow from within the MainWindow class, by adding in the SubWindow constructor
connect(sEditors, SIGNAL(closeWindow()),
main, SLOT(closeWindow(this)));
About 1), I don't understand how I can close and destroy a QWidget from within itself (delete this; didn't seem to work, but I can try again).
About 2) my SLOT(closeWindow(this)) doesn't seem to be triggered, so I am wondering if I can pass "this" as an argument.
Ad 1) You can use QObject::deleteLater(). This will destroy the object in the next event loop cycle, and is specifically create for situations like this
Ad 2) You cannot pass actual arguments as parameters in signal-slot connections.
You can however find out who has emitted the signal by using the sender() function in the slot. In your case, that would be the sEditors object.
Other options:
3) You can use a QSignalMapper to map signals from your editors to the Subwindows.
4) (Using Qt5 / C++11) You can use a lambda connection in your Subwindows:
connect(sEditors, SIGNAL(closeWindow()), [this] () {this->closeWindow();});
Can I pass this to a Qt slot?
A slot is a non-static method, so it already has access to this. The this you refer to is the third argument to QObject::connect. In Qt 4 syntax, you're free to omit the third argument - it defaults to this. In Qt 5 syntax, you must be explicit about it, though.
I don't understand how I can close and destroy a QWidget from within itself
To delete any QObject from within itself, use QObject::deleteLater(). Recall that a QWidget is-a QObject in terms of LSP.
my SLOT(closeWindow(this)) doesn't seem to be triggered
There's no such slot (give us a link to its documentation: you can't), and your slot signature is also invalid because the only things within the parentheses in the slot signature can be types, and this is not a type: SLOT(slotName(TYPE_LIST_HERE)), e.g. SLOT(mySlot(int,QString)).
To close a widget, use its close() slot:
connect(sEditors, SIGNAL(closeWindow()), this, SLOT(close());
Yet, by using Qt 4 connect syntax, you're leaving coding mistakes to be detected at runtime - and then if you don't pay attention to the debug output at runtime, you'll miss it. It's thus much better to use the new (Qt 5) connect syntax, and let the compiler detect errors for you:
connect(sEditors, &MultiEditor::closeWindow, this, &QWidget::close);
Alas, there's no need to tightly couple the object that sends closeWindow to SubWindow - at least not within the SubWindow::SubWindow(). Instead, you can connect at the place where you create the editor.
To delete a widget when it gets closed, simply set the Qt::WA_DeleteOnClose attribute on it and let Qt do it for you. No need to explicitly call deleteLater etc.
You might factor all of it into a factory method:
template <class T> T* SubWindow::makeEditor() {
auto sub = new T{this};
sub->setAttribute(Qt::WA_DeleteOnClose);
connect(sEditor, &MultiEditor::closeWindow, sub, &QWidget::close);
return sub;
}
MainWindow::MainWindow(/*...*/) : /*...*/ {
makeEditor<EditorType1>();
makeEditor<EditorType2>();
/*...*/
}
I have a QwtPlot that contains some curves and I would like to be able to get the selected point(s) (and curve pointer) from these curves : select a point by clicking and select points by dragging a rect.
I use the following code:
// Picker with click point machine to provide point selection
QwtPlotPicker* clickPicker = new QwtPlotPicker(this->canvas());
clickPicker->setStateMachine(new QwtPickerClickPointMachine);
clickPicker->setMousePattern(0,Qt::LeftButton,Qt::SHIFT);
connect(clickPicker, SIGNAL(appended(QPointF)),
this, SLOT(pointSelected(QPointF)));
// Picker with drag rect machine to provide multiple points selection
QwtPlotPicker* rectPicker = new QwtPlotPicker(
this->xBottom, this->yLeft, QwtPicker::RectRubberBand,
QwtPicker::AlwaysOff, this->canvas());
QwtPickerDragRectMachine* test = new QwtPickerDragRectMachine();
test->setState(QwtPickerMachine::RectSelection);
rectPicker->setStateMachine(test);
connect(rectPicker, SIGNAL(selected(QRectF)),
this, SLOT(pointsSelected(QRectF)));
but the pointSelected slot is called every time I click on the QwtPlot and not only on a curve
BTW, I also try to connect a slot to the signal QwtPlotPicker::selected(const QVector &pa) but it is never emitting ...
I think it is more convenient to use the CanvasPicker as it comes with the examples and can be extended easily.
Please have a look at the event_filter which comes with Qwt. You should use the class CanvasPicker (it is not part of the Qwt API, but you'll find the code in the examples).
You can instantiate it in your class using
picker = new CanvasPicker(plot); // plot is a pointer to your instance of QwtPlot
You'll see that the event filter is installed in the constructor of CanvasPicker.
Now have a look at CanvasPicker::eventFilter(QObject *object, QEvent *e) which is called when an event occurs in the event loop of QwtPlot. Implement your application logic in the switch construct, f.i. change case QEvent::MouseMove:.
In my Qt widget I sometimes get this error:
malloc(): smallbin double linked list corrupted
It does not happen all the time but I think I have narrowed it down to when it starts.
I have a QGraphicsView and QGraphicsScene and there I'm drawing lines whos points are stored in a vector. Reason for this is I need to pass this points to another library. Once I draw the points I have an option if I click on a line I'm prompted to another window where I can change the coordinates of a line.
ResizeDialog *dialog = new ResizeDialog(this);
dialog->exec();
delete dialog;
The above code is the code I use to open a new QDialog. I know if I use this->close() the
qt malloc(): smallbin double linked list corrupted does not appear but then I lose the instance of QGraphicsView. Reason I need to keep the QGraphicsView window open if I need to chose to add further lines.
Any advice on how I can eliminate this issue wold be helpful.
Rather than using delete dialog;, use dialog->deleteLater();. I assume the small code portion is inside a slot of the object referenced by "this", and direct deletion is source of trouble as ResizeDialog *dialog = new ResizeDialog(this); affect the parent object this.
For QGraphicsScene::drawItems the reference says:
Reimplement this function to provide custom painting of all items for the scene; gaining complete control over how each item is drawn.
But this function is marked as obsolete.
Is there any new equivalent method?
QGraphicsView::paintEvent() now calls
d->scene->d_func()->drawItems()
which means the method is part of class QGraphicsScenePrivate which you cannot override afaik.
If you need to change the way your items are drawn, first try to think of another way (i.e. a solution which does not require stepping into the drawItems() method). If you can't find any solution like that, your only chance is reactivating the pre-4.6-behaviour by setting
QGraphicsView::setOptimizationFlag( QGraphicsView::IndirectPainting )
I use Qt Designer to build my UI layout. On the layout, I have a combobox named cb_fac_cd. In my code I have a function that will automatically build a combobox based on the list I'm attempting to build. I have a lot of these lists defined in the database and this function spits out a QComboBox.
Unfortunately, until now I've only used this function to add cellWidgets to QTableWidgets. It works perfectly there. Now I want to populate this preexisting combobox.
It seems that a simple
self.ui.cb_fac_cd = makeComboBox('FACILITIES') doesn't work. I can see that the function returns the QComboBox as usual, but the cb_fac_cd combobox remains unpopulated.
How can I copy or assign the returned combobox to the one build in Qt Designer?
I am using PyQt, but that shouldn't make any difference.
As far as I know, you cannot replace objects which are part of the .h files generated by Qt's UIC mechanism (though I cannot confirm that 100% right now).
What I usually do in such cases is to have an empty layout in the ui file and then do the following:
(Note that I'm using Qt/C++ syntax as I don't know the pyqt syntax but I think you will get the idea)
QComboBox* pNewComboBox = makeComboBox( "FACILITIES" );
ui.pComboBoxLayout->addWidget( pComboBox );
Additionally, if possible for your program, consider using an enumeration rather than a string for your makeComboBox function. This is usually faster and safer.
It sounds like you should either
Change makeComboBox to populateComboBox(QComboBox *p) and pass it the combobox in your layout to fill, or
Create and add the QComboBox to your layout dynamically and remove it from your .ui
You can change the model from you Ui to the one you get from the other combobox:
tempCombo = makeComboBox( "FACILITIES" )
self.ui.cb_fac_cd.setModel(tempCombo.model())
But for that part:
I have a lot of these lists defined in the database and this function
spits out a QComboBox. Unfortunately, until now I've only used this function to add
cellWidgets to QTableWidgets.
If the data comes from a database, you might want to look at QSqlRelationalTableModel to avoid doing that manually.